more stuff

This commit is contained in:
Kelvin Sherlock 2021-09-19 18:49:29 -04:00
parent 6e0de284e0
commit 9c526bd762
8 changed files with 1121 additions and 28 deletions

View File

@ -1,4 +1,7 @@
cas se
st_vt52 equ 0
st_vt52_esc equ 2
st_vt52_dca equ 4
@ -69,6 +72,11 @@ cursor_state ds 2 ; on/off/disabled.
draw_inverse ds 2 ; flag to draw inverse
erase_char ds 2 ; clear character
* keypress data.
key ds 2
mod ds 2
do *>256
err "too big"
fin

View File

@ -11,7 +11,8 @@
mx %11
ext update_cursor,reset_tab,reset_all_tabs
ext reset_tab,reset_all_tabs
ext recalc_cursor,recalc_cursor_x,recalc_cursor_y
vt100_csi ent
* 0123456789;ycnlhgrqJKmABCDHf
@ -400,7 +401,7 @@ mode_DECOM
sta y
phy
jsr update_cursor
jsr recalc_cursor
ply
:rts rts
@ -517,7 +518,7 @@ csi_H ; direct cursor addressing
ldx #79
:xxx stx x
jmp update_cursor
jmp recalc_cursor
csi_r ; scrolling region
* based on testing
@ -563,7 +564,7 @@ csi_r ; scrolling region
lda parms+1
sta DECBM
stz x
jmp update_cursor
jmp recalc_cursor
:rts rts

311
vt100.key.S Normal file
View File

@ -0,0 +1,311 @@
* lst off
rel
xc
xc
mx %11
use vt.equ
ext dispatch
KEYMOD equ $c025
KEYSTROBE equ $c010
KBD equ $c000
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
keypress ent
lda KBD
bmi :key
rts
:key
and #$7f
sta key
lda KEYMOD
sta mod
sta KEYSTROBE
bit #kmOption!kmCommand
bne :command
bit #kmKeypad
bne keypad
bit #kmControl
bne :ctrl
lda key
cmp #' '
bcs :notctrl
* control char w/o control bit.
* ie, arrow key / return / tab
asl
tax
jmp (special,x)
:ctrl
lda key
bra :send
:notctrl
cmp #$7f ; delete - special case
bne :send
lda #$08
:send jmp dispatch
:command ; or option
rts
keypad
* todo - keypad enters honors LNM?
lda key
cmp #:MIN
blt :rts
cmp #:MAX+1
bcs :rts
asl
tax
jmp (:table,x)
: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 $0 ; :
dw $0 ; ;
dw $0 ; <
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
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
tsb DECANM
bmi :vt52
tsb DECCKM
bmi :cursor
lda #'['
jsr dispatch
lda key
jmp dispatch
:cursor
lda #'O'
jsr dispatch
* drop through.
:vt52
lda key
jmp dispatch
sav vt52.key.L

View File

@ -6,11 +6,13 @@
* asm boot.S
* asm vt100.ctrl.S
asm vt100.main.S
asm vt100.esc.S
asm vt100.tabs.S
asm vt100.vt52.S
asm vt100.csi.S
asm vt100.screen.S
asm vt100.modem.S
* lnk boot.S
@ -21,5 +23,12 @@
*EMU_SIZE ext
*EMU_BLOCKS geq EMU_SIZE+511\512
lnk vt100.main.L
lnk vt100.esc.L
lnk vt100.tabs.L
lnk vt100.vt52.L
lnk vt100.csi.L
lnk vt100.screen.L
lnk vt100.modem.L
* sav vt100.bin
sav vt100.bin

View File

