;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Output "H" to LCD screen. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;processor 6502 ; Processor directive. PORTB = $6000 ;;; $7F00 Our data port. PORTA = $6001 ;;; $7F01 Our control port. DDRB = $6002 ;;; $7F02 Data Direction Register for Port B. 1: output, 0: input. DDRA = $6003 ;;; $7F03 Data Direction Register for Port A. E = %10000000 ; Enable bit. RW = %01000000 ; Read/Write bit. RS = %00100000 ; Register Select bit. ; E and RS OR'd together is %10100000. ;;;seg .U code org $8000 ; Define the code origin of $8000 (ROM) starting point. Reset: ; INITIALIZE THE STACK ldx #$FF ; Stack always starts with 01xx so we only need lower byte (FF) put in X register. $01FF = top of the stack. txs ; Transfer X register to Stack Pointer. ; INITIALIZE THE V.I.A. (65c22) lda #%11111111 ; #$FF Set all port *B* pins as output. sta DDRB ; Port B Data direction register. lda #%11100000 ; #$E0 Set top 3 port *A* pins as output. sta DDRA ; Port A Data direction register. ; INITIALIZE LCD MODULE Setup1: ; FUNCTION SET. RS = 0, R/W! = 0. lda #%00111000 ; Set 8-bit mode, 2-line display, 5x8 font. jsr lcd_instruction ; Jump to lcd instruction subroutine. Setup2: ; DISPLAY ON/OFF CONTROL. RS = 0, R/W! = 0. lda #%00001110 ; Display on, cursor on, blink off. jsr lcd_instruction ; Jump to lcd instruction subroutine. Setup3: ; ENTRY MODE SET. RS = 0, R/W! = 0. lda #%00000110 ; Increment and shift cursor, don't shift the display. jsr lcd_instruction ; Jump to lcd instruction subroutine. ; SEND DATA TO LCD MODULE SendData: ; Keep the RS bit set to 1 (for data, not instruction) while toggling E bit in order to send one character at a time. lda #"H" ; Letter H. jsr print_char ; Jump to print character subroutine. Start: Loop: jmp Loop ; LCD SUBROUTINES FOR INSTRUCTIONS AND DATA lcd_instruction: pha ; Push A onto the stack. sta PORTB lda #0 ; Clear RS, R/W, and E bits in top 3 lines of Port A. sta PORTA lda #E ; Set Enable bit to 1 to send the instruction. sta PORTA lda #0 ; Clear RS, R/W, and E bits *again*. sta PORTA pla ; Pull A off the stack. rts ; Return from subroutine. print_char: ; A contains character to be printed when subroutine is called. sta PORTB ; Send letter H once RS is set, E is toggled, and RS lda #RS ; Set RS, clear RW & E bits. sta PORTA lda #(RS | E) ; Set E bit to send instruction. ORing keeps RS bit set while setting E. sta PORTA lda #RS ; Clear RW and E bits. sta PORTA ;rts ; Return from subroutine. org $FFFC ; Load the program counter with the address inside memory positions $FFFC and $FFFD (two bytes). word Reset ; Reset vector at FFFC and FFFD where the program starts. ;word $xxxx ; This is required by the cartridges. Interrupt vector is at FFFE. (Break vector on 6507?) ; The label Start is just an alias to ROM address $F000 at the start of our ROM. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; RS pin is Register Select. 0 = instruction, 1 = data. ; R/W pin: Read = 1, Write = 0. ; E pin: Enable = 1. ; Stack: 0100 to 01FF.