Files
2026-07-24 10:49:40 +01:00

141 lines
2.6 KiB
NASM

;
; A0 D4
; A1 D5
; A2 D6
; A3 D7
; A4 RS
; A5 E
.ORG 0x80
PORTA .EQU 0x00
PORTB .EQU 0x01
PORTC .EQU 0x02
PORTD .EQU 0x03
DDRA .EQU 0x04
DDRB .EQU 0x05
DDRC .EQU 0x06
TCR .EQU 0x08
TDR .EQU 0x09
MR .EQU 0x0A
PCR .EQU 0x0B
ACR .EQU 0x0E
ADR .EQU 0x0F
SCRATCH .EQU 0x10
TMPX .EQU 0x11
start:
JSR init_dbus
JSR lcd_init
LDA #txt_hellorld
JSR print
endloop:
BRA endloop
; Text symbols need to be within the first 255 bytes of the code - cus 8 bit registers.
txt_hellorld:
DB "Hellorld",0
; Configure port A to be the interface to the LCD
init_dbus:
LDA #0xFF ; 0xFF -> A Reg
STA DDRA ; All pins output
LDA #0x00 ; 0x00 -> A Reg
STA PORTA ; All pins low
RTS
; Send a nibble plus the RS pin
send_nibble:
ORA #0x20 ; Add the E pin high
STA PORTA ; Output the data
JSR delay ; Wait
AND #0x1F ; Remove the E pin again
STA PORTA ; Output again
JSR delay ; wait
RTS
; Send a data byte split into 2 nibbles. Byte is in A
send_data:
STA SCRATCH ; Store the byte for later use
.REPEAT 4
LSRA ; Shift right 4 times to get the upper nibble
.ENDR
ORA #0x10 ; Set the RS pin high
JSR send_nibble ; Send it
LDA SCRATCH ; Get the old byte back
AND #0x0F ; Mask out just the lower nibble
ORA #0x10 ; Add the RS pin again
JSR send_nibble ; Send it
RTS
; Send an instruction byte split into 2 nibbles. Byte is in A
send_inst:
STA SCRATCH ; Store the byte for later use
.REPEAT 4
LSRA ; Shift right 4 times to get the upper nibble
.ENDR
JSR send_nibble ; Send it
LDA SCRATCH ; Get the old byte back
AND #0x0F ; Mask out the lower nibble
JSR send_nibble ; Send it
RTS
; Clear the screen and home the cursor
lcd_clr:
LDA #0x01 ; Clear screen instruction
JSR send_inst ; Send it
RTS
; Initialize the LCD into 4 bit mode. This assumes that it's in
; the power-on 8 bit state, otherwise the instructions get out
; of sequence and things don't work.
lcd_init:
LDA #0x02 ; 4 bit mode
JSR send_nibble
LDA #0x28 ; 4 bit mode and 2 line mode
JSR send_inst
LDA #0x0E ; Auto increment
JSR send_inst
LDA #0x06 ; Display on
JSR send_inst
JSR lcd_clr ; CLS
RTS
; A short delay to make things work.
delay:
STX TMPX ; Store X into the temporary store
LDX 0x13 ; 0x13 -> X
@ldel:
NOP ; Nothing
DECX ; Decrement X
BNE @ldel ; Repeat until zero
LDX TMPX ; Restore X
RTS
; Print a string. Address of the string is in A
print:
TAX ; Put A into X
@printloop:
LDA ,X ; Grab the byte at X
BEQ @endprint ; If it's zero then bail
JSR send_data ; Send that byte
INCX ; Increment X
BRA @printloop ; Next byte.
@endprint:
RTS