From fad701289fd566450353cf80ceb0f487f93ea6bb Mon Sep 17 00:00:00 2001 From: stid Date: Sat, 9 Nov 2019 19:10:52 -0800 Subject: [PATCH] Fine tune + Keyb2 (not impl yet) --- .gitignore | 4 +- README.md | 7 + hex.asm | 10 +- keyb.asm | 415 ++++++++++++++++++++++++++++++++++++++++++++++++++++ keyb2.asm | 237 ++++++++++++++++++++++++++++++ main.asm | 77 +++++----- math.asm | 2 + mem_map.asm | 53 +++++-- screen.asm | 17 ++- 9 files changed, 770 insertions(+), 52 deletions(-) create mode 100644 README.md create mode 100644 keyb.asm create mode 100644 keyb2.asm diff --git a/.gitignore b/.gitignore index e4320f6..c29a758 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,6 @@ bin/* .DS_Store *.o *.sym -*.lst \ No newline at end of file +*.lst +*.prg +buildlog.txt diff --git a/README.md b/README.md new file mode 100644 index 0000000..02b0b39 --- /dev/null +++ b/README.md @@ -0,0 +1,7 @@ +# Compile to Cart + +``` bash +cartconv -t normal -name "woz" -i main.prg -o woz.crt +x64 woz.crt +cartconv -i woz.crt -o woz.bin +``` diff --git a/hex.asm b/hex.asm index d4095ac..fa6fb6e 100644 --- a/hex.asm +++ b/hex.asm @@ -1,5 +1,8 @@ #importonce #import "mem_map.asm" +.filenamespace Hex + +.pc = * "Hex Routines" // ———————————————————————————————————— @@ -12,7 +15,7 @@ // .x: lsn ascii char // .y: entry value // ———————————————————————————————————— -binhex: pha //save byte +byteToHex: pha //save byte and #%00001111 //extract lsn tax //save it pla //recover byte @@ -28,8 +31,9 @@ binhex: pha //save byte // // convert nybble to hex ascii equivalent... binhex1: cmp #$0a - bcc binhex2 //in decimal range - adc #$66 //hex compensate + bcc binhex2 //in decimal range + sbc #$09 //hex compensate + rts binhex2: eor #%00110000 //finalize nybble rts //done diff --git a/keyb.asm b/keyb.asm new file mode 100644 index 0000000..2ad0a85 --- /dev/null +++ b/keyb.asm @@ -0,0 +1,415 @@ +#importonce +#import "mem_map.asm" +.filenamespace Keyboard + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Keyboard IO Routine + ~~~~~~~~~~~~~~~~~~~ + By: TWW/CTR + + + Preparatory Settings + ~~~~~~~~~~~~~~~~~~~~ + None + + + Destroys + ~~~~~~~~ + Accumulator + X-Register + Y-Register + Carry / Zero / Negative + $dc00 + $dc01 + $50-$5f + + + Footprint + ~~~~~~~~~ + #$206 Bytes + + + Information + ~~~~~~~~~~~ + The routine uses "2 Key rollower" or up to 3 if the key-combination doesen't induce shadowing. + If 2 or 3 keys are pressed simultaneously (within 1 scan) a "No Activity" state has to occur before new valid keys are returned. + RESTORE is not detectable and must be handled by NMI IRQ. + SHIFT LOCK is not detected due to unreliability. + + + Usage + ~~~~~ + Example Code: + + jsr Keyboard + bcs NoValidInput + stx TempX + sty TempY + cmp #$ff + beq NoNewAphanumericKey + // Check A for Alphanumeric keys + sta $0400 + NoNewAphanumericKey: + // Check X & Y for Non-Alphanumeric Keys + ldx TempX + ldy TempY + stx $0401 + sty $0402 + NoValidInput: // This may be substituted for an errorhandler if needed. + + + Returned + ~~~~~~~~ + + +=================================================+ + | Returned in Accumulator | + +===========+===========+=============+===========+ + | $00 - @ | $10 - p | $20 - SPC | $30 - 0 | + | $01 - a | $11 - q | $21 - | $31 - 1 | + | $02 - b | $12 - r | $22 - | $32 - 2 | + | $03 - c | $13 - s | $23 - | $33 - 3 | + | $04 - d | $14 - t | $24 - | $34 - 4 | + | $05 - e | $15 - u | $25 - | $35 - 5 | + | $06 - f | $16 - v | $26 - | $36 - 6 | + | $07 - g | $17 - w | $27 - | $37 - 7 | + | $08 - h | $18 - x | $28 - | $38 - 8 | + | $09 - i | $19 - y | $29 - | $39 - 9 | + | $0a - j | $1a - z | $2a - * | $3a - : | + | $0b - k | $1b - | $2b - + | $3b - ; | + | $0c - l | $1c - £ | $2c - , | $3c - | + | $0d - m | $1d - | $2d - - | $3d - = | + | $0e - n | $1e - ^ | $2e - . | $3e - | + | $0f - o | $1f - <- | $2f - / | $3f - | + +-----------+-----------+-------------+-----------+ + + +================================================================================ + | Return in X-Register | + +=========+=========+=========+=========+=========+=========+=========+=========+ + | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 | + +---------+---------+---------+---------+---------+---------+---------+---------+ + | CRSR UD | F5 | F3 | F1 | F7 | CRSR RL | RETURN |INST/DEL | + +---------+---------+---------+---------+---------+---------+---------+---------+ + + +================================================================================ + | Return in Y-Register | + +=========+=========+=========+=========+=========+=========+=========+=========+ + | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 | + +---------+---------+---------+---------+---------+---------+---------+---------+ + |RUN STOP | L-SHIFT | C= | R-SHIFT |CLR/HOME | CTRL | | | + +---------+---------+---------+---------+---------+---------+---------+---------+ + + CARRY: + - Set = Error Condition (Check A for code): + A = #$01 => No keyboard activity is detected. + A = #$02 => Control Port #1 Activity is detected. + A = #$03 => Key Shadowing / Ghosting is detected. + A = #$04 => 2 or 3 new keys is detected within one scan + A = #$05 => Awaiting "No Activity" state + - Clear = Valid input + A = #$ff => No new Alphanumeric Keys detected (some key(s) being held down AND/OR some Non-Alphanumeric key is causing valid return). + A <> #$ff => New Alphanumeric Key returned. Non-Alphanumeric keys may also be returned in X or Y Register + + Issues/ToDo: + ~~~~~~~~~~~~ + - None + + + Improvements: + ~~~~~~~~~~~~~ + - Replace the subroutine with a pseudocommand and account for speedcode parameter (Memory vs. Cycles). + - Shorten the routine / Optimize if possible. + + + History: + ~~~~~~~~ + V2.5 - New test tool. + Added return of error codes. + Fixed a bug causing Buffer Overflow. + Fixed a bug in Non Alphanumerical Flags from 2.0. + V2.1 - Shortened the source by adding .for loops & Updated the header and some comments. + Added "simultaneous keypress" check. + V2.0 - Added return of non-Alphanumeric keys into X & Y-Registers. + Small optimizations here and there. + V1.1 - Unrolled code to make it faster and optimized other parts of it. + Removed SHIFT LOCK scanning. + V1.0 - First Working Version along with test tool. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ + + .pc = * "Keyboard Scan Routine" + + // Operational Variables + .var MaxKeyRollover = 3 + + +start: + jmp Main + +init: + lda #$ff + sta MemMap.KEYB_SPACE.BufferOld + sta MemMap.KEYB_SPACE.Buffer + sta MemMap.KEYB_SPACE.Buffer+1 + sta MemMap.KEYB_SPACE.Buffer+2 + sta MemMap.KEYB_SPACE.Buffer+3 + sta MemMap.KEYB_SPACE.BufferQuantity + lda #$00 + sta MemMap.KEYB_SPACE.SimultaneousAlphanumericKeysFlag + rts + + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Routine for Scanning a Matrix Row + +KeyInRow: + asl + bcs.r *+5 + jsr KeyFound + .for (var i = 0 ; i < 7 ; i++) { + inx + asl + bcs.r *+5 + jsr KeyFound + } + rts + + + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Routine for handling: Key Found + +KeyFound: + stx MemMap.KEYB_SPACE.TempZP + dec MemMap.KEYB_SPACE.KeyQuantity + bmi.r OverFlow + ldy KeyTable,x + ldx MemMap.KEYB_SPACE.KeyQuantity + sty MemMap.KEYB_SPACE.BufferNew,x + ldx MemMap.KEYB_SPACE.TempZP + rts + + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Routine for handling: Overflow + +OverFlow: + pla // Dirty hack to handle 2 layers of JSR + pla + pla + pla + // Don't manipulate last legal buffer as the routine will fix itself once it gets valid input again. + lda #$03 + sec + rts + + + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Exit Routine for: No Activity + +NoActivityDetected: + // Exit With A = #$01, Carry Set & Reset MemMap.KEYB_SPACE.BufferOld. + lda #$00 + sta MemMap.KEYB_SPACE.SimultaneousAlphanumericKeysFlag // Clear the too many keys flag once a "no activity" state is detected. + stx MemMap.KEYB_SPACE.BufferOld + stx MemMap.KEYB_SPACE.BufferOld+1 + stx MemMap.KEYB_SPACE.BufferOld+2 + sec + lda #$01 + rts + + + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Exit Routine for Control Port Activity + +ControlPort: + // Exit with A = #$02, Carry Set. Keep MemMap.KEYB_SPACE.BufferOld to verify input after Control Port activity ceases + sec + lda #$02 + rts + + + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Configure Data Direction Registers +Main: + ldx #$ff + stx $dc02 // Port A - Output + ldy #$00 + sty $dc03 // Port B - Input + + + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Check for Port Activity + + sty $dc00 // Connect all Keyboard Rows + cpx $dc01 + beq.r NoActivityDetected + + lda MemMap.KEYB_SPACE.SimultaneousAlphanumericKeysFlag + beq.r !+ + // Waiting for all keys to be released before accepting new input. + lda #$05 + sec + rts +!: + + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Check for Control Port #1 Activity + + stx $dc00 // Disconnect all Keyboard Rows + cpx $dc01 // Only Control Port activity will be detected + bne ControlPort + + + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Scan Keyboard Matrix + + lda #%11111110 + sta $dc00 + ldy $dc01 + sty MemMap.KEYB_SPACE.ScanResult+7 + sec + .for (var i = 6 ; i > -1 ; i--) { + rol + sta $dc00 + ldy $dc01 + sty MemMap.KEYB_SPACE.ScanResult+i + } + + + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Check for Control Port #1 Activity (again) + + stx $dc00 // Disconnect all Keyboard Rows + cpx $dc01 // Only Control Port activity will be detected + bne.r ControlPort + + + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Initialize Buffer, Flags and Max Keys + + // Reset current read buffer + stx MemMap.KEYB_SPACE.BufferNew + stx MemMap.KEYB_SPACE.BufferNew+1 + stx MemMap.KEYB_SPACE.BufferNew+2 + + // Reset Non-AlphaNumeric Flag + inx + stx MemMap.KEYB_SPACE.NonAlphaFlagY + + // Set max keys allowed before ignoring result + lda #MaxKeyRollover + sta MemMap.KEYB_SPACE.KeyQuantity + + // Counter to check for simultaneous alphanumeric key-presses + lda #$fe + sta MemMap.KEYB_SPACE.SimultaneousKeys + + + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Check and flag Non Alphanumeric Keys + + lda MemMap.KEYB_SPACE.ScanResult+6 + eor #$ff + and #%10000000 // Left Shift + lsr + sta MemMap.KEYB_SPACE.NonAlphaFlagY + lda MemMap.KEYB_SPACE.ScanResult+0 + eor #$ff + and #%10100100 // RUN STOP - C= - CTRL + ora MemMap.KEYB_SPACE.NonAlphaFlagY + sta MemMap.KEYB_SPACE.NonAlphaFlagY + lda MemMap.KEYB_SPACE.ScanResult+1 + eor #$ff + and #%00011000 // Right SHIFT - CLR HOME + ora MemMap.KEYB_SPACE.NonAlphaFlagY + sta MemMap.KEYB_SPACE.NonAlphaFlagY + + lda MemMap.KEYB_SPACE.ScanResult+7 // The rest + eor #$ff + sta MemMap.KEYB_SPACE.NonAlphaFlagX + + + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Check for pressed key(s) + + lda MemMap.KEYB_SPACE.ScanResult+7 + cmp #$ff + beq *+5 + jsr KeyInRow + .for (var i = 6 ; i > -1 ; i--) { + ldx #[7-i]*8 + lda MemMap.KEYB_SPACE.ScanResult+i + beq *+5 + jsr KeyInRow + } + + + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Key Scan Completed + + // Put any new key (not in old scan) into buffer + ldx #MaxKeyRollover-1 + !: lda MemMap.KEYB_SPACE.BufferNew,x + cmp #$ff + beq Exist // Handle 'null' values + cmp MemMap.KEYB_SPACE.BufferOld + beq Exist + cmp MemMap.KEYB_SPACE.BufferOld+1 + beq Exist + cmp MemMap.KEYB_SPACE.BufferOld+2 + beq Exist + // New Key Detected + inc MemMap.KEYB_SPACE.BufferQuantity + ldy MemMap.KEYB_SPACE.BufferQuantity + sta MemMap.KEYB_SPACE.Buffer,y + // Keep track of how many new Alphanumeric keys are detected + inc MemMap.KEYB_SPACE.SimultaneousKeys + beq TooManyNewKeys + Exist: + dex + bpl !- + + // Anything in Buffer? + ldy MemMap.KEYB_SPACE.BufferQuantity + bmi BufferEmpty + // Yes: Then return it and tidy up the buffer + dec MemMap.KEYB_SPACE.BufferQuantity + lda MemMap.KEYB_SPACE.Buffer + ldx MemMap.KEYB_SPACE.Buffer+1 + stx MemMap.KEYB_SPACE.Buffer + ldx MemMap.KEYB_SPACE.Buffer+2 + stx MemMap.KEYB_SPACE.Buffer+1 + jmp Return + +BufferEmpty: // No new Alphanumeric keys to handle. + lda #$ff + +Return: // A is preset + clc + // Copy MemMap.KEYB_SPACE.BufferNew to MemMap.KEYB_SPACE.BufferOld + ldx MemMap.KEYB_SPACE.BufferNew + stx MemMap.KEYB_SPACE.BufferOld + ldx MemMap.KEYB_SPACE.BufferNew+1 + stx MemMap.KEYB_SPACE.BufferOld+1 + ldx MemMap.KEYB_SPACE.BufferNew+2 + stx MemMap.KEYB_SPACE.BufferOld+2 + // Handle Non Alphanumeric Keys + ldx MemMap.KEYB_SPACE.NonAlphaFlagX + ldy MemMap.KEYB_SPACE.NonAlphaFlagY + rts + +TooManyNewKeys: + sec + lda #$ff + sta MemMap.KEYB_SPACE.BufferQuantity + sta MemMap.KEYB_SPACE.SimultaneousAlphanumericKeysFlag + lda #$04 + rts + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +KeyTable: + .byte $ff, $ff, $ff, $ff, $ff, $ff, $ff, $ff // CRSR DOWN, F5, F3, F1, F7, CRSR RIGHT, RETURN, INST DEL + .byte $ff, $05, $13, $1a, $34, $01, $17, $33 // LEFT SHIFT, "E", "S", "Z", "4", "A", "W", "3" + .byte $18, $14, $06, $03, $36, $04, $12, $35 // "X", "T", "F", "C", "6", "D", "R", "5" + .byte $16, $15, $08, $02, $38, $07, $19, $37 // "V", "U", "H", "B", "8", "G", "Y", "7" + .byte $0e, $0f, $0b, $0d, $30, $0a, $09, $39 // "N", "O" (Oscar), "K", "M", "0" (Zero), "J", "I", "9" + .byte $2c, $00, $3a, $2e, $2d, $0c, $10, $2b // ",", "@", ":", ".", "-", "L", "P", "+" + .byte $2f, $1e, $3d, $ff, $ff, $3b, $2a, $1c // "/", "^", "=", RIGHT SHIFT, HOME, ";", "*", "£" + .byte $ff, $11, $ff, $20, $32, $ff, $1f, $31 // RUN STOP, "Q", "C=" (CMD), " " (SPC), "2", "CTRL", "<-", "1" diff --git a/keyb2.asm b/keyb2.asm new file mode 100644 index 0000000..4f14e4a --- /dev/null +++ b/keyb2.asm @@ -0,0 +1,237 @@ +// Advanced Version of Keyb Input routine +#importonce +.filenamespace Keyboard2 +#import "mem_map.asm" + +KeyMapVec: + .word KeyMap1, KeyMap2, KeyMap3, KeyMap4 + +// Unshifted +KeyMap1: + .byte $14, $0D, $1D, $88, $85, $86, $87, $11 + .byte $33, $57, $41, $34, $5A, $53, $45, $01 + .byte $35, $52, $44, $36, $43, $46, $54, $58 + .byte $37, $59, $47, $38, $42, $48, $55, $56 + .byte $39, $49, $4A, $30, $4D, $4B, $4F, $4E + .byte $2B, $50, $4C, $2D, $2E, $3A, $40, $2C + .byte $5C, $2A, $3B, $13, $01, $3D, $5E, $2F + .byte $31, $5F, $04, $32, $20, $02, $51, $03 + .byte $FF + +// Shifted +KeyMap2: + .byte $94, $8D, $9D, $8C, $89, $8A, $8B, $91 + .byte $23, $D7, $C1, $24, $DA, $D3, $C5, $01 + .byte $25, $D2, $C4, $26, $C3, $C6, $D4, $D8 + .byte $27, $D9, $C7, $28, $C2, $C8, $D5, $D6 + .byte $29, $C9, $CA, $30, $CD, $CB, $CF, $CE + .byte $DB, $D0, $CC, $DD, $3E, $5B, $BA, $3C + .byte $A9, $C0, $5D, $9e, $01, $3D, $DE, $3F + .byte $21, $5F, $04, $22, $A0, $02, $D1, $83 + .byte $FF + +// Commodore +KeyMap3: + .byte $94, $8D, $9D, $8C, $89, $8A, $8B, $91 + .byte $96, $B3, $B0, $97, $AD, $AE, $B1, $01 + .byte $98, $B2, $AC, $99, $BC, $BB, $A3, $BD + .byte $9A, $B7, $A5, $9B, $BF, $B4, $B8, $BE + .byte $29, $A2, $B5, $30, $A7, $A1, $B9, $AA + .byte $A6, $AF, $B6, $DC, $3E, $5B, $A4, $3C + .byte $A8, $DF, $5D, $93, $01, $3D, $DE, $3F + .byte $81, $5F, $04, $95, $A0, $02, $AB, $83 + .byte $FF + +// Control +KeyMap4: + .byte $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF + .byte $1C, $17, $01, $9F, $1A, $13, $05, $FF + .byte $9C, $12, $04, $1E, $03, $06, $14, $18 + .byte $1F, $19, $07, $9E, $02, $08, $15, $16 + .byte $12, $09, $0A, $92, $0D, $0B, $0F, $0E + .byte $FF, $10, $0C, $FF, $FF, $1B, $00, $FF + .byte $1C, $FF, $1D, $FF, $FF, $1F, $1E, $FF + .byte $90, $06, $FF, $05, $FF, $FF, $11, $FF + .byte $FF + +.const CIA1_KeybWrite = $DC00 +.const CIA1_KeybRead = $DC01 + +.const cSYS_DelayValue = 32 +.const cKeybW_Row1 = $FE + +init: + lda #64 + sta MemMap.KEYB2_SPACE.SYS_Lstx + sta MemMap.KEYB2_SPACE.SYS_Sfdx + + lda #cSYS_DelayValue + sta MemMap.KEYB2_SPACE.SYS_Delay + + lda #6 + sta MemMap.KEYB2_SPACE.SYS_Kount + + lda #0 + sta MemMap.KEYB2_SPACE.SYS_Shflag + sta MemMap.KEYB2_SPACE.SYS_Lstshf + + sta MemMap.KEYB2_SPACE.SYS_Ndx + + lda #10 + sta MemMap.KEYB2_SPACE.SYS_Xmax + + rts + +ReadKeyb: + lda #KeyMap1 + sta @SMC_Vec + 2 + + // Clear Shift Flag + lda #$40 + sta MemMap.KEYB2_SPACE.SYS_Sfdx + + lda #0 + sta MemMap.KEYB2_SPACE.SYS_Shflag + + sta CIA1_KeybWrite + ldx CIA1_KeybRead + cpx #$FF + beq @Cleanup + + ldy #$00 + + lda #7 + sta MemMap.KEYB2_SPACE.KeyR + + lda #cKeybW_Row1 + sta @SMC_Row + 1 +@SMC_Row: lda #0 + + sta CIA1_KeybWrite + +@Loop_Debounce: + lda CIA1_KeybRead + cmp CIA1_KeybRead + bne @Loop_Debounce + + ldx #7 +@Loop_Col: lsr + bcs @NextKey + sta @SMC_A + 1 + +@SMC_Vec: lda $FFFF,Y + + // If <4 then is Stop or a Shift Key + cmp #$05 + bcs @NotShift // Not Shift + + cmp #$03 + beq @NotShift // Stop Key + + // Accumulate shift key types (SHIFT=1, COMM=2, CTRL=4) + ora MemMap.KEYB2_SPACE.SYS_Shflag + sta MemMap.KEYB2_SPACE.SYS_Shflag + bpl @SMC_A + +@NotShift: sty MemMap.KEYB2_SPACE.SYS_Sfdx + +@SMC_A: lda #0 + +@NextKey: iny + dex + bpl @Loop_Col + + sec + rol @SMC_Row + 1 + dec MemMap.KEYB2_SPACE.KeyR + bpl @SMC_Row + + jmp @ProcKeyImg + +// Handles the key repeat +@Process: ldy MemMap.KEYB2_SPACE.SYS_Sfdx +@SMC_Key: lda $FFFF,Y + tax + cpy MemMap.KEYB_SPACE.KeyQuantity.SYS_Lstx + beq @SameKey + + ldy #cSYS_DelayValue + sty MemMap.KEYB2_SPACE.SYS_Delay // Repeat delay counter + bne @Cleanup + +@SameKey: and #$7F + ldy MemMap.KEYB2_SPACE.SYS_Delay + beq @EndDelay + dec MemMap.KEYB2_SPACE.SYS_Delay + bne @Exit + +@EndDelay: dec MemMap.KEYB2_SPACE.SYS_Kount + bne @Exit + + ldy #$04 + sty MemMap.KEYB2_SPACE.SYS_Kount + ldy MemMap.KEYB2_SPACE.SYS_Ndx + dey + bpl @Exit + +// Updates the previous key and shift storage +@Cleanup: ldy MemMap.KEYB2_SPACE.SYS_Sfdx + sty MemMap.KEYB_SPACE.KeyQuantity.SYS_Lstx + ldy MemMap.KEYB2_SPACE.SYS_Shflag + sty MemMap.KEYB2_SPACE.SYS_Lstshf + + cpx #$FF + beq @Exit + txa + ldx MemMap.KEYB2_SPACE.SYS_Ndx + cpx MemMap.KEYB2_SPACE.SYS_Xmax + bcs @Exit + + sta MemMap.KEYB2_SPACE.SYS_Keyd,X + inx + stx MemMap.KEYB2_SPACE.SYS_Ndx + +@Exit: lda #$7F + sta CIA1_KeybWrite + rts + +@ProcKeyImg: + lda MemMap.KEYB2_SPACE.SYS_Shflag + cmp #$03 // C= + SHIFT + bne @SetDecodeTable + cmp MemMap.KEYB2_SPACE.SYS_Lstshf + beq @Exit + +@SetDecodeTable: + asl + cmp #8 // CONTROL + bcc @Cont + lda #$06 +@Cont: tax + lda KeyMapVec,X + sta @SMC_Key + 1 + lda KeyMapVec + 1,X + sta @SMC_Key + 2 + jmp @Process + +// -------------------------- +GetKey: lda MemMap.KEYB2_SPACE.SYS_Ndx + bne @IsKey + +@NoKey: lda #255 // Null + sec + rts + +@IsKey: ldy MemMap.KEYB2_SPACE.SYS_Keyd + ldx #0 +@Loop: lda MemMap.KEYB2_SPACE.SYS_Keyd + 1,X + sta MemMap.KEYB2_SPACE.SYS_Keyd,X + inx + cpx MemMap.KEYB2_SPACE.SYS_Ndx + bne @Loop + dec MemMap.KEYB2_SPACE.SYS_Ndx + tya + clc + rts \ No newline at end of file diff --git a/main.asm b/main.asm index c8d2810..ca2e801 100644 --- a/main.asm +++ b/main.asm @@ -4,69 +4,80 @@ // Constants .namespace constants { - .label MainColor = $05 - .label BorderColor = $03 - .label ScreenMem = $0400 + .label MAIN_COLOR = $05 + .label BORDER_COLOR = $03 + .label SCREEN_MEM = $0400 } .word coldstart // coldstart vector -.word start // coldstart vector +.word start // start vector +.byte $C3,$C2,$CD,'8','0' //..CBM80.. -.byte $C3 -.byte $C2 -.byte $CD -.byte $38 -.byte $30 +#import "screen.asm" +#import "keyb.asm" +#import "hex.asm" + + +.pc = * "Kernel Start" coldstart: + ldx #$FF sei + txs + cld stx $d016 jsr $fda3 // Prepare IRQ jsr $fd50 // Init memory. Rewrite this routine to speed up boot process. jsr $fd15 // Init I/O jsr $ff5b // Init video cli -/* - jsr $E453 - jsr $E3BF - jsr $E422 - ldx #$FB -*/ - //tsx - start: jsr initApp; print(testString) - .for(var i=0; i<23; i++) { - print(testString2) - } -deadLoop: jmp deadLoop + +getKeyb: + jsr Keyboard.start + bcs NoValidInput + stx MemMap.KEYB_SPACE.TempX + sty MemMap.KEYB_SPACE.TempY + cmp #$ff + // Check A for Alphanumeric keys + beq NoNewAphanumericKey + jsr printKey + jmp getKeyb + +printKey: + cPrint() + rts + + +NoNewAphanumericKey: + // Check X & Y for Non-Alphanumeric Keys + ldx MemMap.KEYB_SPACE.TempX + ldy MemMap.KEYB_SPACE.TempY +NoValidInput: // This may be substituted for an errorhandler if needed. + jmp getKeyb initApp: { ClearColorRam($00) - ClearScreen(constants.ScreenMem, ' ') - SetBorderColor(constants.MainColor) - SetBackgroundColor(constants.BorderColor) + ClearScreen(constants.SCREEN_MEM, ' ') + SetBorderColor(constants.MAIN_COLOR) + SetBackgroundColor(constants.BORDER_COLOR) jsr Screen.init + jsr Keyboard.init rts } -#import "screen.asm" - +.pc = * "Kernel Data" .encoding "screencode_mixed" testString: - .text "fantastic job 1.0 by =stid=" - .byte 13 - .byte 13 + .text "=stid= os - v 0.1.1a" + .byte $ff .byte 0 -testString2: - .text ".======================================." - .byte 13 - .byte 0 * = $9FFF "EpromFiller" .byte 0 diff --git a/math.asm b/math.asm index 7e04493..b7250d8 100644 --- a/math.asm +++ b/math.asm @@ -3,6 +3,8 @@ #import "mem_map.asm" +.pc = * "Math Routines" + multiply: { stx MemMap.MATH_SPACE.multiTmpX pha diff --git a/mem_map.asm b/mem_map.asm index 55bd12e..1be03db 100644 --- a/mem_map.asm +++ b/mem_map.asm @@ -1,20 +1,53 @@ .filenamespace MemMap #importonce -.const base = $10 +.const ZPAGE_BASE = $2 .namespace SCREEN_SPACE { - .label TempVideoPointer = base // W - .label TempStringPointer = base+2 // W - .label CursorCol = base+4 - .label CursorRow = base+5 - .label tempY = base+6 + .label TempVideoPointer = ZPAGE_BASE // 2 bytes + .label TempStringPointer = ZPAGE_BASE+2 // 2 bytes + .label CursorCol = ZPAGE_BASE+4 // 1 byte + .label CursorRow = ZPAGE_BASE+5 // 1 byte + .label tempY = ZPAGE_BASE+6 // 1 byte + .label tempX = ZPAGE_BASE+7 // 1 byte } .namespace MATH_SPACE { - .label factor1 = base+7 - .label factor2 = base+8 - .label multiTmpX = base+9 - .label result = base+10 // W + .label factor1 = ZPAGE_BASE+8 // 1 byte + .label factor2 = ZPAGE_BASE+9 // 1 byte + .label multiTmpX = ZPAGE_BASE+10 // 1 byte + .label result = ZPAGE_BASE+11 // 2 bytes +} + +.namespace KEYB_SPACE { + .label ScanResult = ZPAGE_BASE+13 // 8 bytes + .label BufferNew = ZPAGE_BASE+21 // 3 bytes + .label KeyQuantity = ZPAGE_BASE+24 // 1 byte + .label NonAlphaFlagX = ZPAGE_BASE+25 // 1 byte + .label NonAlphaFlagY = ZPAGE_BASE+26 // 1 byte + .label TempZP = ZPAGE_BASE+27 // 1 byte + .label SimultaneousKeys = ZPAGE_BASE+28 // 1 byte + + // TODO: Need $FF init + .label BufferOld = ZPAGE_BASE+28 // 1 byte + .label Buffer = ZPAGE_BASE+29 // 4 byte + .label BufferQuantity = ZPAGE_BASE+33 // 1 byte + .label SimultaneousAlphanumericKeysFlag = ZPAGE_BASE+34 // 1 byte + + .label TempX = ZPAGE_BASE+35 // 1 byte + .label TempY = ZPAGE_BASE+36 // 1 byte +} + +.namespace KEYB2_SPACE { + .label KeyR = ZPAGE_BASE+37 + .label SYS_Keyd = ZPAGE_BASE+38 // 10 bytes + .label SYS_Ndx = ZPAGE_BASE+48 // 10 bytes + .label SYS_Xmax = ZPAGE_BASE+49 // 1 bytes + .label SYS_Shflag = ZPAGE_BASE+50 // 1 bytes + .label SYS_Sfdx = ZPAGE_BASE+51 // 1 bytes + .label SYS_Lstx = ZPAGE_BASE+52 // 1 bytes + .label SYS_Delay = ZPAGE_BASE+53 // 1 bytes + .label SYS_Kount = ZPAGE_BASE+54 // 1 bytes + .label SYS_Lstshf = ZPAGE_BASE+55 // 1 bytes } \ No newline at end of file diff --git a/screen.asm b/screen.asm index 3103284..16fc4ef 100644 --- a/screen.asm +++ b/screen.asm @@ -6,12 +6,18 @@ // MACROS // ----------------------- +.pc = * "Screen Routines" + .macro print(stringAddr) { lda #stringAddr // High byte jsr Screen.print } +.macro cPrint() { + jsr Screen.printChar +} + .macro ClearScreen(screen, clearByte) { lda #clearByte ldx #0 @@ -21,7 +27,7 @@ sta screen + $200, x sta screen + $300, x inx - bne !loop- + bne.r !loop- } .macro ClearColorRam(clearByte) { @@ -33,7 +39,7 @@ sta $D800 + $200, x sta $D800 + $300, x inx - bne !loop- + bne.r !loop- } .macro SetBorderColor(color) { @@ -94,9 +100,9 @@ init: { } printChar: { - + stx MemMap.SCREEN_SPACE.tempX // New Line - cmp #13 + cmp #$ff bne.r !+ jsr screenNewLine iny @@ -139,11 +145,12 @@ printChar: { inc MemMap.SCREEN_SPACE.CursorCol lda MemMap.SCREEN_SPACE.CursorCol cmp #constants.COLUMN_NUM+1 - bcc exita + bcc.r exita // CursorCol > COLUMN_NUM ? new line jsr screenNewLine exita: + ldx MemMap.SCREEN_SPACE.tempX rts }