Skip to content

Programming by Design

If you're not prepared to be wrong, you'll never come up with anything original. – Sir Ken Robinson

  • About
  • Java-PbD
  • C-PbD
  • ASM-PbD
  • Algorithms
  • Other

Chapter 6502-A – 8-, 16-, and 32-bit Printing.

Posted on February 9, 2025April 22, 2025 By William Jojo
AsmBook

(Updated April 22, 2025)

signed8bit.asm
; This is the start of the 8-bit library.

define CHROUT $ffd2
define LZF  $30

; This is test code for the 8-bit printing
    LDY  #0
NUMLOOP:
    LDA  NUMBERS,Y
    STA  $31    ; LSB
    PHA         ; SAVE
    JSR  S8OUT  ; PRINT AS SIGNED
    LDA  #7     ; '\t'
    JSR  CHROUT
    PLA         ; RESTORE
    STA  $31
    JSR  U8OUT  ; PRINT AS UNSIGNED
    LDA  #13    ; '\n'
    JSR  CHROUT
    INY
    CPY  #5     ; 5 numbers * 1 byte
    BNE NUMLOOP
    BRK

NUMBERS:
    dcb  -128, 127, -1, 1, 0


; S8OUT - print   signed 8bit value in $31
; U8OUT - print unsigned 8bit value in $31
; Based on code by Leo Scanlon in
; 6502 Software Design, 1980
; $31 LSB (clobbered)
; $30 LEADING ZERO FLAG (LZF, clobbered)
; CLOBBERS A, PRESERVES X & Y

S8OUT:
    JSR  S8OUTNEG
U8OUT:
    ; SAVE X & Y
    TXA
    PHA
    TYA
    PHA
    ; begin
    LDY  #0     ; INIT TABLE POINTER
    STY  LZF    ; CLEAR LZF
S8NEXTDIG:
    LDX  #0
S8DOSUBTRACT:
    LDA  $31
    SEC
    SBC  S8SUBTABLE,Y
    BCC  S8ADDBACK
    STA  $31
    INX
    JMP  S8DOSUBTRACT
    
S8ADDBACK:
    ; there's no actual add back for 8-bit
    TXA
    BNE  S8SETLZF
    BIT  LZF
    BMI  S8CNV2ASCII
    BPL  S8MOVUPTBL
S8SETLZF:
    LDX  #$80
    STX  LZF
S8CNV2ASCII:
    ORA  #$30
    JSR  CHROUT
S8MOVUPTBL:
    INY
    CPY  #$02   ; END OF TABLE?
    BCC  S8NEXTDIG
    LDA  $31    ; LAST DIGIT
    ORA  #$30
    JSR  CHROUT
    ; RESTORE Y & X
    PLA
    TAY
    PLA
    TAX
    RTS
; END S8OUT

; This routine inverts 8-bit sign and
; prints a '-'. Clobbers A.
S8OUTNEG:
    BIT  $31
    BPL  S8OUTEND
    JSR  S8INVSGN
    LDA  #$2D   ; '-'
    JSR  CHROUT 
S8OUTEND:
    RTS
; END S8OUTNEG

; Inverts sign of $31
; Clobbers A.
S8INVSGN:
    LDA  $31    ; LOAD LSB
    EOR  #$FF   ; FLIP BITS
    CLC
    ADC  #1     ; ADD ONE
    STA  $31    ; STORE
    RTS         ; DONE

S8SUBTABLE:
    dcb  100
    dcb  10
signed16bit.asm
; This is the start of the 16-bit library.

define CHROUT $ffd2
define LZF  $30

    LDY  #0
NUMLOOP:
    LDA  NUMBERS,Y
    STA  $31    ; LSB
    PHA         ; SAVE
    INY
    LDA  NUMBERS,Y
    STA  $32    ; MSB
    PHA         ; SAVE
    JSR  S16OUT ; PRINT AS SIGNED
    LDA  #7     ; '\t'
    JSR  CHROUT
    PLA         ; RESTORE
    STA  $32
    PLA         ; RESTORE
    STA  $31
    JSR  U16OUT ; PRINT AS UNSIGNED
    LDA  #13    ; '\n'
    JSR  CHROUT
    INY
    CPY  #10    ; 5 numbers * 2 bytes
    BNE NUMLOOP
    BRK

