I am in the process of writing support assembly code for my BASIC compiler and am stuck with a particular BUG in the routine (PrDec16) that converts and prints an UNSIGNED INT into a DECIMAL STRING (There is also a routine, PrSgnDec16, that prints SIGNED INT which relies on it).
When you compile and run the program, it seems to work BUT the side-effect of the bug is that when you type RUN again, it just clears the screen (it actually prints out something random before it clears). So if I wrote a larger program, it ends up clearing the screen preventing other things to be printed (or it crashed?).
I spent two full days hungting for this bug but cannot find it! Can anyone see where the mistake is?
START:
StoreImm $1234, r0 ; decimal = 4660
jsr PrHex16 ; input at r0
PrintNewline
jsr NEG16 ; input at r0, output at r2
MoveW r2, r0
jsr PrHex16 ; prints EDCC (decimal = 60876)
PrintNewline
ldy #0 ; pad char, 0=none
jsr PrSgnDec16 ; ### BUG, prints -4660 OK, but prog corrupted
; jsr PrDec16 ; ### BUG, prints 60876 OK, but prog corrupted
END: rts
;-----------------------------------------------------------------
; FUNCTION: 16-bit Binary Negation (two's complement)
; INPUT: r0
;
; OUTPUT: r2 = 0 - r0 = ~r0 + 1
;-----------------------------------------------------------------
NEG16: ; 16 bit Binary Negation: r2 = 0 - r0 = ~r0 + 1 (two's complement)
SEC ;Ensure carry is set
LDA #0 ;Load constant zero
SBC r0L ;... subtract the least significant byte
STA r2L ;... and store the result
LDA #0 ;Load constant zero again
SBC r0H ;... subtract the most significant byte
STA r2H ;... and store the result
RTS
;-----------------------------------------------------------------
; FUNCTION: Print 16-bit decimal number
; INPUT: r0 = value to print, copied to scratch r11
; .Y = pad character
; (e.g. '0' #48 or ' ' #32 or #0 for none)
;-----------------------------------------------------------------
PrSgnDec16:
phy ; save .Y = padding char
lda r0H ; load MSB
and #$80 ; check for sign bit of MSB
beq LL1 ; positive, print normally
jsr NEG16 ; negative, NEG16 result at r2
lda #'-' ; print '-' sign
jsr CHROUT
MoveW r2, r0 ; load new positive value
LL1:
ply ; restore .Y
;-----------------------------------------------------------------
; FUNCTION: Print 16-bit decimal number
; INPUT: r0 = value to print, copied to scratch r11
; .Y = pad character
; (e.g. '0' #48 or ' ' #32 or #0 for none)
;
; INPUT: at PrDec16Lp1
; Y=(number of digits)*2-2, e.g. 8 for 5 digits
;
; OUTPUT: A,X,Y corrupted
;-----------------------------------------------------------------
PrDec16:
STY pad ; Save new padding character
MoveW r0, r11
LDY #8 ; Offset to powers of ten
PrDec16Lp1:
LDX #$FF ; Start with digit=-1
SEC
PrDec16Lp2:
LDA r11L ; Subtract current tens
SBC PrDec16Tens+0,Y
STA r11L
LDA r11H
SBC PrDec16Tens+1,Y
STA r11H
INX ; Loop until <0
BCS PrDec16Lp2
LDA r11L ; Add current tens back in
ADC PrDec16Tens+0,Y
STA r11L
LDA r11H
ADC PrDec16Tens+1,Y
STA r11H
TXA ; Not zero, print it
BNE PrDec16Digit
LDA pad ; pad<>0, use it
BNE PrDec16Print
BEQ PrDec16Next
PrDec16Digit:
LDX #48 ; ASC"0", No more zero padding
STX pad
ORA #48 ; ASC"0", Print this digit
PrDec16Print:
JSR CHROUT
PrDec16Next:
DEY ; Loop for next digit
DEY
BPL PrDec16Lp1
RTS
PrDec16Tens:
.word 1
.word 10
.word 100
.word 1000
.word 10000
pad: .res 0 ; default 0 = no padding
;-----------------------------------------------------------------
; FUNCTION: Print 8-bit hexadecimal number
; INPUT: .A = value to print
;
; OUTPUT:
;-----------------------------------------------------------------
PrHex8: ; Print value in A in hexadecimal padded with zeros,
PHA ; Save A
LSR A ; Move top nybble to bottom nybble
LSR A
LSR A
LSR A
JSR PrNybble ; Print this nybble
PLA ; Get A back and print bottom nybble
PrNybble:
AND #15 ; Keep bottom four bits
CMP #10 ; If 0-9, jump to print
BCC PrDigit
ADC #6 ; Convert ':' to 'A'
PrDigit:
ADC #48 ; ASC"0"
JSR CHROUT ; Convert to character and print
RTS
I am in the process of writing support assembly code for my BASIC compiler and am stuck with a particular BUG in the routine (PrDec16) that converts and prints an UNSIGNED INT into a DECIMAL STRING (There is also a routine, PrSgnDec16, that prints SIGNED INT which relies on it).
When you compile and run the program, it seems to work BUT the side-effect of the bug is that when you type RUN again, it just clears the screen (it actually prints out something random before it clears). So if I wrote a larger program, it ends up clearing the screen preventing other things to be printed (or it crashed?).
I spent two full days hungting for this bug but cannot find it! Can anyone see where the mistake is?
C:\dev\src>rm test.prg
C:\dev\src>cl65 -o test.prg -t cx16 -C cx16-asm.cfg test.asm
C:\dev\src>\x16-r38\x16emu.exe -prg test.prg -run
test.asm
Edited by geek504Share this post
Link to post
Share on other sites