woz64/devices/keyboard.asm

370 lines
10 KiB
NASM
Raw Normal View History

2019-11-10 03:10:52 +00:00
#importonce
2020-01-19 06:48:59 +00:00
#import "../core/module.asm"
2020-01-12 20:57:01 +00:00
#import "../libs/memory.asm"
2020-01-12 08:10:01 +00:00
.filenamespace Keyboard
2020-01-13 00:52:10 +00:00
// ========================================================
// ////// CONSTANTS ///////////////////////////////////////
// ========================================================
2019-11-16 22:09:22 +00:00
.const CIA1_KeybWrite = $DC00
.const CIA1_KeybRead = $DC01
.const cSYS_DelayValue = 32
.const cKeybW_Row1 = $FE
2020-01-19 06:48:59 +00:00
.const RASTER_LINE = $d012
2020-01-20 07:32:37 +00:00
* = * "Device: Keyboard"
2020-01-12 08:10:01 +00:00
2020-01-13 00:52:10 +00:00
// ========================================================
// ////// METHODS ROM /////////////////////////////////////
// ========================================================
2020-01-12 08:10:01 +00:00
2020-01-13 00:52:10 +00:00
// --------------------------------------------------------
// init -
// Module Init.
// --------------------------------------------------------
2019-11-18 03:28:54 +00:00
init: {
2020-01-13 01:24:10 +00:00
lda #64
sta MemMap.KEYBOARD.SYS_Lstx
sta MemMap.KEYBOARD.SYS_Sfdx
2019-11-16 22:09:22 +00:00
2020-01-13 01:24:10 +00:00
lda #cSYS_DelayValue
sta MemMap.KEYBOARD.SYS_Delay
2019-11-16 22:09:22 +00:00
2020-01-13 01:24:10 +00:00
lda #6
sta MemMap.KEYBOARD.SYS_Kount
2019-11-16 22:09:22 +00:00
2020-01-13 01:24:10 +00:00
lda #0
sta MemMap.KEYBOARD.SYS_Shflag
sta MemMap.KEYBOARD.SYS_Lstshf
2019-11-16 22:09:22 +00:00
2020-01-13 01:24:10 +00:00
sta MemMap.KEYBOARD.SYS_Ndx
2019-11-16 22:09:22 +00:00
2020-01-13 01:24:10 +00:00
lda #10
sta MemMap.KEYBOARD.SYS_Xmax
2019-11-16 22:09:22 +00:00
2020-01-13 00:52:10 +00:00
// Clone self altering Methods to RAM
2020-01-19 06:48:59 +00:00
MemoryClone(cloneStart, cloneEnd, MemMap.KEYBOARD.keybRamCode)
rts
}
// --------------------------------------------------------
// waitForKey -
// Loop until a new key is available.
//
// Result:
// A = Pressed key code
// --------------------------------------------------------
waitForKey: {
loop:
lda #$FF
raster:
cmp RASTER_LINE // Raster done?
bne raster
jsr Keyboard.ReadKeyb
jsr Keyboard.GetKey
bcs loop
2019-11-16 22:09:22 +00:00
rts
2019-11-18 03:28:54 +00:00
}
2019-11-10 03:10:52 +00:00
2020-01-13 00:52:10 +00:00
// --------------------------------------------------------
// toDebug -
// Print debug info.
// --------------------------------------------------------
2020-01-12 08:10:01 +00:00
toDebug: {
2020-01-13 01:24:10 +00:00
ModuleToDebug(module_type, module_name, version)
rts
2020-01-12 08:10:01 +00:00
}
2020-01-13 00:52:10 +00:00
// ========================================================
2020-01-19 06:48:59 +00:00
// ////// KEYMAPPING ROM //////////////////////////////////
2020-01-13 00:52:10 +00:00
// ========================================================
2019-11-10 03:10:52 +00:00
KeyMapVec:
2020-01-13 01:24:10 +00:00
.word KeyMap1, KeyMap2, KeyMap3, KeyMap4
2019-11-10 03:10:52 +00:00
// 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
2020-01-12 08:10:01 +00:00
2020-01-13 00:52:10 +00:00
// ========================================================
// ////// METHODS RAM /////////////////////////////////////
// ========================================================
2020-01-12 08:10:01 +00:00
* = * "Keyboard Ram"
2019-11-10 03:10:52 +00:00
2019-11-16 22:09:22 +00:00
cloneStart:
2020-01-13 00:52:10 +00:00
// Code between cloneStart & cloneEnd is cloned in RAM
// at Init time. The logic alter the code itself for
// performance and so can't be executed directly in ROM.
// See .pseudopc $1000 directive below.
// --------------------------------------------------------
// ReadKeyb -
// Read Keyboard input - if any- should be called in a loop
// getKey should be used after to chek if and what key was
// pressed.
//
// Example:
// loop:
// jsr Keyboard.ReadKeyb
// jsr Keyboard.GetKey
// bcs loop
// // Key here is in A
// --------------------------------------------------------
2020-01-19 06:48:59 +00:00
.pseudopc MemMap.KEYBOARD.keybRamCode {
2020-01-13 01:24:10 +00:00
ReadKeyb: {
lda #<KeyMap1
sta @SMC_Vec
lda #>KeyMap1
sta @SMC_Vec + 1
2019-11-10 03:10:52 +00:00
2019-11-16 22:09:22 +00:00
// Clear Shift Flag
2020-01-13 01:24:10 +00:00
lda #$40
sta MemMap.KEYBOARD.SYS_Sfdx
2019-11-10 03:10:52 +00:00
2020-01-13 01:24:10 +00:00
lda #0
sta MemMap.KEYBOARD.SYS_Shflag
2019-11-10 03:10:52 +00:00
2020-01-13 01:24:10 +00:00
sta CIA1_KeybWrite
ldx CIA1_KeybRead
cpx #$FF
beq @Cleanup
2019-11-10 03:10:52 +00:00
2020-01-13 01:24:10 +00:00
ldy #$00
2019-11-10 03:10:52 +00:00
2020-01-13 01:24:10 +00:00
lda #7
sta MemMap.KEYBOARD.KeyR
2019-11-10 03:10:52 +00:00
2020-01-13 01:24:10 +00:00
lda #cKeybW_Row1
sta @SMC_Row + 1
@SMC_Row:
lda #0
2019-11-10 03:10:52 +00:00
2020-01-13 01:24:10 +00:00
sta CIA1_KeybWrite
2019-11-10 03:10:52 +00:00
2020-01-13 01:24:10 +00:00
@Loop_Debounce:
lda CIA1_KeybRead
cmp CIA1_KeybRead
bne @Loop_Debounce
2019-11-10 03:10:52 +00:00
2020-01-13 01:24:10 +00:00
ldx #7
@Loop_Col:
lsr
bcs @NextKey
sta @SMC_A + 1
2019-11-10 03:10:52 +00:00
2020-01-13 01:24:10 +00:00
lda @SMC_Vec:$FFFF,Y
2019-11-10 03:10:52 +00:00
2019-11-16 22:09:22 +00:00
// If <4 then is Stop or a Shift Key
2020-01-13 01:24:10 +00:00
cmp #$05
bcs @NotShift // Not Shift
2019-11-10 03:10:52 +00:00
2020-01-13 01:24:10 +00:00
cmp #$03
beq @NotShift // Stop Key
2019-11-10 03:10:52 +00:00
2019-11-16 22:09:22 +00:00
// Accumulate shift key types (SHIFT=1, COMM=2, CTRL=4)
2020-01-13 01:24:10 +00:00
ora MemMap.KEYBOARD.SYS_Shflag
sta MemMap.KEYBOARD.SYS_Shflag
bpl @SMC_A
2019-11-10 03:10:52 +00:00
2020-01-13 01:24:10 +00:00
@NotShift:
sty MemMap.KEYBOARD.SYS_Sfdx
2019-11-10 03:10:52 +00:00
2020-01-13 01:24:10 +00:00
@SMC_A:
lda #0
2019-11-10 03:10:52 +00:00
2020-01-13 01:24:10 +00:00
@NextKey:
iny
2019-11-16 22:09:22 +00:00
dex
2020-01-13 01:24:10 +00:00
bpl @Loop_Col
2019-11-10 03:10:52 +00:00
2019-11-16 22:09:22 +00:00
sec
2020-01-13 01:24:10 +00:00
rol @SMC_Row + 1
dec MemMap.KEYBOARD.KeyR
bpl @SMC_Row
2019-11-10 03:10:52 +00:00
2020-01-13 01:24:10 +00:00
jmp @ProcKeyImg
2019-11-10 03:10:52 +00:00
// Handles the key repeat
2020-01-13 01:24:10 +00:00
@Process:
ldy MemMap.KEYBOARD.SYS_Sfdx
@SMC_Key:
lda $FFFF,Y
2019-11-16 22:09:22 +00:00
tax
2020-01-13 01:24:10 +00:00
cpy MemMap.KEYBOARD.SYS_Lstx
beq @SameKey
ldy #cSYS_DelayValue
sty MemMap.KEYBOARD.SYS_Delay // Repeat delay counter
bne @Cleanup
@SameKey:
and #$7F
ldy MemMap.KEYBOARD.SYS_Delay
beq @EndDelay
dec MemMap.KEYBOARD.SYS_Delay
bne @Exit
@EndDelay:
dec MemMap.KEYBOARD.SYS_Kount
bne @Exit
ldy #$04
sty MemMap.KEYBOARD.SYS_Kount
ldy MemMap.KEYBOARD.SYS_Ndx
2019-11-16 22:09:22 +00:00
dey
2020-01-13 01:24:10 +00:00
bpl @Exit
2019-11-10 03:10:52 +00:00
// Updates the previous key and shift storage
2020-01-13 01:24:10 +00:00
@Cleanup:
ldy MemMap.KEYBOARD.SYS_Sfdx
sty MemMap.KEYBOARD.SYS_Lstx
ldy MemMap.KEYBOARD.SYS_Shflag
sty MemMap.KEYBOARD.SYS_Lstshf
cpx #$FF
beq @Exit
2019-11-16 22:09:22 +00:00
txa
2020-01-13 01:24:10 +00:00
ldx MemMap.KEYBOARD.SYS_Ndx
cpx MemMap.KEYBOARD.SYS_Xmax
bcs @Exit
2019-11-16 22:09:22 +00:00
2020-01-13 01:24:10 +00:00
sta MemMap.KEYBOARD.SYS_Keyd,X
2019-11-16 22:09:22 +00:00
inx
2020-01-13 01:24:10 +00:00
stx MemMap.KEYBOARD.SYS_Ndx
2019-11-16 22:09:22 +00:00
2020-01-13 01:24:10 +00:00
@Exit:
lda #$7F
sta CIA1_KeybWrite
2019-11-16 22:09:22 +00:00
rts
2019-11-10 03:10:52 +00:00
2020-01-13 01:24:10 +00:00
@ProcKeyImg:
lda MemMap.KEYBOARD.SYS_Shflag
cmp #$03 // C= + SHIFT
bne @SetDecodeTable
cmp MemMap.KEYBOARD.SYS_Lstshf
beq @Exit
2019-11-10 03:10:52 +00:00
2020-01-13 01:24:10 +00:00
@SetDecodeTable:
2019-11-16 22:09:22 +00:00
asl
2020-01-13 01:24:10 +00:00
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
}
2019-11-10 03:10:52 +00:00
2020-01-13 00:52:10 +00:00
// --------------------------------------------------------
// GetKey -
// Get latest pressed key - if any. Should be used in
// conjuction with ReadKeyb.
//
// Result:
// A = Pressed key code or 0
// --------------------------------------------------------
2020-01-13 01:24:10 +00:00
GetKey: {
lda MemMap.KEYBOARD.SYS_Ndx
bne @IsKey
2019-11-16 22:09:22 +00:00
2020-01-13 01:24:10 +00:00
@NoKey:
lda #255 // Null
2019-11-16 22:09:22 +00:00
sec
rts
2020-01-13 01:24:10 +00:00
@IsKey:
ldy MemMap.KEYBOARD.SYS_Keyd
ldx #0
@Loop:
lda MemMap.KEYBOARD.SYS_Keyd + 1,X
sta MemMap.KEYBOARD.SYS_Keyd,X
2019-11-16 22:09:22 +00:00
inx
2020-01-13 01:24:10 +00:00
cpx MemMap.KEYBOARD.SYS_Ndx
bne @Loop
dec MemMap.KEYBOARD.SYS_Ndx
2019-11-16 22:09:22 +00:00
tya
clc
rts
2020-01-13 01:24:10 +00:00
}}
2019-11-18 03:28:54 +00:00
2020-01-12 08:10:01 +00:00
* = * "Keyboard Ram End"
2019-11-16 22:09:22 +00:00
cloneEnd:
2019-11-23 02:50:25 +00:00
2020-01-13 00:52:10 +00:00
// ========================================================
// ////// DATA ////////////////////////////////////////////
// ========================================================
2020-01-12 08:10:01 +00:00
2020-01-20 07:32:37 +00:00
* = * "Device: Keyboard Data"
module_type: .byte Module.TYPES.DEVICE
2020-01-13 01:24:10 +00:00
version: .byte 1, 1, 0
2020-01-13 00:52:10 +00:00
.encoding "screencode_mixed"
2020-01-12 08:10:01 +00:00
module_name:
2020-01-13 01:24:10 +00:00
.text "keyboard"
.byte 0
2020-01-13 00:52:10 +00:00
2020-01-20 07:38:20 +00:00
#import "../hardware/mem_map.asm"
2019-11-23 02:50:25 +00:00