6502 Routine to Display Byte as 3Digits
Write a piece of 6502 or 65C02 assembler that -- Prompts the user to enter a 3 digit number between 0 and 255
- Reads in the number as ASCII characters
- Converts the ASCII characters into an 8 bit decimal number
- Writes out the decimal number as a binary number
- Writes out the decimal number as a hexadecimal number
Solution
number.65s
*= $0600
io_area = $e000
io_cls = io_area + 0 ; clear terminal window
io_putc = io_area + 1 ; put char
io_putr = io_area + 2 ; put raw char (doesn’t interpret CR/LF)
io_puth = io_area + 3 ; put as hex number
io_getc = io_area + 4 ; get char
LDX #0 ; start index to zero
print1: LDA msg,X ; load character from current index
BEQ nxt1 ; if we reached the end of the string, exit the loop
STA io_putc ; print the char on the screen
INX ; advance to next char
JMP print1 ; repeat
nxt1: LDX #0
read1: JSR read ; read a character from the user
CMP #$0D ; see if the user pressed enter
BEQ nxt2 ; if so, end reading characters
CPY #3 ; see if we read 3 digits already
BPL skip ; if x is >=3, do not save it in buffer
STA buffer,X ; save it in number at current offset
INX ; increment offset
skip: JMP read1
nxt2: AND #0 ; clear A
STA buffer,X ; set end of string
LDX #0 ; start counter to zero
todec: LDA buffer,X ; load character from current index
BEQ nxt3 ; if we reached the end of the string, exit the loop
SEC ; clear borrow
SBC #$30 ; convert ascii to decimal by subtracting ‘0’
PHA ; save digit in stack
LDA numdec ; load current converted number in a
JSR mul10 ; multiply by 10
STA numdec ; save result in the variable
PLA ; recover A from the stack
CLC
ADC numdec ; add digit to old number*10
STA numdec ; save as current converted number
INX ; go to next character
JMP todec
nxt3: LDA #$0A ; print in a new line
STA io_putc
LDA #$0D ; print in a carriage return
STA io_putc
LDA numdec ; load the converted number
JSR putbin ; print it in binary
LDA #$0A ; print in a new line
STA io_putc
LDA #$0D ; print in a carriage return
STA io_putc
LDA numdec ; load the converted number
JSR puthex ; print it in hexadecimal
BRK
;————————————————-
; read subroutine
; reads a character from the user
;————————————————-
read: LDA io_getc ; read a char
BEQ read ; see if there was a char
STA io_putc ; display read character
RTS
;————————————————-
; mul10 subroutine
; multiplies A by 10
;————————————————-
mul10: PHA ; save a in the stack
ASL ; multiply a by 8 shifting 3 times to the left
ASL
ASL
STA temp ; save a*8 in temp
PLA ; recover old A value from stack
ASL ; multiply by 2 shifting once to the left
CLC ; clear carry
ADC temp ; add a*8 to a*2 to get a*10
RTS ; return
;————————————————-
; putbin subroutine
; prints the decimal number in A as a binary
;————————————————-
putbin: LDX #8 ; load X with 8 to count the 8 bits in the number
TAY ; save A in Y
shlbit: TYA ; recover the current value of A
ASL ; shift to the left to put the MSB in the carry
TAY ; save the value of A
BCS one ; if the carry is set, print a 1
LDA #$30 ; load A with ascii ‘0’
JMP pbit ; go to print the bit
one: LDA #$31 ; load A with ascii ‘1’
pbit: STA io_putc ; show the bit on the screen
DEX ; decrement X
BNE shlbit ; repeat while X is not zero
RTS
;————————————————-
; puthex subroutine
; prints the decimal number in A as a hexadecimal
;————————————————-
puthex: TAY ; save A in Y
LSR ; shift to the left 4 times to put the upper 4 bits in the lower part of A
LSR
LSR
LSR
TAX ; put the value in X
LDA hexdig,X ; load the converted hexadecimal digit
STA io_putc ; print it on the screen
TYA ; load the old value of A
AND #$0F ; leave only the lower 4 bits of A
TAX ; put the value in X
LDA hexdig,X ; load the converted hexadecimal digit
STA io_putc ; print it on the screen
RTS
msg: .DB “Enter a number between 0 and 255: “,0
hexdig: .DB “0123456789ABCDEF”
buffer: .DS 4
temp: .DB 0
numdec: .DB 0 ; here will be the decimal number converted from ASCII
number.asm
*= $0600
io_area = $e000
io_cls = io_area + 0 ; clear terminal window
io_putc = io_area + 1 ; put char
io_putr = io_area + 2 ; put raw char (doesn’t interpret CR/LF)
io_puth = io_area + 3 ; put as hex number
io_getc = io_area + 4 ; get char
LDX #0 ; start index to zero
print1: LDA msg,X ; load character from current index
BEQ nxt1 ; if we reached the end of the string, exit the loop
STA io_putc ; print the char on the screen
INX ; advance to next char
JMP print1 ; repeat
nxt1: LDX #0
read1: JSR read ; read a character from the user
CMP #$0D ; see if the user pressed enter
BEQ nxt2 ; if so, end reading characters
CPY #3 ; see if we read 3 digits already
BPL skip ; if x is >=3, do not save it in buffer
STA buffer,X ; save it in number at current offset
INX ; increment offset
skip: JMP read1
nxt2: AND #0 ; clear A
STA buffer,X ; set end of string
LDX #0 ; start counter to zero
todec: LDA buffer,X ; load character from current index
BEQ nxt3 ; if we reached the end of the string, exit the loop
SEC ; clear borrow
SBC #$30 ; convert ascii to decimal by subtracting ‘0’
PHA ; save digit in stack
LDA numdec ; load current converted number in a
JSR mul10 ; multiply by 10
STA numdec ; save result in the variable
PLA ; recover A from the stack
CLC
ADC numdec ; add digit to old number*10
STA numdec ; save as current converted number
INX ; go to next character
JMP todec
nxt3: LDA #$0A ; print in a new line
STA io_putc
LDA #$0D ; print in a carriage return
STA io_putc
LDA numdec ; load the converted number
JSR putbin ; print it in binary
LDA #$0A ; print in a new line
STA io_putc
LDA #$0D ; print in a carriage return
STA io_putc
LDA numdec ; load the converted number
JSR puthex ; print it in hexadecimal
BRK
;————————————————-
; read subroutine
; reads a character from the user
;————————————————-
read: LDA io_getc ; read a char
BEQ read ; see if there was a char
STA io_putc ; display read character
RTS
;————————————————-
; mul10 subroutine
; multiplies A by 10
;————————————————-
mul10: PHA ; save a in the stack
ASL ; multiply a by 8 shifting 3 times to the left
ASL
ASL
STA temp ; save a*8 in temp
PLA ; recover old A value from stack
ASL ; multiply by 2 shifting once to the left
CLC ; clear carry
ADC temp ; add a*8 to a*2 to get a*10
RTS ; return
;————————————————-
; putbin subroutine
; prints the decimal number in A as a binary
;————————————————-
putbin: LDX #8 ; load X with 8 to count the 8 bits in the number
TAY ; save A in Y
shlbit: TYA ; recover the current value of A
ASL ; shift to the left to put the MSB in the carry
TAY ; save the value of A
BCS one ; if the carry is set, print a 1
LDA #$30 ; load A with ascii ‘0’
JMP pbit ; go to print the bit
one: LDA #$31 ; load A with ascii ‘1’
pbit: STA io_putc ; show the bit on the screen
DEX ; decrement X
BNE shlbit ; repeat while X is not zero
RTS
;————————————————-
; puthex subroutine
; prints the decimal number in A as a hexadecimal
;————————————————-
puthex: TAY ; save A in Y
LSR ; shift to the left 4 times to put the upper 4 bits in the lower part of A
LSR
LSR
LSR
TAX ; put the value in X
LDA hexdig,X ; load the converted hexadecimal digit
STA io_putc ; print it on the screen
TYA ; load the old value of A
AND #$0F ; leave only the lower 4 bits of A
TAX ; put the value in X
LDA hexdig,X ; load the converted hexadecimal digit
STA io_putc ; print it on the screen
RTS
msg: .DB “Enter a number between 0 and 255: “,0
hexdig: .DB “0123456789ABCDEF”
buffer: .DS 4
temp: .DB 0
numdec: .DB 0 ; here will be the decimal number converted from ASCII