NUMBERS:
    dcw  -32768, 32767, -1, 1, 0


; S16OUT - print   signed 16-bit value in $31/$32
; U16OUT - print unsigned 16-bit value in $31/$32
; Based on code by Leo Scanlon in
; 6502 Software Design, 1980
; $31 LSB (clobbered)
; $32 MSB (clobbered)
; $30 LEADING ZERO FLAG (LZF, clobbered)
; CLOBBERS A, PRESERVES X & Y

S16OUT:
    JSR  S16OUTNEG
U16OUT:
    ; SAVE X & Y
    TXA
    PHA
    TYA
    PHA
    ; begin
    LDY  #0     ; INIT TABLE POINTER
    STY  LZF    ; CLEAR LZF
S16NEXTDIG:
    LDX  #0
S16DOSUBTRACT:
    LDA  $31
    SEC
    SBC  S16SUBTABLE,Y
    STA  $31
    LDA  $32
    INY
    SBC  S16SUBTABLE,Y
    BCC  S16ADDBACK
    STA  $32
    INX
    DEY
    JMP  S16DOSUBTRACT
    
S16ADDBACK:
    DEY
    LDA  $31
    ADC  S16SUBTABLE,Y
    STA  $31
    TXA
    BNE  S16SETLZF
    BIT  LZF
    BMI  S16CNV2ASCII
    BPL  S16MOVUPTBL
S16SETLZF:
    LDX  #$80
    STX  LZF
S16CNV2ASCII:
    ORA  #$30
    JSR  CHROUT
S16MOVUPTBL:
    INY
    INY
    CPY  #$08   ; END OF TABLE?
    BCC  S16NEXTDIG
    LDA  $31    ; LAST DIGIT
    ORA  #$30
    JSR  CHROUT
    ; RESTORE Y & X
    PLA
    TAY
    PLA
    TAX
    RTS
; END S16OUT

; This routine inverts 16-bit sign and
; prints a '-'. Clobbers A.
S16OUTNEG:
    BIT  $32
    BPL  S16OUTEND
    JSR  S16INVSGN
    LDA  #$2D   ; '-'
    JSR  CHROUT 
S16OUTEND:
    RTS
; END S16OUTNEG

; Inverts sign of $31/$32
; Clobbers A.
S16INVSGN:
    LDA  $31    ; LOAD LSB
    EOR  #$FF   ; FLIP BITS
    CLC
    ADC  #1     ; ADD ONE
    STA  $31    ; STORE
    LDA  $32    ; LOAD MSB
    EOR  #$FF   ; FLIP BITS
    ADC  $0     ; ADD PREVIOUS CARRY
    STA  $32    ; STORE
    RTS         ; DONE

S16SUBTABLE:
    dcw  10000
    dcw  1000
    dcw  100
    dcw  10
signed32bit.asm
; This is the start of the 32-bit library.

define CHROUT $ffd2
define LZF  $30

    LDY  #0
NUMLOOP:
    LDA  NUMBERS,Y
    STA  $31    ; LSB
    PHA         ; SAVE
    INY
    LDA  NUMBERS,Y
    STA  $32    ; NEXT
    PHA         ; SAVE
    INY
    LDA  NUMBERS,Y
    STA  $33    ; NEXT
    PHA         ; SAVE
    INY
    LDA  NUMBERS,Y
    STA  $34    ; MSB
    PHA         ; SAVE
    JSR  S32OUT ; PRINT AS SIGNED
    LDA  #7     ; '\t'
    JSR  CHROUT
    PLA         ; RESTORE
    STA  $34
    PLA         ; RESTORE
    STA  $33
    PLA         ; RESTORE
    STA  $32
    PLA         ; RESTORE
    STA  $31
    JSR  U32OUT ; PRINT AS UNSIGNED
    LDA  #13    ; '\n'
    JSR  CHROUT
    INY
    CPY  #32    ; 8 numbers * 4 bytes
    BNE NUMLOOP
    BRK

