Compare commits

...

32 Commits
r2 ... master

Author SHA1 Message Date
Kelvin Sherlock
a687a08b0b add command-L to toggle local/online
add command-Q to quit.

Since ROM 1 doesn't have _RemoveCDA in ROM, the control panel is only installed in ROM 3.
(TODO -- check at runtime in case launched from GS/OS)
2022-02-07 10:34:10 -05:00
Kelvin Sherlock
90e807ba46 reset - enable auto-repeat. 2022-01-30 22:29:49 -05:00
Kelvin Sherlock
2c432b3fc1 command-L toggles local/online mode. 2022-01-30 22:29:33 -05:00
Kelvin Sherlock
dcbafc2999 commentary. 2022-01-30 15:52:38 -05:00
Kelvin Sherlock
80edada6e9 DECCOLM 132 support (partial).
I still don't support 132 mode but switching clears the screen, homes the cursor,
and clears any scrolling regions, so it's necessary for passing the vttest suite.
2022-01-30 15:52:32 -05:00
Kelvin Sherlock
04113c4725 Rom 1 _InstallCDA call clobbers some direct page locations.
This is fixed in ROM 3 (or via the TS patches if you boot GS/OS).
Workaround it by switching to DPAGE 0.

Also, allocate memory (since I originally thought that might be relevant).
2022-01-30 15:50:54 -05:00
Kelvin Sherlock
1f7e3b3b4c to make life easier for emacs, backspace will send $7f instead of $08.
command-backspace will send $08 (as will Control-H).
If you have an extended keyboard, delete will also send $08.
(mame uses delete to toggle keyboard mode so it's not yet tested).
2022-01-29 15:43:08 -05:00
Kelvin Sherlock
18daf26568 add DECARM, x, and y to the CDA 2022-01-29 15:41:14 -05:00
Kelvin Sherlock
60259531d5 DECARM - auto repeat support. defaults to auto-repeat on.
n.b. - mame does not currently set the repeat bit in the keymod reg so it's not well tested.
2022-01-29 14:24:55 -05:00
Kelvin Sherlock
22d1c744bb auto-wrap wasn't advancing the cursor after wrapping. 2022-01-29 11:56:15 -05:00
Kelvin Sherlock
c15ae6ac4c add DECREQTPARM support, fix a bug with DA/Device attributes response. 2022-01-29 11:23:41 -05:00
Kelvin Sherlock
9dfc3cc7c9 saving the cursor also saves the SGR 2022-01-29 10:43:09 -05:00
Kelvin Sherlock
71993497ea $7f (delete) character is a null char. drop it (and $00) when checking the read queue. 2022-01-28 23:21:13 -05:00
Kelvin Sherlock
acfe94a4c7 command keys:
* command 1 - command 4 equivalent to PF1 - PF4
* command-delete = backspace (0x7f)
* command-return = linefeed (0x0a)
2022-01-28 22:25:33 -05:00
Kelvin Sherlock
9cf52cb34e vttest fixes
1. control-space should generate a null character
2. vt52 application mode keys were off.
2022-01-28 22:12:37 -05:00
Kelvin Sherlock
186d71de47 print the cancel character for ^X and ^Z.
based on testing, this applies to vt52 and vt100.
use the current x pos to choose between $56 and $57 (mouse text checkerboard)
so multiple characters look pretty.
2022-01-17 13:13:07 -05:00
Kelvin Sherlock
4eb578b94e merge hexdump code 2022-01-17 13:11:00 -05:00
Kelvin Sherlock
c2d3ee0f28 show all SGR (inverse, bold, underscore, blink) as inverted. 2022-01-15 16:36:28 -05:00
Kelvin Sherlock
900dccb3d1 head/tail swapped. 2022-01-15 16:31:38 -05:00
Kelvin Sherlock
ea6ee76a9d fix CDA paging 2022-01-15 16:15:05 -05:00
Kelvin Sherlock
1cc501e72a buffer outgoing keystrokes
this also adds a hexdump in the CDA for the outgoing buffer
in local mode, "incoming" data is read from the outgoing buffer.
Currently data is (potentially) sent on each run of the main loop.
I thought about using the TX empty interrupt but it still needs to be
kicked off at some point (unlike incoming data)
2022-01-15 15:59:29 -05:00
Kelvin Sherlock
f486bbfb1b don't re-enable the cursor blink while there is still pending modem data. this improves performance and visuals. 2022-01-09 19:38:25 -05:00
Kelvin Sherlock
8fa8d8d1fa move modem q variables to the direct page, adjust CDA hexdump to show most recent 16*8 bytes. 2022-01-08 22:26:34 -05:00
Kelvin Sherlock
02c6e1271c cda print_number - support for 0-255 2021-12-19 20:16:52 -05:00
Kelvin Sherlock
279f424cee cda - improve ssc register display 2021-12-06 20:14:35 -05:00
Kelvin Sherlock
e1639db6e4 cda - display SCC registers. 2021-12-05 22:47:40 -05:00
Kelvin Sherlock
6f055a1ef9 update cursor save/cursor restore to also save the DECOM settings. tested with vt100 (mame) 2021-11-28 15:46:29 -05:00
Kelvin Sherlock
cd1397e3cf fixed cursor position report
- verified DECOM behavior
- was missing [ write.
2021-11-28 14:45:03 -05:00
ksherlock
3e53d52226
Create README.md 2021-10-26 08:16:26 -04:00
Kelvin Sherlock
a4fc8a1a19 cda bugs 2021-10-25 14:30:50 -04:00
Kelvin Sherlock
260023c33b fix bug with scrolling region. frotz now works... 2021-10-25 14:30:42 -04:00
Kelvin Sherlock
0d64af63d2 move direct page so it's accessible to CDA
CDA shows direct page variables
move SCC setup to be table-based
esc c reset support.
2021-10-25 13:17:47 -04:00
10 changed files with 1621 additions and 217 deletions

12
README.md Normal file
View File

@ -0,0 +1,12 @@
# itty-bitty-vtty
A vt100 emulator for the Apple IIgs
vt100, modem port, 9600 baud, 8-N-1 (MAME defaults)
A vt100 emulator based on The [User Guide](https://www.vt100.net/docs/vt100-ug/contents.html). Underspecified behavior is tested with MAME's vt100 emulation.
Unimplemented due to hardware limitations:
* alternate character sets
* graphic rendition (except plain/reverse)
* 132-column mode

View File

@ -18,6 +18,7 @@ st_vt100_csi_bad equ 22
ESC equ $1b ESC equ $1b
DPAGE equ $1f00
dum 0 dum 0
state ds 2 state ds 2
@ -35,6 +36,7 @@ DECOM ds 2 ; origin
DECSCNM ds 2 ; screen mode DECSCNM ds 2 ; screen mode
DECAWM ds 2 ; wrap DECAWM ds 2 ; wrap
DECARM ds 2 ; auto repeat DECARM ds 2 ; auto repeat
DECCOLM ds 2 ; character per line (80/132)
LNM ds 2 ; new line LNM ds 2 ; new line
@ -45,7 +47,6 @@ SGR ds 2 ; graphics, bit 1 = bold, 4 = underscore, 5 = blink, 7 = inverse
*CHARSET ds 2 ; *CHARSET ds 2 ;
*GRAPHICS ds 2 ; *GRAPHICS ds 2 ;
*DECCOLM ds 2 ; character per line (80/132)
*DECINLM ds 2 ; interlace *DECINLM ds 2 ; interlace
*DECSCLM ds 2 ; scroll mode *DECSCLM ds 2 ; scroll mode
@ -81,6 +82,17 @@ mod ds 2
* saved cursor * saved cursor
saved_x ds 2 saved_x ds 2
saved_y ds 2 saved_y ds 2
saved_decom ds 2
saved_sgr ds 2
* async read/write pointers.
*
read_q_head ds 2
read_q_tail ds 2
write_q_head ds 2
write_q_tail ds 2
do *>256 do *>256
err "too big" err "too big"

View File

@ -9,6 +9,8 @@
tbx on ; qasm tbx on ; qasm
use apple2gs.equ use apple2gs.equ
use vt.equ
use debug
* alternate character set * alternate character set
@ -25,19 +27,78 @@
* 40-column control panel * 40-column control panel
* TODO - if 80 column set in preferences, draw centered in 80-column mode * TODO - if 80 column set in preferences, draw centered in 80-column mode
init_cda ent
dum 0
* cda direct page variables
ptr ds 2
dend
*
* rom 0/1 doesn't include _RemoveCDA in ROM so it can't be removed.
* additionally, _InstallCDA has bugs.
* so, for now, disable on ROM 1.
cda_startup ent
php php
rep #$30 rep #$30
jsr $fe1f ; idroutine. y = rom
cpy #3
bcc :nope
*
* rom 1 IIgs InstallCDA clobbers $3c-$43 on the direct page
*
phd
pea #0
pld
psl #handle psl #handle
_InstallCDA _InstallCDA
pld
:nope
plp plp
rts rts
cda_shutdown ent
mx %00
jsr $fe1f ; idroutine. y = rom
cpy #3
bcc :nope
phd
pea #0
pld
psl #handle
_RemoveCDA
pld
:nope
rts
handle adrl Header ; can use a fake handle for now, until we need to _RemoveCDA handle adrl Header ; can use a fake handle for now, until we need to _RemoveCDA
Header Header
str 'Virtual Terminal' str 'Virtual Terminal'
adrl start adrl start
adrl shutdown adrl shutdown
* variables.
page ds 2
MAX_PAGE equ 8
pages dw variables
dw hexdump_r
dw hexdump_w
dw ssc_registers
shutdown shutdown
mx %00 mx %00
@ -58,19 +119,59 @@ start
sta SETALTCHAR sta SETALTCHAR
rep #$30 rep #$30
stz page
jsr clear jsr clear
jsr box jsr box
main
jsr clear_inner
ldx page
jsr (pages,x)
:keyloop :keyloop
sep #$30
lda KBD lda KBD
bpl :keyloop bpl :keyloop
sta KEYSTROBE sta KEYSTROBE
rep #$30
and #$7f
cmp #$1b
beq :exit
cmp #$08 ; left
beq :left
cmp #$15
beq :right
bra :keyloop
:exit
pld pld
plb plb
rtl rtl
:left lda page
dec
dec
bpl :lok
lda #MAX_PAGE-2
:lok sta page
bra main
:right lda page
inc
inc
cmp #MAX_PAGE
bcc :rok
lda #0
:rok sta page
bra main
clear clear
ldx #23*2 ldx #23*2
@ -89,21 +190,38 @@ clear
bpl :loop bpl :loop
rts rts
clear_inner
* clear the inner contents.
ldx #16*2
lda #" "
:loop ldy text+8,x
]offset equ 4
lup 16
sta |0+]offset,y
]offset equ ]offset+2
--^
dex
dex
bpl :loop
rts
box box
php php
* top line * top line
lda #"_ " lda #"_ "
sta $0400+38 sta |line_0+38
lda #" _" lda #" _"
sta $0400 sta |line_0
lda #"__" lda #"__"
ldx #34 ldx #34
]loop sta $0400+2,x ]loop sta |line_0+2,x
dex dex
dex dex
bpl ]loop bpl ]loop
@ -111,15 +229,15 @@ box
* bottom line. * bottom line.
* 'L' = $4c = _ but high * 'L' = $4c = _ but high
lda #'L '!$8000 ; keep ' ' high ascii. lda #'L '!$8000 ; keep ' ' high ascii.
sta $07d0+38 sta |line_23+38
lda #' L'!$0080 ; keep ' ' high ascii. lda #' L'!$0080 ; keep ' ' high ascii.
sta $07d0 sta |line_23
lda #'LL' lda #'LL'
ldx #34 ldx #34
]loop sta $07d0+2,x ]loop sta |line_23+2,x
dex dex
dex dex
bpl ]loop bpl ]loop
@ -150,14 +268,14 @@ box
* title * title
ldx #36 ldx #36
]loop lda :title,x ]loop lda :title,x
sta |$0480+1,x sta |line_1+1,x
dex dex
dex dex
bpl ]loop bpl ]loop
lda #'LL' lda #'LL'
ldx #36 ldx #36
]loop sta |$0500+1,x ]loop sta |line_2+1,x
dex dex
dex dex
bpl ]loop bpl ]loop
@ -165,7 +283,7 @@ box
* bottom instructions * bottom instructions
ldx #:instr_len-2 ldx #:instr_len-2
]loop lda :instr,x ]loop lda :instr,x
sta |$0750+1,x sta |line_22+1,x
dex dex
dex dex
bpl ]loop bpl ]loop
@ -187,6 +305,692 @@ box
ds 38-18,' ' ds 38-18,' '
* print variables.
variables
php
sep #$20
jsr local
jsr decanm
jsr decom
jsr deckpam
jsr decckm
jsr decawm
jsr decarm
jsr decscnm
jsr deccolm
jsr lnm
jsr sgr
jsr dectm
jsr decbm
jsr decx
jsr decy
plp
rts
local
mx %10
ldy #line_4+4
ldx #:str
jsr print_xy_str
lda DPAGE+LOCAL
jmp print_on_off
:str asc "LOCAL: ",00
decanm
mx %10
ldy #line_5+4
ldx #:str
jsr print_xy_str
lda DPAGE+DECANM
bmi :100
ldx #:vt52
jmp print_xy_str
:100 ldx #:vt100
jmp print_xy_str
:str asc "DECANM: ",00
:vt100 asc "vt100",00
:vt52 asc "vt52",00
decom
mx %10
ldy #line_6+4
ldx #:str
jsr print_xy_str
lda DPAGE+DECOM
jmp print_on_off
:str asc "DECOM: ",00
deckpam
mx %10
ldy #line_7+4
ldx #:str
jsr print_xy_str
lda DPAGE+DECKPAM
jmp print_on_off
:str asc "DECKPAM: ",00
decckm
mx %10
ldy #line_8+4
ldx #:str
jsr print_xy_str
lda DPAGE+DECCKM
jmp print_on_off
:str asc "DECCKM: ",00
decawm
mx %10
ldy #line_9+4
ldx #:str
jsr print_xy_str
lda DPAGE+DECAWM
jmp print_on_off
:str asc "DECAWM: ",00
decarm
mx %10
ldy #line_10+4
ldx #:str
jsr print_xy_str
lda DPAGE+DECARM
jmp print_on_off
:str asc "DECARM: ",00
decscnm
mx %10
ldy #line_11+4
ldx #:str
jsr print_xy_str
lda DPAGE+DECSCNM
jmp print_on_off
:str asc "DECSCNM: ",00
deccolm
mx %10
ldy #line_12+4
ldx #:str
jsr print_xy_str
lda DPAGE+DECCOLM
jmp print_on_off
:str asc "DECCOLM: ",00
lnm
mx %10
ldy #line_13+4
ldx #:str
jsr print_xy_str
lda DPAGE+LNM
jmp print_on_off
:str asc "LNM: ",00
sgr
mx %10
ldy #line_14+4
ldx #:str
jsr print_xy_str
lda DPAGE+SGR
jmp print_binary
:str asc "SGR: ",00
dectm
mx %10
ldy #line_15+4
ldx #:str
jsr print_xy_str
lda DPAGE+DECTM
inc
jmp print_number
:str asc "DECTM: ",00
decbm
mx %10
ldy #line_16+4
ldx #:str
jsr print_xy_str
lda DPAGE+DECBM
inc
jmp print_number
:str asc "DECBM: ",00
decx
mx %10
ldy #line_17+4
ldx #:str
jsr print_xy_str
lda DPAGE+x
and #$7f
inc
jmp print_number
:str asc "X: ",00
decy
mx %10
ldy #line_18+4
ldx #:str
jsr print_xy_str
lda DPAGE+y
inc
jmp print_number
:str asc "Y: ",00
print_xy_str
mx %10
:loop lda |$0,x
beq :end
sta |$0,y
inx
iny
bra :loop
:end
rts
print_on_off
mx %10
bmi :set
ldx #:off
jmp print_xy_str
:set ldx #:on
jmp print_xy_str
:on asc "on",00
:off asc "off",00
print_number
debug print_number
*
* print a base-10 number, 0-255
* a = #
mx %10
ldx #0
:100
cmp #100
bcc :10x
inx
* sec
sbc #100
bra :100
:10x
cpx #0
beq :10
pha
txa
* clc
* adc #"0"
ora #"0"
sta |$0,y
iny
pla
ldx #0
:10
cmp #10
bcc :1x
inx
sbc #10
bra :10
:1x
cpx #0
beq :1
pha
txa
* clc
* adc #"0"
ora #"0"
sta |$0,y
iny
pla
:1
* clc
* adc #"0"
ora #"0"
sta |$0,y
iny
rts
print_binary
mx %10
* pha
* lda #"%"
* sta |$0,y
* iny
* pla
lup 8
asl
pha
lda #0
adc #"0"
sta |$0,y
iny
pla
--^
rts
print_hex
mx %10
xba
lda #0
xba
pha
lsr
lsr
lsr
lsr
tax
lda hex,x
sta |$0,y
iny
pla
and #$0f
tax
lda hex,x
sta |$0,y
iny
rts
hexdump_r
*
* $1e00 buffer
*
mx %00
lda DPAGE+read_q_tail
sec
sbc #8*16
and #$00ff
ora #$1e00
jmp hexdump_common
hexdump_w
*
* $1d00 buffer
*
mx %00
lda DPAGE+write_q_tail
sec
sbc #8*16
and #$00ff
ora #$1d00
jmp hexdump_common
hexdump_common
*
* a = address to start.
:screen equ 0
:screen2 equ 2
*:offset equ 4
:ptr equ 6
:count equ 8
:row equ 10
:c equ 12
mx %00
debug hexdump
php
sta :ptr
lda #0
* stz :offset
sep #$20
ldx #4*2
stx :row
:one_row
ldx :row
ldy text,x
sty :screen
sty :screen2
lda #8
sta :count
:one_byte
lda (:ptr)
inc :ptr
sta :c
lsr
lsr
lsr
lsr
tax
lda hex,x
ldy :screen
sta |$04,y
iny
lda :c
and #$0f
tax
lda hex,x
sta |$04,y
iny
lda #" "
sta |$04,y
iny
sty :screen
* ascii
ldx #"."
lda :c
cmp #$20
blt :dot
cmp #$80
bcs :dot
ora #$80
tax
:dot
txa
ldy :screen2
sta |8*3+4,y
iny
sty :screen2
dec :count
bne :one_byte
ldx :row
inx
inx
stx :row
cpx #20*2
bcc :one_row
plp
rts
hex asc "0123456789abcdef"
ssc_registers
debug ssc_registers
*
* print SSC read registers. read reg 8 (incoming data byte) is skipped.
*
*
*SCCBREG equ $c038
*SCCAREG equ $c039
*SCCBDATA equ $c03a
*SCCADATA equ $c03b
* read everything at once.
php
sep #$34 ; short m/x, ints off
lda #0
xba
* sei
ldx #0
lda SCCAREG ; sync
lda SCCBREG ; sync
stx SCCAREG
lda SCCAREG
sta ssc_data+0
stx SCCBREG
lda SCCBREG
sta ssc_data+1
inx ;1
stx SCCAREG
lda SCCAREG
sta ssc_data+2
stx SCCBREG
lda SCCBREG
sta ssc_data+3
inx ;2
stx SCCAREG
lda SCCAREG
sta ssc_data+4
stx SCCBREG
lda SCCBREG
sta ssc_data+5
inx ;3
stx SCCAREG
lda SCCAREG
sta ssc_data+6
stx SCCBREG
lda SCCBREG
sta ssc_data+7
ldx #10 ; 10
stx SCCAREG
lda SCCAREG
sta ssc_data+8
stx SCCBREG
lda SCCBREG
sta ssc_data+9
ldx #12 ; 12
stx SCCAREG
lda SCCAREG
sta ssc_data+10
stx SCCBREG
lda SCCBREG
sta ssc_data+11
inx ; 13
stx SCCAREG
lda SCCAREG
sta ssc_data+12
stx SCCBREG
lda SCCBREG
sta ssc_data+13
ldx #15 ; 15
stx SCCAREG
lda SCCAREG
sta ssc_data+14
stx SCCBREG
lda SCCBREG
sta ssc_data+15
cli
rep #$10 ; long x
mx %10
jsr rr0
jsr rr1
jsr rr2
jsr rr3 ; only exists in channel A.
jsr rr10
jsr rr12 ; baud low
* jsr rr13 ; baud high
jsr rr15
plp
rts
ssc_data ds 16
rr0
mx %10
ldy #line_5+4
ldx #:str
jsr print_xy_str
lda ssc_data+0
jsr print_binary
iny
iny
lda ssc_data+1
jmp print_binary
:str asc "RR 0: ",00
rr1
mx %10
ldy #line_6+4
ldx #:str
jsr print_xy_str
lda ssc_data+2
jsr print_binary
iny
iny
lda ssc_data+3
jmp print_binary
:str asc "RR 1: ",00
rr2
mx %10
ldy #line_7+4
ldx #:str
jsr print_xy_str
lda ssc_data+4
jsr print_binary
iny
iny
lda ssc_data+5
jmp print_binary
:str asc "RR 2: ",00
rr3
mx %10
ldy #line_8+4
ldx #:str
jsr print_xy_str
lda ssc_data+6
jsr print_binary
iny
iny
lda ssc_data+7
jmp print_binary
:str asc "RR 3: ",00
rr10
mx %10
ldy #line_9+4
ldx #:str
jsr print_xy_str
lda ssc_data+8
jsr print_binary
iny
iny
lda ssc_data+9
jmp print_binary
:str asc "RR 10: ",00
* 12/13 are baud
rr12
mx %10
ldy #line_10+4
ldx #:str
jsr print_xy_str
iny
iny
iny
iny
lda ssc_data+12
jsr print_hex
lda ssc_data+10
jsr print_hex
iny
iny
iny
iny
iny
iny
lda ssc_data+13
jsr print_hex
lda ssc_data+11
jmp print_hex
:str asc "RR 12: ",00
rr15
mx %10
ldy #line_11+4
ldx #:str
jsr print_xy_str
lda ssc_data+14
jsr print_binary
iny
iny
lda ssc_data+15
jmp print_binary
:str asc "RR 15: ",00
text text
dw $0400 dw $0400
dw $0480 dw $0480
@ -215,4 +1019,30 @@ text
line_0 equ $0400
line_1 equ $0480
line_2 equ $0500
line_3 equ $0580
line_4 equ $0600
line_5 equ $0680
line_6 equ $0700
line_7 equ $0780
line_8 equ $0428
line_9 equ $04a8
line_10 equ $0528
line_11 equ $05a8
line_12 equ $0628
line_13 equ $06a8
line_14 equ $0728
line_15 equ $07a8
line_16 equ $0450
line_17 equ $04d0
line_18 equ $0550
line_19 equ $05d0
line_20 equ $0650
line_21 equ $06d0
line_22 equ $0750
line_23 equ $07d0
sav vt100.cda.L sav vt100.cda.L

