Kowalski Simulator Macro Anomalies
Posted: Sat Jul 21, 2012 5:43 am
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.
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.
—————————————————————————————————————————————————————————————————
Code: Select all
.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.
—————————————————————————————————————————————————————————————————