Number output in 6502 machine code
Contents
Print 8-bit hexadecimal
Print value in A in hexadecimal padded with zeros.
\ On entry, A=value to print \ On exit, A corrupted .PrHex PHA :\ Save A LSR A:LSR A:LSR A:LSR A :\ Move top nybble to bottom nybble JSR PrNybble :\ Print this nybble PLA :\ Get A back and print bottom nybble .PrNybble AND #15 :\ Keep bottom four bits CMP #10:BCC PrDigit :\ If 0-9, jump to print ADC #6 :\ Convert ':' to 'A' .PrDigit ADC #ASC"0":JMP OSWRCH :\ Convert to character and print
Print 8-bit hexadecimal (more cunning)
Print value in A in hexadecimal padded with zeros. (I used http://www.obelisk.me.uk/6502/algorithms.html to refresh my memory.)
\ On entry, A=value to print \ On exit, A corrupted .PrHex PHA :\ Save A LSR A:LSR A:LSR A:LSR A :\ Move top nybble to bottom nybble JSR PrNybble PLA AND #15 :\ Mask out original bottom nybble .PrNybble SED CLC ADC #&90 :\ Produce &90-&99 or &00-&05 ADC #&40 :\ Produce &30-&39 or &41-&46 CLD JMP OSWRCH :\ Print it
Print 8-bit decimal
Print value in A in decimal padded with zeros.
\ On entry, A=value to print \ On exit, A corrupted .PrDec LDX #&FF:SEC :\ Prepare for subtraction .PrDec100 INX:SBC #100:BCS PrDec100 :\ Count how many 100s ADC #100:JSR PrDecDigit :\ Print the 100s LDX #&FF:SEC :\ Prepare for subtraction .PrDec10 INX:SBC #10:BCS PrDec10 :\ Count how many 10s ADC #10:JSR PrDecDigit :\ Print the 10s TAX :\ Pass 1s into X .PrDecDigit PHA:TXA :\ Save A, pass digit to A ORA #ASC"0":JSR OSWRCH :\ Convert to character and print it PLA:RTS :\ Restore A and return
Print multi-byte numbers in decimal
These routines will print 16-bit, 24-bit and 32-bit values in decimal with no padding or specified character padding. They can be optimised for for specific implementations.
16-bit decimal
\ --------------------------- \ Print 16-bit decimal number \ --------------------------- \ On entry, num=number to print \ pad=0 or pad character (eg '0' or ' ') \ On entry at PrDec16Lp1, \ Y=(number of digits)*2-2, eg 8 for 5 digits \ On exit, A,X,Y,num,pad corrupted \ Size 69 bytes \ ----------------------------------------------------------------- .PrDec16 LDY #8 :\ Offset to powers of ten .PrDec16Lp1 LDX #&FF:SEC :\ Start with digit=-1 .PrDec16Lp2 LDA num+0:SBC PrDec16Tens+0,Y:STA num+0 :\ Subtract current tens LDA num+1:SBC PrDec16Tens+1,Y:STA num+1 INX:BCS PrDec16Lp2 :\ Loop until <0 LDA num+0:ADC PrDec16Tens+0,Y:STA num+0 :\ Add current tens back in LDA num+1:ADC PrDec16Tens+1,Y:STA num+1 TXA:BNE PrDec16Digit :\ Not zero, print it LDA pad:BNE PrDec16Print:BEQ PrDec16Next :\ pad<>0, use it .PrDec16Digit LDX #ASC"0":STX pad :\ No more zero padding ORA #ASC"0" :\ Print this digit .PrDec16Print JSR OSWRCH .PrDec16Next DEY:DEY:BPL PrDec16Lp1 :\ Loop for next digit RTS : .PrDec16Tens EQUW 1 EQUW 10 EQUW 100 EQUW 1000 EQUW 10000 \ -----------------------------------------------------------------
24-bit decimal
\ --------------------------- \ Print 24-bit decimal number \ --------------------------- \ On entry, num=number to print \ pad=0 or pad character (eg '0' or ' ') \ On entry at PrDec24Lp1, \ Y=(number of digits)*3-3, eg 21 for 8 digits \ On exit, A,X,Y,num,pad corrupted \ Size 98 bytes \ ----------------------------------------------------------------- .PrDec24 LDY #21 :\ Offset to powers of ten .PrDec24Lp1 LDX #&FF:SEC :\ Start with digit=-1 .PrDec24Lp2 LDA num+0:SBC PrDec24Tens+0,Y:STA num+0 :\ Subtract current tens LDA num+1:SBC PrDec24Tens+1,Y:STA num+1 LDA num+2:SBC PrDec24Tens+2,Y:STA num+2 INX:BCS PrDec24Lp2 :\ Loop until <0 LDA num+0:ADC PrDec24Tens+0,Y:STA num+0 :\ Add current tens back in LDA num+1:ADC PrDec24Tens+1,Y:STA num+1 LDA num+2:ADC PrDec24Tens+2,Y:STA num+2 TXA:BNE PrDec24Digit :\ Not zero, print it LDA pad:BNE PrDec24Print:BEQ PrDec24Next :\ pad<>0, use it .PrDec24Digit LDX #ASC"0":STX pad :\ No more zero padding ORA #ASC"0" :\ Print this digit .PrDec24Print JSR OSWRCH .PrDec24Next DEY:DEY:DEY:BPL PrDec24Lp1 :\ Loop for next digit RTS : .PrDec24Tens EQUW 1 :EQUB 1 DIV 65536 EQUW 10 :EQUB 10 DIV 65536 EQUW 100 :EQUB 100 DIV 65536 EQUW 1000 :EQUB 1000 DIV 65536 EQUW 10000 :EQUB 10000 DIV 65536 EQUW 100000 :EQUB 100000 DIV 65536 EQUW 1000000 :EQUB 1000000 DIV 65536 EQUW 10000000:EQUB 10000000 DIV 65536 \ -----------------------------------------------------------------
32-bit decimal
\ --------------------------- \ Print 32-bit decimal number \ --------------------------- \ On entry, num=number to print \ pad=0 or pad character (eg '0' or ' ') \ On entry at PrDec32Lp1, \ Y=(number of digits)*4-4, eg 36 for 10 digits \ On exit, A,X,Y,num,pad corrupted \ Size 129 bytes \ ----------------------------------------------------------------- .PrDec32 LDY #36 :\ Offset to powers of ten .PrDec32Lp1 LDX #&FF:SEC :\ Start with digit=-1 .PrDec32Lp2 LDA num+0:SBC PrDec32Tens+0,Y:STA num+0 :\ Subtract current tens LDA num+1:SBC PrDec32Tens+1,Y:STA num+1 LDA num+2:SBC PrDec32Tens+2,Y:STA num+2 LDA num+3:SBC PrDec32Tens+3,Y:STA num+3 INX:BCS PrDec32Lp2 :\ Loop until <0 LDA num+0:ADC PrDec32Tens+0,Y:STA num+0 :\ Add current tens back in LDA num+1:ADC PrDec32Tens+1,Y:STA num+1 LDA num+2:ADC PrDec32Tens+2,Y:STA num+2 LDA num+3:ADC PrDec32Tens+3,Y:STA num+3 TXA:BNE PrDec32Digit :\ Not zero, print it LDA pad:BNE PrDec32Print:BEQ PrDec32Next :\ pad<>0, use it .PrDec32Digit LDX #ASC"0":STX pad :\ No more zero padding ORA #ASC"0" :\ Print this digit .PrDec32Print JSR OSWRCH .PrDec32Next DEY:DEY:DEY:DEY:BPL PrDec32Lp1 :\ Loop for next digit RTS : .PrDec32Tens EQUD 1 EQUD 10 EQUD 100 EQUD 1000 EQUD 10000 EQUD 100000 EQUD 1000000 EQUD 10000000 EQUD 100000000 EQUD 1000000000 \ -----------------------------------------------------------------
Jgharston 07:51, 25 December 2011 (UTC) Jgharston (talk) 07:13, 30 June 2018 (CEST)