View File

@ -16,8 +16,9 @@
ext recalc_cursor,recalc_cursor_x,recalc_cursor_y ext recalc_cursor,recalc_cursor_x,recalc_cursor_y
ext erase_line_0,erase_line_1,erase_line_2 ext erase_line_0,erase_line_1,erase_line_2
ext erase_screen_0,erase_screen_1,erase_screen_2 ext erase_screen_0,erase_screen_1,erase_screen_2
ext update_sgr
ext write_modem ext write_modem,write_modem_str
vt100_csi ent vt100_csi ent
@ -261,7 +262,7 @@ vt100_csi_2 ent
dw :rts ; u dw :rts ; u
dw :rts ; v dw :rts ; v
dw :rts ; w dw :rts ; w
dw :rts ; x dw csi_x ; x
dw csi_y ; y dw csi_y ; y
:modifier :modifier
@ -353,7 +354,7 @@ mode_common
dw :rts ; error dw :rts ; error
dw mode_DECCKM dw mode_DECCKM
dw mode_DECANM dw mode_DECANM
dw :rts ; DECCOLM dw mode_DECCOLM ; DECCOLM
dw :rts ; DECSCLM dw :rts ; DECSCLM
dw mode_DECSCNM dw mode_DECSCNM
dw mode_DECOM dw mode_DECOM
@ -395,10 +396,33 @@ mode_DECANM
:rts rts :rts rts
*mode_DECCOLM mode_DECCOLM
* sty DECCOLM * 80/132 mode.
* rts * vt102 guide states:
* NOTE: When you change the number of columns per line, the screen is erased.
* This also sets the scrolling region for full screen (24 lines).
*
* based on testing, this always clears the screen and resets x/y, regardless of current mode.
*
bit pmod
bpl :rts
sty DECCOLM
lda #0
sta DECTM
lda #23
sta DECBM
stz x
stz y
phy
jsr recalc_cursor
jsr erase_screen_2
ply
:rts rts
mode_DECSCNM mode_DECSCNM
bit pmod bit pmod
@ -472,12 +496,8 @@ csi_m
cpx pcount cpx pcount
blt :loop blt :loop
* now update - bit 7 indicates inverse. jmp update_sgr
lda SGR
and #$80
sta draw_inverse
:rts rts
:and db $00,$ff,$ff,$ff,$ff,$ff,$ff,$ff :and db $00,$ff,$ff,$ff,$ff,$ff,$ff,$ff
@ -679,6 +699,7 @@ csi_H ; direct cursor addressing
jmp recalc_cursor jmp recalc_cursor
csi_r ; scrolling region csi_r ; scrolling region
debug csi_r
* based on testing * based on testing
* esc [ n r (no second parmeter) is equivalent to esc [ n ; 24 r * esc [ n r (no second parmeter) is equivalent to esc [ n ; 24 r
* esc [ r sets scrolling region to 1 ; 24 ( in accordance with above ) * esc [ r sets scrolling region to 1 ; 24 ( in accordance with above )
@ -703,11 +724,11 @@ csi_r ; scrolling region
:check :check
* 23 max * 23 max
ldx parms+0 ldx parms+0
cmp #23+1 cpx #23+1
bge :rts bge :rts
ldx parms+1 ldx parms+1
cmp #23+1 cpx #23+1
bge :rts bge :rts
@ -786,12 +807,19 @@ csi_n ; status report
lda #'n' lda #'n'
jmp write_modem jmp write_modem
:cpr ; cursor report :cpr ; cursor report
* TODO - verify and support DECOM * returned y is in terms of DECOM.
lda #ESC lda #ESC
jsr write_modem jsr write_modem
lda #'[' lda #'['
jsr write_modem
lda y lda y
inc bit DECOM
bpl :y
sec
sbc DECTM
:y inc
jsr write_digit jsr write_digit
lda #';' lda #';'
jsr write_modem jsr write_modem
@ -827,23 +855,45 @@ write_digit
:table db 0,10,20,30,40,50,60,70,80 :table db 0,10,20,30,40,50,60,70,80
csi_c ; what are you? csi_c ; what are you?
lda #ESC * DA - Device Attributes
jsr write_modem
lda #'[' mx %11
jsr write_modem
lda #'?' php
jsr write_modem rep #$10 ; long x/y
lda #'1' ldy #:response
jsr write_modem jsr write_modem_str
lda #'?' plp
jsr write_modem rts
lda #'0'
jsr write_modem :response asc 1b,'[?1;0c',00 ; No options.
lda #'c'
jmp write_modem
csi_y ; invoke confidence test csi_y ; invoke confidence test
* ??? * ???
rts rts
csi_x ; request terminal parameters
* DECREQTPARM Request Terminal Parameters
mx %11
lda parms
cmp #2
bcs :rts
inc
inc
ora #'0'
sta :response+2
php
rep #$10 ; long x/y
ldy #:response
jsr write_modem_str
plp
:rts rts
:response asc 1b,'[x;1;1;112;112;1;0x',00 ; no parity, 8-bits, 9600/9600, 16x multiplier, no stp flags.
sav vt100.csi.L sav vt100.csi.L

View File

@ -109,8 +109,11 @@ xoff
rts rts
can can
sub sub
ext draw_char_raw
* cancel esc sequence and display error character * cancel esc sequence and display error character
stz state stz state
lda #$57 ; mouse text block
jmp draw_char_raw
rts rts
esc esc

View File

@ -11,6 +11,8 @@
ext recalc_cursor,recalc_cursor_x,recalc_cursor_y ext recalc_cursor,recalc_cursor_x,recalc_cursor_y
ext scroll_up,scroll_down ext scroll_up,scroll_down
ext reset
ext update_sgr
vt100_esc ent vt100_esc ent
* #[()=>cH78DEM * #[()=>cH78DEM
@ -133,21 +135,29 @@ vt100_esc ent
esc_7 ; save cursor position, graphic rendition, and character set. esc_7 ; save cursor position, graphic rendition, and character set.
* based on testing, DECOM is also saved/restored.
lda x lda x
sta saved_x sta saved_x
lda y lda y
sta saved_y sta saved_y
lda DECOM
sta saved_decom
lda SGR
sta saved_sgr
rts rts
esc_8 ; restore cursor position, graphic rendition, and character set. esc_8 ; restore cursor position, graphic rendition, and character set.
* TODO - how does this interact with DECOM?
lda saved_x lda saved_x
sta x sta x
lda saved_y lda saved_y
sta y sta y
lda saved_decom
sta DECOM
lda saved_sgr
sta SGR
jsr update_sgr
jmp recalc_cursor jmp recalc_cursor
esc_eq ; enter alternate keypad mode esc_eq ; enter alternate keypad mode
@ -206,8 +216,8 @@ esc_M ; reverse index
:rts rts :rts rts
esc_c ; reset terminal. esc_c ; TODO - reset terminal.
rts jmp reset
vt100_esc_bad ent vt100_esc_bad ent
@ -294,6 +304,7 @@ vt100_esc_rparen ent
* SI, aka Control-O aka 0x0f set the G0 char set * SI, aka Control-O aka 0x0f set the G0 char set
* not currently supported. * not currently supported.
* TODO - mouse text support?
ldx #st_vt100 ldx #st_vt100
stx state stx state

View File

@ -4,13 +4,16 @@
xc xc
xc xc
tbx on
use vt.equ use vt.equ
use apple2gs.equ use apple2gs.equ
use debug use debug
mx %11 mx %11
ext dispatch * ext dispatch
ext write_modem
kmShift equ %0000_0001 kmShift equ %0000_0001
@ -22,22 +25,58 @@ kmUpdateMod equ %0010_0000
kmOption equ %0100_0000 kmOption equ %0100_0000
kmCommand equ %1000_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 keypress ent
debug keypress debug keypress
lda KBD lda KBD
bmi :key bmi :key
rts :rts rts
:key :key
and #$7f and #$7f
sta key sta key
lda KEYMOD lda KEYMOD
sta mod sta mod
sta KEYSTROBE 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
bpl :arm
bit #kmRepeat
bne :rts
:arm
bit #kmOption!kmCommand bit #kmOption!kmCommand
bne :command bne command
bit #kmKeypad bit #kmKeypad
bne keypad jne keypad
bit #kmControl bit #kmControl
bne :ctrl bne :ctrl
@ -55,22 +94,35 @@ keypress ent
:ctrl :ctrl
lda key lda key
and #$1f ; control-space should generate 0, not $20.
bra :send bra :send
:notctrl :notctrl
cmp #$7f ; delete - special case * cmp #$7f ; delete - special case
bne :send * bne :send
lda #$08 * lda #$08
:send jmp dispatch :send jmp dispatch
:command ; or option command ; or option
rts
* apple-return -> linefeed
keypad * apple-backspace -> delete
* todo - keypad enters honors LNM?
lda key 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 cmp #:MIN
blt :rts blt :rts
cmp #:MAX+1 cmp #:MAX+1
@ -83,6 +135,104 @@ keypad
:rts rts :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 :MIN equ 13
:MAX equ 61 :MAX equ 61
:table :table
@ -118,7 +268,7 @@ keypad
dw pf4 ; * dw pf4 ; *
dw comma ; + dw comma ; +
dw :rts ; , dw :rts ; ,
dw dash ; - dw dash ; -
dw dot ; . dw dot ; .
dw pf3 ; / PF3 -> ESC R dw pf3 ; / PF3 -> ESC R
dw digit ; 0 dw digit ; 0
@ -131,9 +281,9 @@ keypad
dw digit ; 7 dw digit ; 7
dw digit ; 8 dw digit ; 8
dw digit ; 9 dw digit ; 9
dw $0 ; : dw :rts ; :
dw $0 ; ; dw :rts ; ;
dw $0 ; < dw :rts ; <
dw pf2 ; = PF2 -> ESC Q dw pf2 ; = PF2 -> ESC Q
@ -195,6 +345,7 @@ digit
lda #'?' lda #'?'
jsr dispatch jsr dispatch
lda key lda key
ora #$40
jmp dispatch jmp dispatch

View File

@ -4,6 +4,8 @@
xc xc
xc xc
tbx on ; qasm
mx %11 mx %11
use vt.equ use vt.equ
use apple2gs.equ use apple2gs.equ
@ -11,13 +13,14 @@
ext scroll_down ext scroll_down
ext recalc_cursor,recalc_cursor_x,recalc_cursor_y ext recalc_cursor,recalc_cursor_x,recalc_cursor_y
ext write_modem,read_modem,init_modem,modem_vector ext modem_io,modem_vector,reset_modem_buffer
ext modem_startup,modem_shutdown
ext keypress ext keypress
ext disable_cursor,enable_cursor,cursor_vector ext disable_cursor,enable_cursor,cursor_vector
ext erase_screen,fill_screen ext erase_screen,fill_screen
ext init_tabs ext init_tabs
ext init_audio ext init_audio
ext init_cda ext cda_startup,cda_shutdown
main debug main main debug main
@ -25,6 +28,9 @@ main debug main
xce xce
cli cli
pea DPAGE
pld
jsr init jsr init
jsr enable_cursor jsr enable_cursor
@ -34,23 +40,23 @@ main debug main
stz SCANINT ; reset 1-sec interrupt stz SCANINT ; reset 1-sec interrupt
loop loop
bit LOCAL jsr keypress ; check for a keypress, write data to out buffer.
bmi :kb jsr modem_io ;
jsr read_modem bcc :nope
bcc :kb
pha pha
jsr disable_cursor jsr disable_cursor
pla pla
jsr vt100 jsr vt100
:kb bra loop
jsr keypress
:nope ; no modem data, re-enable the cursor.
jsr enable_cursor jsr enable_cursor
bra loop bra loop
init init
mx %11 mx %11
lda #" " lda #" "
jsr fill_screen ; erase first to prevent flash if going 40->80 columns. jsr fill_screen ; erase first to prevent flash if going 40->80 columns.
@ -59,6 +65,9 @@ init
sta SETALTCHAR sta SETALTCHAR
rep #$30 rep #$30
jsr init_mem
ldx #254 ldx #254
:zloop stz 0,x :zloop stz 0,x
dex dex
@ -103,30 +112,196 @@ init
sta DECBM sta DECBM
lda #$80 lda #$80
* sta LOCAL * sta LOCAL
sta DECANM sta DECANM ; ANSI (vt100) on
sta DECARM ; key repeat on
* lda #st_vt52 * lda #st_vt52
lda #st_vt100 lda #st_vt100
sta state sta state
* jsr erase_screen * jsr erase_screen
jsr init_modem jsr modem_startup
jsr init_tabs jsr init_tabs
jsr init_audio jsr init_audio
jsr init_cda jsr cda_startup
rts rts
dispatch ent MasterID dw 0
mx %11 init_mem
* a = character to xmit *
bit LOCAL * see prodos technote #27
bmi :local *
jmp write_modem * _InstallCDA uses the memory manager ; otherwise I wouldn't bother
:local * This is here to prevent MM from stomping on our memory.
*
mx %00
stz MasterID
_TLStartUp
pha pha
jsr disable_cursor _MMStartUp
pla pla
bcs :p8
rts
:p8
_MTStartUp
pea #0
pea #$1000
_GetNewID
pla
sta MasterID
* bank 0
pha
pha
pea #$0000
pea #$b800
lda MasterID
pha
pea #$c013
pea #0000
pea #0800
_NewHandle
pla
pla
* bank 1
pha
pha
pea #$0000
pea #$b800
lda MasterID
pha
pea #$c013
pea #$0001
pea #$0800
_NewHandle
pla
pla
rts
reset ent
mx %11
php
* disable 1-sec interrupt...
lda #4
trb VGCINT ; disable 1-sec interrupt.
stz SCANINT ; reset 1-sec interrupt
lda #" "
jsr fill_screen ; erase first to prevent flash if going 40->80 columns.
rep #$30
ldx #254
:zloop stz 0,x
dex
dex
bpl :zloop
lda #$0400
sta cursor_base
lda #$01
sta cursor_base+2
lda #" " ; 16-bit
sta erase_char
lda #$0080
sta cursor_state
lda #0 ; clear high byte
sep #$30
lda #"_"
sta cursor_char
lda #23
sta DECBM
lda #$80
sta DECANM ; ansi mode
sta DECARM ; key repeat on
lda #st_vt100
sta state
jsr init_tabs
* jsr enable_cursor
jsr reset_modem_buffer
lda #4
tsb VGCINT ; enable 1-sec interrupt.
stz SCANINT ; reset 1-sec interrupt
plp
rts
quit ent
* need to disable modem interrupts
sep #$30
lda #4
trb VGCINT ; disable 1-sec interrupt.
stz SCANINT ; reset 1-sec interrupt
jsr modem_shutdown
rep #$30
jsr cda_shutdown
lda MasterID
beq :e
pha
pha
_DisposeAll
_DeleteID
:e
pea #0
pld
sec
xce
mx %00
inc $3f4 ; invalidate power-up bit
jsr $bf00
db $65
dw :parms
brk $ea
:parms db 4
db 0
dw 0
db 0
dw 0
*dispatch ent
* mx %11
** a = character to xmit
* bit LOCAL
* bmi :local
* jmp write_modem
*:local
* pha
* jsr disable_cursor
* pla
* fall through * fall through
@ -149,7 +324,7 @@ vt100
ext vt100_esc,vt100_csi,vt100_csi_2 ext vt100_esc,vt100_csi,vt100_csi_2
ext vt100_esc_pound,vt100_esc_lparen,vt100_esc_rparen ext vt100_esc_pound,vt100_esc_lparen,vt100_esc_rparen
ext vt100_esc_bad,vt100_csi_bad ext vt100_esc_bad,vt100_csi_bad
ext draw_char ext draw_char,draw_char_raw
dw draw_char dw draw_char
dw vt52_esc dw vt52_esc
@ -225,7 +400,16 @@ ctrl_18
ctrl_1a ctrl_1a
* vt100 - abort current escape sequence * vt100 - abort current escape sequence
* and display error character. * and display error character.
* TODO - display error character (mouse text) *
* based on testing, this applies to vt52 and vt100;
* cancel character is drawn regardless of current state.
lda x
and #$1
ora #$56 ; $56 or $57
* lda #$57
jsr draw_char_raw
bit DECANM bit DECANM
bpl :vt52 bpl :vt52
lda #st_vt100 lda #st_vt100

View File

@ -6,7 +6,8 @@
mx %11 mx %11
cas se cas se
* use vt.equ use vt.equ
use debug
SCCBREG equ $c038 SCCBREG equ $c038
SCCAREG equ $c039 SCCAREG equ $c039
@ -29,143 +30,132 @@ SerFlag equ $e10104 ;
* *
* see IIgs TN #18 - Do-It-Yourself SCC Access * see IIgs TN #18 - Do-It-Yourself SCC Access
init_modem ent modem_startup ent
enable_modem ent
* sep #$30 * sep #$30
php
sei
stz q_head stz read_q_head
stz q_tail stz read_q_tail
stz write_q_head
* reset channel B (modem port) stz write_q_tail
ldx #9
lda #%01_0_1_0_0_0_1
stx SCCBREG
sta SCCBREG
nop
nop
* x16 clock mode, 1 stop bit, no parity
ldx #4
lda #%01_00_01_0_0
stx SCCBREG
sta SCCBREG
* 8 bits/char, rx disabled.
ldx #3
lda #%11_0_0_0_0_0_0
stx SCCBREG
sta SCCBREG
* 8 data bits, RTS
ldx #5
lda #%0_11_0_0_0_1_0
stx SCCBREG
sta SCCBREG
* bit 7 = 1 for printer port, 0 for modem port.
* 5/6 = (%10) rcv clock = br output
* 4/3 = (%10) tx clock = br output
ldx #11
lda #%0_10_10_0_00
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 * zero out the buffer [for CDA debugger]
ldx #14
lda #0
stx SCCBREG
sta SCCBREG
* enable baud rate generator
ldx #14
lda #%000_0_0_0_0_1
stx SCCBREG
sta SCCBREG
* 8 bits/char, rx enabled.
ldx #3
lda #%11_0_0_0_0_0_1
stx SCCBREG
sta SCCBREG
* 8 data bits, tx enabled, RTS
ldx #5
lda #%0_11_0_1_0_1_0
stx SCCBREG
sta SCCBREG
* disable interrupts
ldx #15
lda #0
stx SCCBREG
sta SCCBREG
* reset ext/status interrupts
ldx #0 ldx #0
lda #%00_010_0_00 ]loop stz read_buffer,x
stx SCCBREG inx
bne ]loop
lda SCCBREG ; sync access
ldx #0
]loop
lda :table,x
bmi :done
sta SCCBREG sta SCCBREG
inx
* enable interrupts lda :table,x
ldx #1
* lda #0
lda #%0_0_0_10_0_0_0 ; inr on rx or special condition.
stx SCCBREG
sta SCCBREG sta SCCBREG
inx
* reset ch b ptr to 0? bra ]loop
lda SCCBREG :done
* no vector, master interrupts enabled
ldx #9
lda #%00_0_0_1_0_1_0
stx SCCBREG
sta SCCBREG
nop
nop
* adjust SerFlag so serial IRQs will be handled. * adjust SerFlag so serial IRQs will be handled.
lda >SerFlag lda >SerFlag
ora #%00_000_111 ; channel B interrupts. ora #%00_000_111 ; channel B interrupts.
sta >SerFlag sta >SerFlag
plp
rts rts
write_modem ent :table ; register, value
* db 9,%01_0_1_0_0_0_1 ; reset channel B (modem port) - handled @ startup.
db 4,%01_00_01_0_0 ; x16 clock, 1 stop bit, no parity
db 3,%11_0_0_0_0_0_0 ; 8 bits, rx disabled
db 5,%0_11_0_0_0_1_0 ; 8 bits, RTS
db 11,%0_10_10_0_00 ; modem port, rcv/tx clock = br
db 12,10 ; 9600 baud (low)
db 13,0 ; 9600 baud (high)
db 14,0 ; disable baud rate generator
db 14,%000_0_0_0_0_1 ; enable baud rate generator
db 3,%11_0_0_0_0_0_1 ; 8 bits, rx enabled
db 5,%0_11_0_1_0_1_0 ; 8 bits, tx enabled, RTS
db 15,0 ; disable external interrupts
db 0,%00_010_0_00 ; reset ext/status interrupts
db 1,%0_0_0_10_0_0_0 ; interrupts on rx or special condition
db 9,%00_0_0_1_0_1_0 ; master interrupts enabled.
db -1,-1
disable_modem ent
* local mode
mx %11
php
sei
lda SCCBREG ; sync access
lda #9
sta SCCBREG
lda #%01_0_1_0_0_0_1 ; reset channel B.
sta SCCBREG
stz read_q_head
stz read_q_tail
stz write_q_head
stz write_q_tail
plp
rts
modem_shutdown ent
mx %11
php
sei
lda SCCBREG ; sync access
lda #9
sta SCCBREG
lda #%01_0_1_0_0_0_1 ; reset channel B.
sta SCCBREG
lda >SerFlag
and #%11_111_000 ; channel B interrupts.
sta >SerFlag
plp
rts
write_modem_sync ent
mx %11 mx %11
* a: byte to send * a: byte to send
tay ; save tay ; save
* ldx #0 * ldx #0
php
:mask = %0010_0100 ; tx buffer empty, clear to send :mask = %0010_0100 ; tx buffer empty, clear to send
:wait stz SCCBREG :wait
cli ; guard scc register access.
sei
stz SCCBREG
lda SCCBREG lda SCCBREG
and #:mask and #:mask
cmp #:mask cmp #:mask
bne :wait bne :wait
sty SCCBDATA sty SCCBDATA
plp
rts rts
read_modem_sync ent read_modem_sync ent
* c set if data read * c set if data read
* v set if overrun * v set if overrun
@ -183,9 +173,7 @@ read_modem_sync ent
lda SCCBREG lda SCCBREG
and #%0010_0000 and #%0010_0000
beq :ok beq :ok
* indicate overrun...
lda #"x"
sta |$07d0+20
* clear the overrun * clear the overrun
lda #$30 ; reg0, error reset. lda #$30 ; reg0, error reset.
sta SCCBREG sta SCCBREG
@ -198,17 +186,14 @@ read_modem_sync ent
lda SCCBDATA lda SCCBDATA
* debugging... * debugging...
ldx :debug
sta $1e00,x
inc :debug
sec sec
:rts rts :rts rts
:debug ds 2 write_buffer equ $1d00
read_buffer equ $1e00
buffer equ $1d00
modem_vector ent modem_vector ent
jml modem_int jml modem_int
@ -219,14 +204,21 @@ modem_int
* a/x/y don't need to be preserved. * a/x/y don't need to be preserved.
* return carry clear if handled, carry set if not. * return carry clear if handled, carry set if not.
* doesn't access direct page.
* check/clear overrun? * check/clear overrun?
*
* n.b. - vt100 would drop $00 and $7f characters here - I drop them later.
*
mx %11 mx %11
phb phb
phk phk
plb plb
lda SCCBREG ; sync
stz SCCBREG stz SCCBREG
lda SCCBREG lda SCCBREG
and #%0000_0001 ; rx ready. and #%0000_0001 ; rx ready.
@ -234,9 +226,9 @@ modem_int
:read :read
lda SCCBDATA lda SCCBDATA
ldx q_tail ldx DPAGE+read_q_head
sta buffer,x sta read_buffer,x
inc q_tail inc DPAGE+read_q_head
* more? * more?
stz SCCBREG stz SCCBREG
@ -263,6 +255,130 @@ modem_int
plb plb
rtl rtl
modem_io ent
debug modem_io
mx %11
php
sei
bit LOCAL
bmi :local
:write
* send any outbound data...
:mask = %0010_0100 ; tx buffer empty, clear to send
ldx write_q_tail
cpx write_q_head
beq :read
lda SCCBREG ; sync
stz SCCBREG
lda SCCBREG
and #:mask
cmp #:mask
bne :read
* ldx write_q_tail
lda write_buffer,x
sta SCCBDATA
inc write_q_tail
:read
ldx read_q_tail
cpx read_q_head
beq :nope
lda read_buffer,x
inc read_q_tail
* $00 and $7f dropped here.
and #$7f
beq :read
cmp #$7f
beq :read
plp
sec
rts
:nope
plp
clc
rts
:local
ldx write_q_tail
cpx write_q_head
beq :nope
lda write_buffer,x
inc write_q_tail
plp
sec
rts
write_modem ent
write_modem_async ent
mx %11
php
sei
* bit LOCAL
* bmi :local
ldx write_q_head
sta write_buffer,x
inc write_q_head
plp
rts
*:local
* ldx read_q_head
* sta read_buffer,x
* inc read_q_head
* plp
* rts
write_modem_str ent
; y = address of string (0-terminated)
; inc write_q_head vs inx
; because it wraps at $ff
mx %10
php
sei
* bit LOCAL
* bmi :local
:loop lda |$0000,y
beq :fini
ldx write_q_head
sta write_buffer,x
inc write_q_head
iny
bra :loop
*:local lda |$0000,y
* beq :fini
* ldx read_q_head
* sta read_buffer,x
* inc read_q_head
* iny
* bra :local
:fini
plp
rts
read_modem ent read_modem ent
read_modem_async ent read_modem_async ent
@ -270,12 +386,12 @@ read_modem_async ent
php php
sei sei
ldx q_head ldx read_q_tail
cpx q_tail cpx read_q_head
beq :nope beq :nope
lda buffer,x lda read_buffer,x
inc q_head inc read_q_tail
plp plp
sec sec
rts rts
@ -285,8 +401,19 @@ read_modem_async ent
clc clc
rts rts
q_head ds 2 reset_modem_buffer ent
q_tail ds 2 mx %11
php
sei
stz read_q_head
stz read_q_tail
stz write_q_head
stz write_q_tail
plp
rts
*buffer ds 256 *buffer ds 256
sav vt100.modem.L sav vt100.modem.L

View File

@ -21,6 +21,17 @@
* cursor_state - $80 = disabled, $40 = on * cursor_state - $80 = disabled, $40 = on
update_sgr ent
stz draw_inverse
lda SGR
beq :rts
lda #$80
sta draw_inverse
:rts rts
text text
dw $0400 dw $0400
@ -100,11 +111,20 @@ cursor_int
mx %11 mx %11
phb
phd
phk
plb
* check if CDA active. * check if CDA active.
* $ff = inactive, $00 = active * $ff = inactive, $00 = active
lda >NumInts lda >NumInts
bpl :rts bpl :rts
pea DPAGE
pld
ldy cursor_offset ldy cursor_offset
lda cursor_state lda cursor_state
@ -125,6 +145,8 @@ cursor_int
sta [cursor_base],y sta [cursor_base],y
:rts stz SCANINT ; reset 1-sec interrupt :rts stz SCANINT ; reset 1-sec interrupt
pld
plb
clc clc
rtl rtl
@ -225,16 +247,20 @@ draw_char ent
bpl :normal bpl :normal
; invert it. ; invert it.
cmp #$60 ; `, first lowercase cmp #$60 ; `, first lowercase
bge :draw ; nothing to do for lowercase bge draw_char_raw ; nothing to do for lowercase
cmp #$40 ; @, first uppercase cmp #$40 ; @, first uppercase
bcc :draw ; nothing to do for special bcc draw_char_raw ; nothing to do for special
:uc and #%10111111 ; ~ $40 :uc and #%10111111 ; ~ $40
bra :draw bra draw_char_raw
:normal ora #$80 :normal ora #$80
:draw
draw_char_raw ent
* entry point for writing character to screen w/o processing it
* sta cursor_saved_char * sta cursor_saved_char
* with DECAWM, x = 79, will CR LF (with scroll) before drawing character. * with DECAWM, x = 79, will CR LF (with scroll) before drawing character.
@ -269,8 +295,6 @@ draw_char ent
rts rts
:wrap :wrap
stz x stz x
ldy y ldy y
@ -284,7 +308,7 @@ draw_char ent
jsr recalc_cursor jsr recalc_cursor
pla pla
sta [cursor_base] ; offset 0 sta [cursor_base] ; offset 0
rts jmp advance_x
:scroll :scroll
pha ; save pha ; save
@ -293,7 +317,7 @@ draw_char ent
jsr recalc_cursor_x jsr recalc_cursor_x
pla pla
sta [cursor_base] ; offset 0 sta [cursor_base] ; offset 0
rts jmp advance_x
* erase screen commands are not affected by origin or scrolling region. * erase screen commands are not affected by origin or scrolling region.