6502 Routine to Display Byte as 3Digits

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