This is part 4 in a series of posts in which I will document my journey (and mistakes) of building a 6502 based computer.
A Whole System
I now have a compute board, screen, and keypad. Linking it all up is just a case of running wires from each board back to the I/O point on the compute board.
My next challange is to write some code to make it all work.
The screen is just a shift register system and so it can be driven much like an SPI bus, so I created a “SPI_Write_Byte” function.
SPI_Write_Byte: ; writes the byte in A register to SPI bus. sta ZP_Temp ; zero page ldx #$08 SPI_loop: asl ZP_Temp ; bit shift zero page bcc SPI_out_low_bit lda PORTB and #0b11111100 ; data low & clock low ora #0b00000010 ; data high & clock unchanged sta PORTB inc PORTB ; set clock high dec PORTB ; set clock low jmp SPI_bit_done SPI_out_low_bit: lda PORTB and #0b11111100 ; data low & clock low sta PORTB inc PORTB ; set clock high dec PORTB ; set clock low SPI_bit_done dex bne SPI_loop rts
The screen can display three bytes as hex, which is six digits of a seven segment display. Each byte to be displayed gets split into two 4 bit sections, those 4 bits are an index to an array to the right bits needed to display the single hex digit. In this example $400 is the byte to display, $420 and $421 are bit masks to turn off single bits of the display. The bit mask magic allows for turning on or off the decimal point or blinking the whole digit.
lda $400 tay and #$0F tax lda Array_7seg,x and $420 jsr SPI_Write_Byte tya and #$F0 lsr lsr lsr lsr tax lda Array_7seg,x and $421 jsr SPI_Write_Byte
The keypad is driven as just a row and column system, we set each row high one at a time and see if any column is high, then we do (col*4)+row math to get an index to an array for what keycode to return. $405 is just a temporary storage location that could be moved to ZeroPage.
readKeypad: ldx #$04 ; Row 4 - counting down ldy #0b10000000 ; Row 1 ScanRow: sty PORTB lda PORTA and #0b00011111 ; mask off keypad only cmp #$00 bne Row_Found dex ; count row down tya lsr tay cmp #0b00001000 bne ScanRow lda #$ff rts Row_Found: stx $405 ; store row ldy #$ff FindCol: iny lsr bcc FindCol tya asl asl ; col * 4 clc adc $405 ; add row tax lda KeypadArray,x rts
The keypad has 16 buttons for the hex digits, and also 4 control buttons of “R”, “W”, “X”, “ENT”.
The memory monitor is a simple state machine and pushing R, W, or X moves between modes and allows for Reading, Writing, or eXecuting from memory.
This allows the user to “toggle” code into memory and then run that code.
The code for the monitor is not ready to share and a bit large for a blog post.
In part 5 we will create a single PCB with compute, keypad, screen and an SD card interface.