I'm working on a game for the Atari VCS and have been dusting off my 30+ year old skills in writing MOS 6502 assembly language.
The VCS runs at 1.19 MHz and is based on a MOS 6507 chip with some custom logic and 128 bytes only of RAM.
Outline of Problem
The game needs to display a value as 3 ASCII digits, but I'm working in full range signed and unsigned bytes, rather than BCD, so I now have the problem of converting from a full range byte to ASCII digits.
What I have so Far
I have been able to put the following together, and it appears to work. I'd welcome any tips for making it smaller, faster etc.
Currently the program is estimated to run in around 114+ cycles, just counting the instruction cycle counts with no branches taken.
; ; FormatUnsigned.asm ; ; 6502 routine to format an unsigned byte into a space ; followed by 2 decimal digits if < 100, or 3 decimal ; digits if >= 100. ; seg.u Variables org $80 char1 .byte ; output chars char2 .byte char3 .byte Temp .byte ; temp seg Code org $f000 TestFormat lda #211 ; sample value jsr FormatUnsigned ; format brk ; halt ; A = value to format unsigned FormatUnsigned: ldy #$20 ; default hundreds digit sty char1 ; is a space ; calculate char1 ldy #$30 ; '0' sec ; set carry for sub loop Sub100 sbc #100 iny ; y = '1', '2' bcs Sub100 ; loop whilst carry is not borrowed adc #100 ; add 100 back dey ; and take back the inc to y cpy #$30 ; if y is '0', just leave the space in there beq SkipHundreds sty char1 ; save '1' or '2' into char1 SkipHundreds ; format value < 100 into BCD tay ; save a in y lsr lsr lsr lsr and #$F ; get high nybble tax ; into x for indexing lda highNybble,x sta Temp ; save in temp tya ; get value - 100s back and #$0f ; low nybble tay ; low nybble in y cmp #$0a ; <10? bcc NoSub10 sbc #$0a ; subtract 10 tay ; save in y clc lda #$10 ; Add '10' to bcd saved value adc Temp sta Temp tya NoSub10 sed ; decimal mode adc Temp ; add bcd value to 0-9 in a sta Temp ; save bcd value cld ; leave decimal mode Write2ndChar lsr ; get high nybble lsr lsr lsr and #$0f adc #$30 sta char2 ; save 2nd character Write3rdChar lda Temp and #$0f ; get low nybble adc #$30 sta char3 ; save 3rd character rts highNybble .byte $00 .byte $16 .byte $32 .byte $48 .byte $64 .byte $80 .byte $96
The program works correctly for tested inputs, producing an output of $32 $31 $31 for the decimal value 211.