6502/bins/bin2dec.s
2022-05-12 21:36:39 +09:30

163 lines
3.0 KiB
ArmAsm

PORTB = $6000
PORTA = $6001
DDRB = $6002
DDRA = $6003
value = $0200 ; 2 bytes
mod10 = $0202 ; 2 bytes
message = $0204 ; 6 bytes
E = %10000000
RW = %01000000
RS = %00100000
.org $8000
reset:
lda #%11111111 ; set all pins on port B to output
sta DDRB
lda #%11100000 ; set top 3 pins on port A to output
sta DDRA
lda #%00111000 ; set 8-bit mode, 2 line display, 5x8 font.
jsr command_to_lcd
lda #%00001110 ; set display and curson on, do not blink
jsr command_to_lcd
lda #%00000110 ; set entry mode increment and display shift off
jsr command_to_lcd
lda #%00000001
jsr command_to_lcd
; null terminated string init
lda #0
sta message
; initialise value to number to be converted
lda number
sta value
lda number + 1
sta value + 1
divide:
; initialise mod10 to be zero
lda #0
sta mod10
sta mod10 + 1
clc ; clear carry
ldx #16
divloop:
; rotating the qotient and remainder
rol value
rol value + 1
rol mod10
rol mod10 + 1
; a,y = dividend - divisor
sec
lda mod10
sbc #10
tay ; save low byte to Y
lda mod10 + 1
sbc #0
bcc ignore_result ; branch if dividend < divisor
; store result
sty mod10
sta mod10 + 1
ignore_result:
dex
bne divloop
rol value ; shift in the last bit of the quotient
rol value + 1
lda mod10
clc
adc #"0"
jsr push_char_message
; if value != 0, continue dividing
lda value
ora value + 1
bne divide ; branche if value isn't 0
; once we are done dividing, print message.
ldx #0
print:
lda message,x
beq loop ; load sets zero flag (checked by beq) when it loads a zero byte.
jsr ASCII_to_lcd
inx
jmp print
loop:
jmp loop
number: .word 1729
push_char_message:
pha ; push char to stack
ldy #0
char_loop:
lda message,y ; get char on string into x
tax
pla
sta message,y ; add char from from stack to string
iny
txa ; put char in x into a
pha ; put char onto stack, if 0 zero flag set
bne char_loop
pla
sta message,y ; put null back onto end of string
rts ; RETURN
lcd_wait:
pha ; save porta to stack
lda #%00000000 ; set PORTB to input
sta DDRB
lcdbusy:
lda #RW
sta PORTA
lda #(RW | E)
sta PORTA
lda PORTB
and #%10000000 ; check LCD busy flag
bne lcdbusy ; branch if it is NOT set
lda #RW
sta PORTA
lda #%11111111 ; set PORTB to output again
sta DDRB
pla ; load stack value back to porta
rts ; RETURN
command_to_lcd:
jsr lcd_wait ; ensure LCD is not busy before sending instruction
sta PORTB
lda #0 ; clear RS/RW/E bits
sta PORTA
lda #E ; set enable bit to send instruction
sta PORTA
lda #0 ; clear RS/RW/E bits
sta PORTA
rts ; RETURN
char_to_lcd:
jsr lcd_wait ; ensure LCD is not busy before sending instruction
sta PORTB
lda #RS ; RS set
sta PORTA
lda #(RS | E) ; RS and E set
sta PORTA
lda #RS ; RS set
sta PORTA
rts ; RETURN
.org $fffc
.word reset
.word $0000