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
And, Write a 6502 Assembler Programme that counts the number of times each letter occurs in a sentence and stores that in a buffer. You may presume that you can hard code in the string corresponding to the sentence and the string will be null terminated and entirely upper case. The buffer should be of size 26 (for each letter of the alphabet) and should store the  amount of each letter in the corresponding position in the buffer (i.e the number of A's in the sentence should be stored in position zero of the buffer and the number of S's should be stored in position 18). 

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