@ -1,13 +1,14 @@
lst off
cas se
rel
xc
xc
mx %11
use vt.equ
ext update_cursor,scroll_down
ext scroll_down
ext recalc_cursor,recalc_cursor_x,recalc_cursor_y
vt100
mx %11
@ -24,17 +25,16 @@ vt100
:state_table
ext vt52_esc,vt52_dca_1,vt52_dca_2
ext vt52_esc,vt52_dca
ext vt100_esc,vt100_csi,vt100_csi_2
ext vt100_esc_pound,vt100_esc_lparen,vt100_esc_rparen
ext vt100_esc_bad,vt100_csi_bad
ext char
ext draw_char
dw char
dw draw_char
dw vt52_esc
dw vt52_dca_1
dw vt52_dca_2
dw char
dw vt52_dca
dw draw_char
dw vt100_esc
dw vt100_csi
dw vt100_csi_2
@ -122,7 +122,7 @@ ctrl_08 ; back space
and #$7f
dec
sta x
jmp update_cursor
jmp recalc_cursor_x
:rts
ctrl_09 ; tab
@ -132,7 +132,7 @@ ctrl_09 ; tab
bmi :rts
jsr next_tab_stop
stx x
jmp update_cursor
jmp recalc_cursor_x
:rts rts
ctrl_0a ; line feed - cursor down w/ scroll
@ -144,24 +144,25 @@ ctrl_0c ; form feed.
bit #LNM
bpl :lf
stz x
jsr recalc_cursor_x
:lf
lda y
cmp #DECBM
blt :simple
lda #" " ; needs to factor in reverse video
sta cursor_saved_char
* lda #" " ; needs to factor in reverse video
* sta cursor_saved_char
jmp scroll_down
* if LNM mode, need to update cursor as well.
:simple
inc y
jmp update_cursor
jmp recalc_cursor_y
ctrl_0d ; carriage return - cursor to column 0.
stz x
jmp update_cursor
jmp recalc_cursor_x
sav vt100.main.L

171
vt100.modem.S Normal file
View File

@ -0,0 +1,171 @@
lst off
rel
xc
xc
mx %11
cas se
* use vt.equ
SCCBREG equ $c038
SCCAREG equ $c039
SCCBDATA equ $c03a
SCCADATA equ $c03b
init_modem
sep #$30
* reset channel B (modem port)
ldx #9
lda #%01010001
stx SCCBREG
sta SCCBREG
nop
nop
* x16 clock mode, 1 stop bit, no parity
ldx #4
lda #%01000100
stx SCCBREG
sta SCCBREG
* 8 bits/char, rx disabled.
ldx #3
lda #%11000000
stx SCCBREG
sta SCCBREG
* 8 data bits, RTS
ldx #5
lda #%01100010
stx SCCBREG
sta SCCBREG
ldx #11
lda #%01010000
stx SCCBREG
sta SCCBREG
* 9600 baud
ldx #12
lda #10
stx SCCBREG
sta SCCBREG
* 9600 baud
ldx #13
lda #0
stx SCCBREG
sta SCCBREG
* disable baud rate generator
ldx #14
lda #0
stx SCCBREG
sta SCCBREG
* enable baud rate generator
ldx #14
lda #%00000001
stx SCCBREG
sta SCCBREG
* 8 bits/char, rx enabled.
ldx #3
lda #%11000001
stx SCCBREG
sta SCCBREG
* 8 data bits, tx enabled, RTS
ldx #5
lda #%01101010
stx SCCBREG
sta SCCBREG
* disable interrupts
ldx #15
lda #0
stx SCCBREG
sta SCCBREG
* reset ext/status interrupts
ldx #0
lda #%00010000
stx SCCBREG
sta SCCBREG
* disable interrupts
ldx #1
lda #0
stx SCCBREG
sta SCCBREG
* reset ch b ptr to 0?
lda SCCBREG
* status, visible, master interrupts disabled
ldx #9
lda #%00010001
stx SCCBREG
sta SCCBREG
nop
nop
rts
write_modem ent
mx %11
* a: byte to send
tay ; save
* ldx #0
:mask = %0010_0100 ; tx buffer empty, clear to send
:wait stz SCCBREG
lda SCCBREG
and #:mask
cmp #:mask
bne :wait
sty SCCBDATA
rts
read_modem ent
* c set if data read
* v set if overrun
mx %11
* ldx #0
rep #$41 ; clear C + V
stz SCCBREG
lda SCCBREG
and #%0001
beq :rts
* read reg 1 for overrun
lda #1
sta SCCBREG
lda SCCBREG
and #%0010_0000
beq :ok
* clear the overrun
lda #$30 ; reg0, error reset.
sta SCCBREG
stz SCCBREG
sep #$40 ; V
:ok
* lda #8
* sta SCCBREG
* lda SCCBREG
lda SCCBDATA
sec
:rts rts
sav vt100.modem.L