NUMBERS:
    dcq  -2147483648,2147483647,-1000000000, -32768, 32767, -1, 1, 0


; S32OUT - print   signed 32-bit value in $31/$32/$33/$34
; U32OUT - print unsigned 32-bit value in $31/$32/$33/$34
; Based on code by Leo Scanlon in
; 6502 Software Design, 1980
; $31 LSB (clobbered)
; $32     (clobbered)
; $33     (clobbered)
; $34 MSB (clobbered)
; $30 LEADING ZERO FLAG (LZF, clobbered)
; CLOBBERS A, PRESERVES X & Y

S32OUT:
    JSR  S32OUTNEG
U32OUT:
    ; SAVE X & Y
    TXA
    PHA
    TYA
    PHA
    ; begin
    LDY  #0     ; INIT TABLE POINTER
    STY  LZF    ; CLEAR LZF
S32NEXTDIG:
    LDX  #0
S32DOSUBTRACT:
    LDA  $31
    SEC
    SBC  S32SUBTABLE,Y
    STA  $31
    LDA  $32
    INY
    SBC  S32SUBTABLE,Y
    STA  $32
    LDA  $33
    INY
    SBC  S32SUBTABLE,Y
    STA  $33
    LDA  $34
    INY
    SBC  S32SUBTABLE,Y
    BCC  S32ADDBACK
    STA  $34
    INX
    DEY
    DEY
    DEY
    JMP  S32DOSUBTRACT
    
S32ADDBACK:
    DEY
    DEY
    DEY
    LDA  $31
    ADC  S32SUBTABLE,Y
    STA  $31
    INY
    LDA  $32
    ADC  S32SUBTABLE,Y
    STA  $32
    INY
    LDA  $33
    ADC  S32SUBTABLE,Y
    STA  $33
    TXA
    BNE  S32SETLZF
    BIT  LZF
    BMI  S32CNV2ASCII
    BPL  S32MOVUPTBL
S32SETLZF:
    LDX  #$80
    STX  LZF
S32CNV2ASCII:
    ORA  #$30
    JSR  CHROUT
S32MOVUPTBL:
    INY
    INY
    CPY  #36    ; END OF TABLE?
    BCC  S32NEXTDIG
    LDA  $31    ; LAST DIGIT
    ORA  #$30
    JSR  CHROUT
    ; RESTORE Y & X
    PLA
    TAY
    PLA
    TAX
    RTS
; END S32OUT

; This routine inverts 16bit sign and
; prints a '-'. Clobbers A.
S32OUTNEG:
    BIT  $34
    BPL  S32OUTEND
    JSR  S32INVSGN
    LDA  #$2D   ; '-'
    JSR  CHROUT 
S32OUTEND:
    RTS
; END S32OUTNEG

; Inverts sign of $31/$32/$33/$34
; Clobbers A.
S32INVSGN:
    LDA  $31    ; LOAD LSB
    EOR  #$FF   ; FLIP BITS
    CLC
    ADC  #1     ; ADD ONE
    STA  $31    ; STORE
    LDA  $32    ; LOAD MSB
    EOR  #$FF   ; FLIP BITS
    ADC  $0     ; ADD PREVIOUS CARRY
    STA  $32    ; STORE
    LDA  $33    ; LOAD MSB
    EOR  #$FF   ; FLIP BITS
    ADC  $0     ; ADD PREVIOUS CARRY
    STA  $33    ; STORE
    LDA  $34    ; LOAD MSB
    EOR  #$FF   ; FLIP BITS
    ADC  $0     ; ADD PREVIOUS CARRY
    STA  $34    ; STORE
    RTS         ; DONE

S32SUBTABLE:
    dcq  1000000000
    dcq  100000000
    dcq  10000000
    dcq  1000000
    dcq  100000
    dcq  10000
    dcq  1000
    dcq  100
    dcq  10

Post navigation

❮ Previous Post: Chapter 6502-6 – Numbers and Math
Next Post: Chapter x86_64-0 – Where to Begin? ❯

Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.

Copyright © 2018 – 2025 Programming by Design.