141 lines
2.6 KiB
NASM
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
|
|
|
|
|
|
|
|
|