592
vt100.screen.S Normal file
View File

@ -0,0 +1,592 @@
lst off
rel
xc
xc
use vt.equ
mx %11
* x 0-79
* y 0-23
* DECMT 0-22
* DECMB 1-23
*
* cursor_base - pointer to current line
* cursor_offset - index into current line
* cursor_saved_char - saved character under the cursor
* cursor_state - $80 = disabled, $40 = on
text
dw $0400
dw $0480
dw $0500
dw $0580
dw $0600
dw $0680
dw $0700
dw $0780
dw $0428
dw $04a8
dw $0528
dw $05a8
dw $0628
dw $06a8
dw $0728
dw $07a8
dw $0450
dw $04d0
dw $0550
dw $05d0
dw $0650
dw $06d0
dw $0750
dw $07d0
disable_cursor ent
mx %11
php
sei
bit cursor_state
bmi :rts
bvc :80
lda cursor_saved_char
ldy cursor_offset
sta [cursor_base],y
:80 lda #$80
tsb cursor_state
:rts plp
rts
enable_cursor ent
mx %11
php
sei
bit cursor_state
bpl :rts
bvc :80
* option for inverted cursor?
lda cursor_char
ldy cursor_offset
sta [cursor_base],y
:80 lda #$80
trb cursor_state
:rts plp
rts
recalc_cursor ent
* recalculate the cursor pointer after x/y changed
* assumes cursor is off so no saving/restoring the cursor char.
mx %11
php
rep #$30
lda y
asl
tay
lda text,y
sta cursor_base
lda x
and #$7f
lsr
sta cursor_offset
stz cursor_base+2
bcs :ok
inc cursor_base+2
:ok plp
rts
recalc_cursor_x ent
mx %11
php
lda x
and #$7f
lsr
sta cursor_offset
stz cursor_base+2
bcs :ok
inc cursor_base+2
:ok plp
rts
recalc_cursor_y ent
mx %11
php
rep #$30
lda y
asl
tay
lda text,y
sta cursor_base
plp
rts
advance_x ent
mx %11
* ldx x
* cpx #79
* bcs :rts
inc x
lda #1
eor cursor_base+2
sta cursor_base+2
beq :rts
inc cursor_offset
:rts rts
draw_char ent
; a = char
* alternate character set
* 00 - 1f = uppercase inverse letters ('@' - '_')
* 00 - 3f = special characters, inverse (' ' - '?')
* 40 - 4f = mouse text
* 60 - 7f = lower case letters, inverse
* 80 - 9f = upper case letters, normal
* a9 - ff = special, upper, lower chars, normal.
* for normal letters, ora $80
* for inverse letters, uppercase need to be remapped to 0-1f
* others don't change.
bit draw_inverse
bpl :normal
; invert it.
cmp #$60 ; `, first lowercase
bge :draw ; nothing to do for lowercase
cmp #$40 ; @, first uppercase
bcc :draw ; nothing to do for special
:uc and #%10111111 ; ~ $40
bra :draw
:normal ora #$80
:draw
* with DECAWM, x = 79, will CR LF (with scroll) before drawing character.
* at column 79, x increases but cursor does not. up/down does not change
* overflow. backspace / left arrow will go to 78.
* x = 80 indicates next char will wrap if DECAWM. however, treated as 79
ldx x
cpx #79
bcs :rm
ldy cursor_offset
sta [cursor_base],y
jmp advance_x
:rm
beq :79
bit DECAWM
bmi :wrap
:79
ldy cursor_offset
sta [cursor_base],y
lda #$80
tsb x ; mark overflow
rts
:wrap
stz x
ldy y
cpy DECBM
beq :scroll
cpy #23
beq :23 ;
inc y
:23 pha ; save character
jsr recalc_cursor
pla
sta [cursor_base] ; offset 0
rts
:scroll
pha ; save
jsr scroll_down
jsr recalc_cursor_x
pla
sta [cursor_base] ; offset 0
rts
erase_screen ent
mx %11
lda erase_char
* fall through
fill_screen ent
* fill the entire screen with the a register.
* text screen is out of order, so this doesn't use much code but
* it's not linear either.
mx %11
sta >$000400
sta >$010400
php
rep #$30
ldx #$0400
ldy #$0401
lda #40*24-2
mvn $01,$01
ldx #$0400
ldy #$0401
lda #40*24-2
mvn $00,$00
* not needed since $0,$0 last
* phk
* plb
plp
rts
* scroll...
* scroll will always be one line at a time
scroll_up ent
* move DECTM .. DECBM-1 -> DECTM+1 .. DECBM insert blank line at DECTM.
mx %11
php
rep #$30
lda DECBM
sec
sbc DECTM
sta r0
lda DECBM
asl ;
tax
jmp (:dispatch,x)
:dispatch
dw :00,:01,:02,:03,:04
dw :05,:06,:07,:08,:09
dw :10,:11,:12,:13,:14
dw :15,:16,:17,:18,:19
dw :20,:21,:22,:23
* mvn 1,1 first so mvn 0,0 will restore b
:cp mac
lda #$40
lda #40
ldx #]1
ldy #]2
mvn $1,$1
lda #$40
lda #40
ldx #]1
ldy #]2
mvn $0,$0
dec r0
bne *+5
brl :done
<<<
* number refers to the source line.
:23 :cp $0750;$07d0
:22 :cp $06d0;$0750
:21 :cp $0650;$06d0
:20 :cp $05d0;$0650
:19 :cp $0550;$05d0
:18 :cp $04d0;$0550
:17 :cp $0450;$04d0
:16 :cp $07a8;$0450
:15 :cp $0728;$07a8
:14 :cp $06a8;$0728
:13 :cp $0628;$06a8
:12 :cp $05a8;$0628
:11 :cp $0528;$05a8
:10 :cp $04a8;$0528
:09 :cp $0428;$04a8
:08 :cp $0780;$0428
:07 :cp $0700;$0780
:06 :cp $0680;$0700
:05 :cp $0600;$0680
:04 :cp $0580;$0600
:03 :cp $0500;$0580
:02 :cp $0480;$0500
:01 :cp $0400;$0480
:00
:done
* now clear DECTM line
* lda DECTM
* asl
* tay
* ldx text,y
ldx cursor_base
lda erase_char
sta cursor_saved_char
ldy #19
:loop
sta >$000000,x
sta >$010000,x
inx
inx
dey
bpl :loop
plp
rts
scroll_down ent
* move DECTM+1 .. DECBM -> DECTM .. DECBM-1, insert blank line at DECBM.
mx %11
php
rep #$30
lda DECBM
sec
sbc DECTM
sta r0
lda DECTM
asl ;
tax
jmp (:dispatch,x)
:dispatch
dw :00,:01,:02,:03,:04
dw :05,:06,:07,:08,:09
dw :10,:11,:12,:13,:14
dw :15,:16,:17,:18,:19
dw :20,:21,:22,:23
:cp mac
lda #$40
lda #40
ldx #]1
ldy #]2
mvn $1,$1
lda #$40
lda #40
ldx #]1
ldy #]2
mvn $0,$0
dec r0
bne *+5
brl :done
<<<
* todo -- fix offsets
* number refers to the dest line.
:00 :cp $0480;$0400
:01 :cp $0500;$0480
:02 :cp $0580;$0500
:03 :cp $0600;$0580
:04 :cp $0680;$0600
:05 :cp $0700;$0680
:06 :cp $0780;$0700
:07 :cp $0428;$0780
:08 :cp $04a8;$0428
:09 :cp $0528;$04a8
:10 :cp $05a8;$0528
:11 :cp $0628;$05a8
:12 :cp $06a8;$0628
:13 :cp $0728;$06a8
:14 :cp $07a8;$0728
:15 :cp $0450;$07a8
:16 :cp $04d0;$0450
:17 :cp $0550;$04d0
:18 :cp $05d0;$0550
:19 :cp $0650;$05d0
:20 :cp $06d0;$0650
:21 :cp $0750;$06d0
:22 :cp $07d0;$0750
:23
:done
* now clear DECBM line
* lda DECBM
* asl
* tay
* ldx text,y
ldx cursor_base
lda erase_char
sta cursor_saved_char
ldy #19
:loop
sta >$000000,x
sta >$010000,x
inx
inx
dey
bpl :loop
plp
rts
* erase 0 - cursor to end of line
* erase 1 - start of line to cursor
* erase 2 - erase line
erase_line_2 ent
mx %11
php
rep #$30
* lda y
* asl
* ldx text,y
ldx cursor_base
lda erase_char
ldy #19
:loop
sta >$000000,x
sta >$010000,x
inx
inx
dey
bpl :loop
plp
rts
erase_line_0 ent
*
* erase cursor to end of line.
*
mx %11
lda x
beq erase_line_2
php
rep #$30
lda cursor_base
clc
adc cursor_offset
tax
sep #$20 ; short m
* odd byte
ldy cursor_offset
lda cursor_base+2
bne :even
lda erase_char
sta [cursor_base],y
inx
iny
cpy #40
beq :exit
:even
lda erase_char
:loop sta >$010000,x
sta >$000000,x
inx
iny
cpy #40
blt :loop
:exit
plp
rts
erase_line_1 ent
* erase start of line to cursor.
mx %11
lda x
cmp #79
bcs erase_line_2
php
rep #$30
lda cursor_base
clc
adc cursor_offset
tax
ldy cursor_offset
lda cursor_base+2
beq :odd
lda erase_char
sta [cursor_base],y
dex
dey
bmi :exit
:odd
lda erase_char
:loop sta >$010000,x
sta >$000000,x
dex
dey
bpl :loop
:exit plp
rts
* erase screen commands are not affected by origin or scrolling region.
* erase screen
* erase start -> cursor
* erase cursor -> end
sav vt100.screen.L

