The computer is coming along nicely. Next a Display is added to the system.
The display hangs a bit over the side of the board as the SN74LS21 takes up some extra space. But already I only need only 2kb of address space instead of 8kb like the Ben Eater original.
Thanks to the macro assembler the source code is a lot shorter then the version from Ben Eater. One could probably shorten it further but I'm into over engineering.
.listbytes 16
.pagelength 66
.case +
;;
; VIA register
;
.segment "VIA"
.scope VIA
IORB = $7F00 ; Output Register "B" Input Register "B"
IORA = $7F01 ; Output Register "A" Input Register "A"
DDRB = $7F02 ; Data Direction Register "B"
DDRA = $7F03 ; Data Direction Register "A"
T1C_L = $7F04 ; T1 Low-Order
T1C_H = $7F05 ; T1 High-Order Counter
T1L_L = $7F06 ; T1 Low-Order Latches
T1L_H = $7F07 ; T1 High-Order Latches
T2C_L = $7F08 ; T2 Low-Order
T2C_H = $7F09 ; T2 High-Order Counter
SR = $7F0A ; Shift Register
ACR = $7F0B ; Auxiliary Control Register
PCR = $7F0C ; Peripheral Control Register
IFR = $7F0D ; Interrupt Flag Register
IER = $7F0E ; Interrupt Enable Register
RA = $7F0F ; Same as Reg 1 except no "Handshake"
;;
; Set VIA data direction register A
;
.macro Set_A Value
LDA Value
STA VIA::DDRA
.endmacro
;;
; Set VIA data direction register B
;
.macro Set_B Value
LDA Value
STA VIA::DDRB
.endmacro
;;
; Set VIA output register A
;
.macro Out_A Value
LDA Value
STA VIA::IORA
.endmacro
;;
; Set VIA output register B
;
.macro Out_B Value
LDA Value
STA VIA::IORB
.endmacro
.endscope
;;
; LCD Display
;
.scope LCD
E = %10000000
RW = %01000000
RS = %00100000
;;
; Send Data to LCD display
.macro Control_LCD Instruction
Out_B Instruction
Out_A #0 ; Clear RS, RW, E bits
Out_A #LCD::E ; Set E bit to send instruction
Out_A #0 ; Clear E bit
.endmacro
;;
; Send Data to LCD display
.macro Data_LCD Data
Out_B Data
Out_A #LCD::RS ; Set RS, Clear RW, E bits
Out_A #(LCD::RS | LCD::E) ; Set E bit to send data
Out_A #LCD::RS ; Clear E bit
.endmacro
.endscope
.segment "CODE"
Do_RES: Set_A #%11100000 ; Set top 3 pin as output
Set_B #%11111111 ; Set all pins as output
Control_LCD #%00111000 ; Set 8-bit mode; 2 line display; 5×8 font
Control_LCD #%00001110 ; Display in; cursor on; blink off
Control_LCD #%00000110 ; Increment and shift cursor; don't shift display
Control_LCD #%00000001 ; Clear Display
Data_LCD #'H' ; Send character 'H' to display
Data_LCD #'e' ; Send character 'e' to display
Data_LCD #'l' ; Send character 'l' to display
Data_LCD #'l' ; Send character 'l' to display
Data_LCD #'o' ; Send character 'o' to display
Data_LCD #',' ; Send character ',' to display
Data_LCD #' ' ; Send character ' ' to display
Data_LCD #'W' ; Send character 'W' to display
Data_LCD #'o' ; Send character 'o' to display
Data_LCD #'r' ; Send character 'r' to display
Data_LCD #'l' ; Send character 'l' to display
Data_LCD #'d' ; Send character 'd' to display
Data_LCD #'!' ; Send character '!' to display
STP ; Stop Processor
Do_NMI: RTI
Do_IRQ: RTI
.segment "HEADER"
.word Do_NMI
.word Do_RES
.word Do_IRQ
You find the source code for the program with makefile, linker configuration file and assembler source code on GitLab: 6502Tutorial — Tools/Create_LED.