diff --git a/Software/06_button_test/Makefile b/Software/06_button_test/Makefile new file mode 100644 index 0000000..3898721 --- /dev/null +++ b/Software/06_button_test/Makefile @@ -0,0 +1,12 @@ +all: button_test.rom + +clean: + rm -f *.lst *.map *.o *.rom + +%.o: src/%.s + ca65 -o $@ $< + +%.rom: %.o ../kw6502.cfg + ld65 -C ../kw6502.cfg -o build/$@ $< + +.PHONY: all clean \ No newline at end of file diff --git a/Software/06_button_test/README.md b/Software/06_button_test/README.md new file mode 100644 index 0000000..e1f6afd --- /dev/null +++ b/Software/06_button_test/README.md @@ -0,0 +1,4 @@ +# Button Test + +This program listens for button presses and prints a different character on the lcd for every button +It also contains two custom lcd characters: arrow up and arrow down. diff --git a/Software/06_button_test/build/button_test.rom b/Software/06_button_test/build/button_test.rom new file mode 100644 index 0000000..17b3aa0 Binary files /dev/null and b/Software/06_button_test/build/button_test.rom differ diff --git a/Software/06_button_test/src/button_test.s b/Software/06_button_test/src/button_test.s new file mode 100644 index 0000000..53b1059 --- /dev/null +++ b/Software/06_button_test/src/button_test.s @@ -0,0 +1,36 @@ +.segment "ZP" + switch: .res 1 ; Holds switch code pushed + +.segment "RAM" + +.segment "ACIA" + acia_data: .res 1 ; Read: Receiver Data Register - Write: Transmit Data Register + acia_status: .res 1 ; Read: Status Register - Write: Programmed Reset (Data is "Don't Care") + acia_command: .res 1 ; Command Register + acia_control: .res 1 ; Control Register + +.segment "VIA" + via_b: .res 1 ; Register "B" + via_a: .res 1 ; Register "A" + via_ddrb: .res 1 ; Data Direction Register "B" + via_ddra: .res 1 ; Data Direction Register "A" + via_t1c_l: .res 1 ; Read: T1 Low-Order Counter - Write: T1 Low-Order Latches + via_t1c_h: .res 1 ; T1 High-Order Counter + via_t1l_l: .res 1 ; T1 Low-Order Latches + via_t1l_h: .res 1 ; T1 High-Order Latches + via_t2c_l: .res 1 ; Read: T2 Low-Order Counter - Write: T2 Low-Order Latches + via_t2c_h: .res 1 ; T2 High-Order Counter + via_sr: .res 1 ; Shift Register + via_acr: .res 1 ; Auxilary Control Register + via_pcr: .res 1 ; Peripheral Control Register + via_ifr: .res 1 ; Interrupt Flag Register + via_ier: .res 1 ; Interrupt Enable Register + via_a_noh: .res 1 ; Same as Register "A" (via_a) except no "Handshake" + +.segment "CODE" + .include "main.s" + +.segment "VECTORS" + .word nmi + .word main + .word irq \ No newline at end of file diff --git a/Software/06_button_test/src/lcd.s b/Software/06_button_test/src/lcd.s new file mode 100644 index 0000000..2917e9e --- /dev/null +++ b/Software/06_button_test/src/lcd.s @@ -0,0 +1,64 @@ +E = %10000000 +RW = %01000000 +RS = %00100000 + +init_lcd: + lda #%11111111 ; Set all pins on port B to output + sta via_ddrb + lda #%11100000 ; Set top 3 pins on port A to output + sta via_ddra + + lda #%00111000 ; Set 8-bit mode; 2-line display; 5x8 font + jsr lcd_instruction + lda #%00001110 ; Display on; cursor on; blink off + jsr lcd_instruction + lda #%00000110 ; Increment and shift cursor; don't shift display + jsr lcd_instruction + lda #$00000001 ; Clear display + jsr lcd_instruction + rts + +_lcd_wait: + pha + lda #%00000000 ; Port B is input + sta via_ddrb +@lcdbusy: + lda #RW + sta via_a + lda #(RW | E) + sta via_a + lda via_b + and #%10000000 + bne @lcdbusy + + lda #RW + sta via_a + lda #%11111111 ; Port B is output + sta via_ddrb + pla + rts + +lcd_instruction: + jsr _lcd_wait + sta via_b + lda #0 ; Clear RS/RW/E bits + sta via_a + lda #E ; Set E bit to send instruction + sta via_a + lda #0 ; Clear RS/RW/E bits + sta via_a + rts + +write_lcd: + pha + jsr _lcd_wait + sta via_b + lda #RS ; Set RS; Clear RW/E bits + sta via_a + lda #(RS | E) ; Set E bit to send instruction + sta via_a + lda #RS ; Clear E bits + sta via_a + pla + rts + \ No newline at end of file diff --git a/Software/06_button_test/src/main.s b/Software/06_button_test/src/main.s new file mode 100644 index 0000000..c3fd01f --- /dev/null +++ b/Software/06_button_test/src/main.s @@ -0,0 +1,109 @@ + .include "lcd.s" + +main: + jsr init_lcd ; lcd.s - initialize lcd + jsr lcd_custom_chars + +funcn: + jsr getkey +left: + lda switch + cmp #%00001110 + bne top + lda #%01111111 + jsr write_lcd + jmp funcn + +top: + lda switch + cmp #%00001101 + bne right + lda #%00000000 + jsr write_lcd + jmp funcn + +right: + lda switch + cmp #%00001011 + bne down + lda #%01111110 + jsr write_lcd + jmp funcn + +down: + lda switch + cmp #%00000111 + bne unknown + lda #%00000001 + jsr write_lcd + jmp funcn + +unknown: + lda #'?' + jsr write_lcd + jmp funcn + + +; Subroutines +getkey: + lda via_a ; read switches + and #%00001111 ; mask out other bits + cmp #%00001111 ; no keys pushed? + beq getkey ; check again... + sta switch ; store value read +@again: + lda via_a ; wait for key up + and #%00001111 ; mask out other bits + cmp #%00001111 ; no keys pushed? + bne @again ; check again... + rts + +lcd_custom_chars: + lda #%01000000 ; First Custom CGRAM Character + jsr lcd_instruction + + ; Arrow Up + lda #%00000000 + jsr write_lcd + lda #%00000100 + jsr write_lcd + lda #%00001110 + jsr write_lcd + lda #%00010101 + jsr write_lcd + lda #%00000100 + jsr write_lcd + lda #%00000100 + jsr write_lcd + lda #%00000000 + jsr write_lcd + lda #%00000000 + jsr write_lcd + + ; Arrow Down + lda #%00000000 + jsr write_lcd + lda #%00000100 + jsr write_lcd + lda #%00000100 + jsr write_lcd + lda #%00010101 + jsr write_lcd + lda #%00001110 + jsr write_lcd + lda #%00000100 + jsr write_lcd + lda #%00000000 + jsr write_lcd + lda #%00000000 + jsr write_lcd + + lda #%10000000 ; Go back to writing to visible display + jsr lcd_instruction + rts + +nmi: + rti + +irq: + rti \ No newline at end of file diff --git a/Software/README.md b/Software/README.md index a15ccc4..c9e988e 100644 --- a/Software/README.md +++ b/Software/README.md @@ -8,6 +8,8 @@ This documentation provides necessary insight into software provided in the repo 2. [Serial Test](02_serial_test): This program reads and writes to the serial monitor. 3. [Serial and LCD](03_serial_and_lcd): This program reads from the serial monitor and output it on both the lcd and serial monitor 4. WIP [Shell](04_shell): This program creates a shell on both the lcd and serial monitor. +5. [MicroChess](05_microchess): Microchess for the Kim-1 was the first game program sold for home computers. After six months of development, the first copy was shipped on December 18, 1976. +6. [Button Test](06_button_test): This program listens for button presses and runs different code for every button ## Setting up development environment on Windows