View File

@ -15,8 +15,8 @@
ext update_cursor,write_modem,draw_char
ext write_modem,draw_char
ext advance_x,recalc_cursor,recalc_cursor_x,recalc_cursor_y
vt52_esc ent
@ -103,7 +103,7 @@ esc_A ; cursor up.
cmp DECTM
beq :rts
dec y
jmp update_cursor
jmp recalc_cursor_y
:rts rts
@ -115,7 +115,7 @@ esc_B ; cursor down
cmp DECBM
beq :rts
iny y
jmp update_cursor
jmp recalc_cursor_y
:rts rts
@ -126,7 +126,7 @@ esc_C ; cursor right
cmp #79
bcs :rts
inc x
jmp update_cursor
jmp recalc_cursor_x
:rts rts
esc_D ; cursor left
@ -136,7 +136,7 @@ esc_D ; cursor left
and #$7f
dec
sta x
jmp update_cursor
jmp recalc_cursor_x
:rts rts
esc_I ; cursor up w/ line scroll
@ -157,7 +157,7 @@ esc_H ; cursor home
lda DECTM
sta y
:go jmp update_cursor
:go jmp recalc_cursor
esc_F ; enter graphics mode
@ -198,7 +198,7 @@ esc_Z ; terminal identity.
vta52_dca ent
vt52_dca ent
* this differs from esc [ H in that invalid
* values are ignored rather than clamped.
* based on testing, does not respect DECOM.
@ -225,7 +225,7 @@ vta52_dca ent
sta y
:update
stz :tmp
jmp update_cursor
jmp recalc_cursor
:tmp ds 2