itty-bitty-vtty/vt100.key.S
2024-09-12 16:04:21 -04:00

466 lines
5.5 KiB
ArmAsm

lst off
rel
xc
xc
tbx on
use vt.equ
use apple2gs.equ
use debug
mx %11
* ext dispatch
ext write_modem
kmShift equ %0000_0001
kmControl equ %0000_0010
kmCapsLock equ %0000_0100
kmRepeat equ %0000_1000
kmKeypad equ %0001_0000
kmUpdateMod equ %0010_0000
kmOption equ %0100_0000
kmCommand equ %1000_0000
*
* The vt100 has a delete key and a backspace key.
* delete sends 0x7f. backspace sends 0x08.
* stty is general set so 0x7f is the erase character.
* termcaps generally claim 0x08 is the backspace character.
*
* emacs, by default, thinks 0x08 ( ^H ) means you want help.
*
* so, backspace will send 0x7f. control-H or command-backspace
* will send 0x08.
*
* TODO - keys
* command-L -> local/online mode?
* command-Q -> quit
* command-K -> clear screen?
* command-R -> reset settings
*
dispatch
jmp write_modem
keypress ent
debug keypress
lda KBD
bmi :key
:rts rts
:key
and #$7f
sta key
lda KEYMOD
sta mod
sta KEYSTROBE
* if DECARM is clear, skip repeat characters.
*
* a REAL vt100 will never auto-repeat ESC, TAB, RETURN, or if Control is also pressed.
*
bit DECARM
bmi :arm
bit #kmRepeat
bne :rts
:arm
bit #kmOption!kmCommand
bne command
bit #kmKeypad
jne keypad
bit #kmControl
bne :ctrl
lda key
cmp #' '
bcs :notctrl
* control char w/o control bit.
* ie, arrow key / return / tab
* no cmp / sbc needed
asl
tax
lsr ; restore
jmp (special,x)
:ctrl
lda key
and #$1f ; control-space should generate 0, not $20.
bra :send
:notctrl
* cmp #$7f ; delete - special case
* bne :send
* lda #$08
:send jmp dispatch
command ; or option
* apple-return -> linefeed
* apple-backspace -> delete
lda key
cmp #$7f
beq :bs
cmp #$0d
beq :lf
cmp #'a'
bcc :0
cmp #'z'+1
bcs :0
and #$df ; ~ $20
:0
cmp #:MIN
blt :rts
cmp #:MAX+1
bcs :rts
sec
sbc #:MIN
asl
tax
jmp (:table,x)
:rts rts
:bs lda #$08
jmp dispatch ;
:lf lda #$0a
jmp dispatch
ext enable_modem,disable_modem
:local
bit LOCAL
bmi :online
lda #$80
sta LOCAL
jmp disable_modem
:online
stz LOCAL
jmp enable_modem
:quit
ext quit
jmp quit
rts
:reset
* TODO
rts
:clear
* TODO
rts
:MIN equ 49
:MAX equ 82
:table
dw pf1 ; 1
dw pf2 ; 2
dw pf3 ; 3
dw pf4 ; 4
dw :rts ; 5
dw :rts ; 6
dw :rts ; 7
dw :rts ; 8
dw :rts ; 9
dw :rts ; :
dw :rts ; ;
dw :rts ; <
dw :rts ; =
dw :rts ; >
dw :rts ; ?
dw :rts ; @
dw :rts ; A
dw :rts ; B
dw :rts ; C
dw :rts ; D
dw :rts ; E
dw :rts ; F
dw :rts ; G
dw :rts ; H
dw :rts ; I
dw :rts ; J
dw :clear ; K
dw :local ; L
dw :rts ; M
dw :rts ; N
dw :rts ; O
dw :rts ; P
dw :quit ; Q
dw :reset ; R
keypad
lda key
cmp #:MIN
blt :rts
cmp #:MAX+1
bcs :other
sec
sbc #:MIN
asl
tax
jmp (:table,x)
:other
* keypad delete key ($75 aka 'u') will send as backspace ($08)
*
cmp #'u'
bne :rts
lda #$08
jmp dispatch
:rts rts
:MIN equ 13
:MAX equ 61
:table
dw enter ; ^M Enter -> \r, ESC ? M
dw :rts ; ^N
dw :rts ; ^O
dw :rts ; ^P
dw :rts ; ^Q
dw :rts ; ^R
dw :rts ; ^S
dw :rts ; ^T
dw :rts ; ^U
dw :rts ; ^V
dw :rts ; ^W
dw :rts ; ^X
dw :rts ; ^Y
dw :rts ; ^Z
dw pf1 ; ^[ PF1 -> ESC P
dw :rts ; ^\
dw :rts ; ^]
dw :rts ; ^^
dw :rts ; ^_
dw :rts ;
dw :rts ; !
dw :rts ; "
dw :rts ; #
dw :rts ; $
dw :rts ; %
dw :rts ; &
dw :rts ; '
dw :rts ; (
dw :rts ; )
dw pf4 ; *
dw comma ; +
dw :rts ; ,
dw dash ; -
dw dot ; .
dw pf3 ; / PF3 -> ESC R
dw digit ; 0
dw digit ; 1
dw digit ; 2
dw digit ; 3
dw digit ; 4
dw digit ; 5
dw digit ; 6
dw digit ; 7
dw digit ; 8
dw digit ; 9
dw :rts ; :
dw :rts ; ;
dw :rts ; <
dw pf2 ; = PF2 -> ESC Q
enter
bit DECKPAM
bmi :alt
brl cr
:alt
jmp ?O
comma
* iigs keyboard is a +
lda #','
sta key
bit DECKPAM
bmi :alt
jmp dispatch
:alt
jmp ?O
dot
lda key
bit DECKPAM
bmi :alt
jmp dispatch
:alt
jmp ?O
dash
lda key
bit DECKPAM
bmi :alt
jmp dispatch
:alt
jmp ?O
digit
lda key
bit DECKPAM
bmi :alt
jmp dispatch
:alt
* jmp ?O
* drop through
?O
* send ESC ? key if vt52, ESC O key if vt100
lda #ESC
jsr dispatch
bit DECANM
bpl :vt52
lda #'O'
jsr dispatch
lda key
ora #$40
jmp dispatch
:vt52
lda #'?'
jsr dispatch
lda key
ora #$40
jmp dispatch
pf1
lda #'P'
sta key
bra pf
pf2
lda #'Q'
sta key
bra pf
pf3
lda #'R'
sta key
bra pf
pf4
lda #'S'
sta key
pf
lda #ESC
jsr dispatch
bit DECANM
bpl :vt52
lda #'O'
jsr dispatch
:vt52 lda key
jmp dispatch
special
dw dispatch ; ^@
dw dispatch ; ^A
dw dispatch ; ^B
dw dispatch ; ^C
dw dispatch ; ^D
dw dispatch ; ^E
dw dispatch ; ^F
dw dispatch ; ^G
dw left ; ^H
dw dispatch ; ^I - tab
dw down ; ^J
dw up ; ^K
dw dispatch ; ^L
dw cr ; ^M
dw dispatch ; ^N
dw dispatch ; ^O
dw dispatch ; ^P
dw dispatch ; ^Q
dw dispatch ; ^R
dw dispatch ; ^S
dw dispatch ; ^T
dw right ; ^U
dw dispatch ; ^V
dw dispatch ; ^W
dw dispatch ; ^X
dw dispatch ; ^Y
dw dispatch ; ^Z
dw dispatch ; ^[
dw dispatch ; ^\
dw dispatch ; ^]
dw dispatch ; ^^
dw dispatch ; ^_
cr
* Return sends CR or CR + LF (LNM)
bit LNM
bmi :crlf
lda #$0d
jmp dispatch
:crlf
lda #$0d
jsr dispatch
lda #$0a
jmp dispatch
left
lda #'D'
bra arrow
right
lda #'C'
bra arrow
up
lda #'A'
bra arrow
down
lda #'B'
* drop through
arrow
* actual character generated depends on DECANM and DECCKM
sta key
lda #ESC
jsr dispatch
bit DECANM
bpl :vt52
bit DECCKM
bmi :cursor
lda #'['
jsr dispatch
lda key
jmp dispatch
:cursor
lda #'O'
jsr dispatch
* drop through.
:vt52
lda key
jmp dispatch
sav vt100.key.L