# Number output in 6502 machine code

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

## 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
.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
.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
.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)