In the process of writing a macro to automate and "error proof" a computational process that I frequently encounter in dealing with things like block and inode allocation maps on disk drives, I ran across an interesting anomaly in the Kowalski simulator. Rather than try to explain it, here's a test program that uses the macro as part of code that computes the number of bits in a hard drive disk block, given the block size in bytes.
.opt proc65c02,caseinsensitive
;===============================================================================
;
shiftfac .macro .op
;
; ————————————————————————————————————————————————————————————————
; This macro converts a power-of-2 value into the number of shifts
; required to perform integer multiplication or division using the
; ASL, LSR, ROL & ROR instructions. The macro parameter must be 2
; or an exact multiple of 2, such as 16 or 32768, & cannot exceed
; 65536 (2^16). The output of this macro is an LDX # instruction.
;
; The following example multiplies the value in NUM & NUM+1 by 16,
; with the remainder stored at NUM+2:
;
; shiftfac 16 ;generates LDX #4
; loop asl num ;each left rotate...
; rol num+1 ;multiplies the number...
; rol num+2 ;by 2
; dex
; bne loop
; ————————————————————————————————————————————————————————————————
;
.shift .=1
.if .op != 2
.else
.shift .=.shift+1
.if .op != 4
.else
.shift .=.shift+1
.if .op != 8
.else
.shift .=.shift+1
.if .op != 16
.else
.shift .=.shift+1
.if .op != 32
.else
.shift .=.shift+1
.if .op != 64
.else
.shift .=.shift+1
.if .op != 128
.else
.shift .=.shift+1
.if .op != 256
.else
.shift .=.shift+1
.if .op != 512
.else
.shift .=.shift+1
.if .op != 1024
.else
.shift .=.shift+1
.if .op != 2048
.else
.shift .=.shift+1
.if .op != 4096
.else
.shift .=.shift+1
.if .op != 8192
.else
.shift .=.shift+1
.if .op != 16384
.else
.shift .=.shift+1
.if .op != 32768
.else
.shift .=.shift+1
.if .op == 65536
.error "MACRO ERROR: "+%0$+": INVALID OPERAND"
.endif
.endif
.endif
.endif
.endif
.endif
.endif
.endif
.endif
.endif
.endif
.endif
.endif
.endif
.endif
.endif
ldx #.shift
.endm
;
;
; test code — computes number of bits in a disk block...
;
*=$2000
;
num =$00 ;number storage
;
blksiz =512 ;size of a disk block
n_bits =8 ;bits in a byte
;
ldx #<blksiz ;block size LSB
ldy #>blksiz ;block size MSB
stx num ;set LSB
sty num+1 ;set MSB
stz num+2 ;clear overflow
shiftfac n_bits ;get number of shifts
;
loop asl num ;each left rotate...
rol num+1 ;multiplies the number...
rol num+2 ;by 2
dex
bne loop
;
brk
.end
If you copy the above program into the simulator, it will assemble and run without error, and will produce the correct result, which is $001000 or 4096. However, if you examine the logic tree in the macro body you will see the anomaly.
Comments? Has anyone else run into this?
—————————————————————————————————————————————————————————————————
EDIT: This problem has been corrected in an update to the simulator. The current version is now 1.2.11.
—————————————————————————————————————————————————————————————————
Last edited by BigDumbDinosaur on Sun Jul 22, 2012 11:33 pm, edited 1 time in total.
Yep. The version jump was because Mr. Kowalski fixed a problem that developed after he released V1.2.9, which was double-spacing in the listing output. He also got the .PARAMTYPE macro feature working.
Yep. The version jump was because Mr. Kowalski fixed a problem that developed after he released V1.2.9, which was double-spacing in the listing output. He also got the .PARAMTYPE macro feature working.
Hi BDD,
I've been searching through the forum for bugs/feature requests/etc with the Kowalski Simulator and found this. Can you describe the purpose and use of the .PARAMTYPE feature?
I will post a consolidated list of bugs and feature requests once its completed.
printstr .macro .string
.if .paramtype(.string) == 2
(assemble code to process as a character string)
.else
(assemble code to process as an address)
.endif
.endm
The above macro invocation would process "This is a test." as a character string. On the other hand, the following invocation:
It would also be useful to have other types like character as well. We discussed this on another thread. The Kowalski macros are fairly crippled, especially compared to something like the CA65 assembler. I haven't looked at the source but how hard would it be to disable macros and let the simulator accept input from a more functional macro program?