Compare commits
66 Commits
Author | SHA1 | Date |
---|---|---|
Kelvin Sherlock | a687a08b0b | |
Kelvin Sherlock | 90e807ba46 | |
Kelvin Sherlock | 2c432b3fc1 | |
Kelvin Sherlock | dcbafc2999 | |
Kelvin Sherlock | 80edada6e9 | |
Kelvin Sherlock | 04113c4725 | |
Kelvin Sherlock | 1f7e3b3b4c | |
Kelvin Sherlock | 18daf26568 | |
Kelvin Sherlock | 60259531d5 | |
Kelvin Sherlock | 22d1c744bb | |
Kelvin Sherlock | c15ae6ac4c | |
Kelvin Sherlock | 9dfc3cc7c9 | |
Kelvin Sherlock | 71993497ea | |
Kelvin Sherlock | acfe94a4c7 | |
Kelvin Sherlock | 9cf52cb34e | |
Kelvin Sherlock | 186d71de47 | |
Kelvin Sherlock | 4eb578b94e | |
Kelvin Sherlock | c2d3ee0f28 | |
Kelvin Sherlock | 900dccb3d1 | |
Kelvin Sherlock | ea6ee76a9d | |
Kelvin Sherlock | 1cc501e72a | |
Kelvin Sherlock | f486bbfb1b | |
Kelvin Sherlock | 8fa8d8d1fa | |
Kelvin Sherlock | 02c6e1271c | |
Kelvin Sherlock | 279f424cee | |
Kelvin Sherlock | e1639db6e4 | |
Kelvin Sherlock | 6f055a1ef9 | |
Kelvin Sherlock | cd1397e3cf | |
ksherlock | 3e53d52226 | |
Kelvin Sherlock | a4fc8a1a19 | |
Kelvin Sherlock | 260023c33b | |
Kelvin Sherlock | 0d64af63d2 | |
Kelvin Sherlock | c470e945ec | |
Kelvin Sherlock | 77ec62a091 | |
Kelvin Sherlock | 5a1f0f6ffc | |
Kelvin Sherlock | 26ceb7aa50 | |
Kelvin Sherlock | 42d38bfa77 | |
Kelvin Sherlock | f13947a9c2 | |
Kelvin Sherlock | 892aed32f4 | |
Kelvin Sherlock | 31394e84c4 | |
Kelvin Sherlock | 6c8da61822 | |
Kelvin Sherlock | 8d0f3b6496 | |
Kelvin Sherlock | 2ae6964664 | |
Kelvin Sherlock | 2a8a409194 | |
Kelvin Sherlock | 11d62bb333 | |
Kelvin Sherlock | 39429e4e09 | |
Kelvin Sherlock | 9343302f9b | |
Kelvin Sherlock | dbf4e07b95 | |
Kelvin Sherlock | 74d0ee7f07 | |
Kelvin Sherlock | 45aea0293f | |
Kelvin Sherlock | 7fbd54e791 | |
Kelvin Sherlock | 121673badb | |
Kelvin Sherlock | 63cac578bd | |
Kelvin Sherlock | 73722a2c02 | |
Kelvin Sherlock | 1b2ac595d7 | |
Kelvin Sherlock | e9e969a56b | |
Kelvin Sherlock | 6abf2574e3 | |
Kelvin Sherlock | dfdf608018 | |
Kelvin Sherlock | d97b32a699 | |
Kelvin Sherlock | 9c526bd762 | |
Kelvin Sherlock | 6e0de284e0 | |
Kelvin Sherlock | 42bef68d80 | |
Kelvin Sherlock | 073813c199 | |
Kelvin Sherlock | 1eaaf3aaaf | |
Kelvin Sherlock | 492a3bfbec | |
Kelvin Sherlock | dbda9761c5 |
|
@ -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
|
|
@ -0,0 +1,41 @@
|
|||
|
||||
CLR80VID equ $c00c
|
||||
SET80VID equ $c00d
|
||||
CLRALTCHAR equ $c00e
|
||||
SETALTCHAR equ $c00f
|
||||
TXTSET equ $c051
|
||||
KEYMOD equ $c025
|
||||
KEYSTROBE equ $c010
|
||||
KBD equ $c000
|
||||
VGCINT equ $c023
|
||||
SCANINT equ $c032
|
||||
|
||||
RDCARDRAM equ $c003
|
||||
RDMAINRAM equ $c002
|
||||
WRCARDRAM equ $c005
|
||||
WRMAINRAM equ $c004
|
||||
|
||||
* modem port / printer port
|
||||
|
||||
SCCBREG equ $c038
|
||||
SCCAREG equ $c039
|
||||
SCCBDATA equ $c03a
|
||||
SCCADATA equ $c03b
|
||||
|
||||
* Sound GLU
|
||||
SGCONTROL equ $c03c ; Sound GLU control register
|
||||
SGDATA equ $c03d ; Sound GLU data register
|
||||
SGADDRL equ $c03e ; Sound GLU address reg low
|
||||
SGADDRH equ $c03f ; Sound GLU address reg high
|
||||
|
||||
|
||||
* interrupt vectors. JMP ABSLONG.
|
||||
IRQ1SEC equ $e10054
|
||||
IRQMOUSE equ $e10034
|
||||
IRQQTR equ $e10038
|
||||
IRQVBL equ $e10030
|
||||
IRQSND equ $e1002c
|
||||
IRQSCAN equ $e10028
|
||||
IRQSERIAL equ $e10024
|
||||
IRQATALK equ $e10020
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
|
||||
iix qlink vt100.link.S && \
|
||||
profuse -orw vt100.po && \
|
||||
cp vt100.system /Volumes/vt100/vt100.system \
|
||||
&& umount /Volumes/vt100
|
|
@ -0,0 +1,198 @@
|
|||
|
||||
rel
|
||||
mx %11
|
||||
|
||||
ent erase_line
|
||||
ent erase_line_0
|
||||
ent erase_line_1
|
||||
ent erase_line_2
|
||||
|
||||
erase_line
|
||||
; a = 0 - erase x - eol (inclusive)
|
||||
; a = 1 - erase 0 - x (inclusive)
|
||||
; a = 2 - erase 0 - eol
|
||||
cmp #2
|
||||
bcs :rts
|
||||
asl
|
||||
tax
|
||||
jmp (:table,x)
|
||||
:rts rts
|
||||
|
||||
:table
|
||||
dw erase_line_0
|
||||
dw erase_line_1
|
||||
dw erase_line_2
|
||||
|
||||
erase_line_2
|
||||
* erase entire line.
|
||||
php
|
||||
rep #$30
|
||||
ldy #38
|
||||
lda #" "
|
||||
:loop
|
||||
sta [text01],y
|
||||
sta (text00),y
|
||||
dey
|
||||
dey
|
||||
bpl :loop
|
||||
plp
|
||||
rts
|
||||
|
||||
mx %11
|
||||
|
||||
erase_line_0
|
||||
* erase to eol
|
||||
|
||||
lda x
|
||||
lsr
|
||||
tay
|
||||
lda #" "
|
||||
bcs :half
|
||||
:loop
|
||||
sta [text01],y
|
||||
:half sta (text00),y
|
||||
iny
|
||||
cpy #40
|
||||
bcc :loop
|
||||
rts
|
||||
|
||||
erase_line_1
|
||||
* erase to x (inclusive)
|
||||
|
||||
lda x
|
||||
lsr
|
||||
tay
|
||||
lda #" "
|
||||
bcc :half
|
||||
|
||||
:loop
|
||||
sta (text00),y
|
||||
:half sta [text01],y
|
||||
dey
|
||||
bpl :loop
|
||||
rts
|
||||
|
||||
|
||||
erase_screen ent
|
||||
; a = 0 - erase [cursor, end] (inclusive)
|
||||
; a = 1 - erase [start, cursor] (inclusive)
|
||||
; a = 2 - erase [start, end]
|
||||
cmp #2
|
||||
bcs :rts
|
||||
asl
|
||||
tax
|
||||
jmp (:table,x)
|
||||
:rts rts
|
||||
|
||||
:table
|
||||
dw erase_screen_0
|
||||
dw erase_screen_1
|
||||
dw erase_screen_2
|
||||
|
||||
erase_screen_2 ent
|
||||
* erase the entire screen.
|
||||
php
|
||||
rep #$30
|
||||
lda #" " ; high bit set.
|
||||
|
||||
c00 cc $0400
|
||||
c01 cc $0480
|
||||
c02 cc $0500
|
||||
c03 cc $0580
|
||||
c04 cc $0600
|
||||
c05 cc $0680
|
||||
c06 cc $0700
|
||||
c07 cc $0780
|
||||
c08 cc $0428
|
||||
c09 cc $04a8
|
||||
c10 cc $0528
|
||||
c11 cc $05a8
|
||||
c12 cc $0628
|
||||
c13 cc $06a8
|
||||
c14 cc $0728
|
||||
c15 cc $07a8
|
||||
c16 cc $0450
|
||||
c17 cc $04d0
|
||||
c18 cc $0550
|
||||
c19 cc $05d0
|
||||
c20 cc $0650
|
||||
c21 cc $06d0
|
||||
c22 cc $0750
|
||||
c23 cc $07d0
|
||||
plp
|
||||
rts
|
||||
|
||||
mx %11
|
||||
|
||||
erase_screen_0 ent
|
||||
* erase from cursor to the end.
|
||||
mx %11
|
||||
ldx #0 ; for jmp (,x)
|
||||
lda x
|
||||
ora y
|
||||
beq :all
|
||||
|
||||
lda x
|
||||
beq :x0
|
||||
jsr erase_line_0
|
||||
lda y
|
||||
inc
|
||||
bra :x1
|
||||
:x0
|
||||
lda y
|
||||
:x1 cmp #23
|
||||
bcs :rts
|
||||
asl
|
||||
tax
|
||||
:all php ; clear_table will plp.
|
||||
rep #$30
|
||||
lda #" "
|
||||
jmp (clear_table,x)
|
||||
|
||||
:rts rts
|
||||
|
||||
|
||||
erase_screen_1 ent
|
||||
* erase from start to cursor.
|
||||
jsr erase_line_1
|
||||
lda y
|
||||
bne :ok
|
||||
rts
|
||||
:ok
|
||||
php
|
||||
rep #$30
|
||||
lda y
|
||||
dey
|
||||
asl
|
||||
tax
|
||||
lda #" "
|
||||
jmp (:clear_table,x)
|
||||
:clear_table
|
||||
|
||||
|
||||
c23 cc $07d0
|
||||
c22 cc $0750
|
||||
c21 cc $06d0
|
||||
c20 cc $0650
|
||||
c19 cc $05d0
|
||||
c18 cc $0550
|
||||
c17 cc $04d0
|
||||
c16 cc $0450
|
||||
c15 cc $07a8
|
||||
c14 cc $0728
|
||||
c13 cc $06a8
|
||||
c12 cc $0628
|
||||
c11 cc $05a8
|
||||
c10 cc $0528
|
||||
c09 cc $04a8
|
||||
c08 cc $0428
|
||||
c07 cc $0780
|
||||
c06 cc $0700
|
||||
c05 cc $0680
|
||||
c04 cc $0600
|
||||
c03 cc $0580
|
||||
c02 cc $0500
|
||||
c01 cc $0480
|
||||
c00 cc $0400
|
||||
plp
|
||||
rts
|
|
@ -0,0 +1,95 @@
|
|||
|
||||
|
||||
import sys
|
||||
|
||||
|
||||
special = {
|
||||
}
|
||||
for x in range(0,0x20): special[chr(x)] = '^' + chr(0x40 + x)
|
||||
|
||||
cmap = {
|
||||
'\'': '\'',
|
||||
'\"': '\"',
|
||||
'?': '?',
|
||||
'\\': '\\',
|
||||
'a': '\a',
|
||||
'b': '\b',
|
||||
'f': '\f',
|
||||
'n': '\n',
|
||||
'r': '\r',
|
||||
't': '\t',
|
||||
'v': '\v',
|
||||
}
|
||||
|
||||
|
||||
|
||||
argv = sys.argv[1:]
|
||||
|
||||
chars = []
|
||||
for arg in argv:
|
||||
|
||||
if arg == "--ctrl":
|
||||
for c in range(0,32):
|
||||
chars.append(chr(c))
|
||||
continue
|
||||
|
||||
if arg == "--upper":
|
||||
for c in range(ord('A'), ord('Z')+1):
|
||||
chars.append(chr(c))
|
||||
continue
|
||||
|
||||
if arg == "--lower":
|
||||
for c in range(ord('a'), ord('z')+1):
|
||||
chars.append(chr(c))
|
||||
continue
|
||||
|
||||
if arg == "--digit":
|
||||
for c in range(ord('0'), ord('9')+1):
|
||||
chars.append(chr(c))
|
||||
continue
|
||||
|
||||
|
||||
# ^X is a control character
|
||||
if len(arg) == 2 and arg[0] == '^':
|
||||
c = chr(ord(arg[1]) & 0x1f)
|
||||
chars.append(c)
|
||||
continue
|
||||
# \X is an escaped character
|
||||
if len(arg) == 2 and arg[0] == '\\':
|
||||
c = arg[1]
|
||||
if c in cmap: chars.append(cmap[c])
|
||||
continue
|
||||
|
||||
# X-Y is a range of characters.
|
||||
if len(arg) == 4 and arg[1] == '-':
|
||||
a = arg[0]
|
||||
b = arg[2]
|
||||
for c in range(ord(a),ord(b)+1):
|
||||
chars.append(chr(c))
|
||||
continue
|
||||
|
||||
chars.extend(arg)
|
||||
|
||||
chars = list(set(chars))
|
||||
chars.sort()
|
||||
|
||||
if not chars: exit(1)
|
||||
|
||||
mmin = ord(chars[0])
|
||||
mmax = ord(chars[-1])
|
||||
|
||||
print(":MIN\tequ {}".format(mmin))
|
||||
print(":MAX\tequ {}".format(mmax))
|
||||
print()
|
||||
|
||||
|
||||
|
||||
|
||||
print(":table")
|
||||
for x in range(mmin, mmax+1):
|
||||
c = chr(x)
|
||||
print("\tdw $0\t; {}".format(special.get(c, c)))
|
||||
|
||||
# for c in chars:
|
||||
# x = ord(c)
|
||||
# print("\tdw $0\t; {}".format(special.get(c, c)))
|
|
@ -0,0 +1,100 @@
|
|||
|
||||
cas se
|
||||
|
||||
|
||||
st_vt52 equ 0
|
||||
st_vt52_esc equ 2
|
||||
st_vt52_dca equ 4
|
||||
st_vt100 equ 6
|
||||
st_vt100_esc equ 8
|
||||
st_vt100_csi equ 10
|
||||
st_vt100_csi_2 equ 12
|
||||
st_vt100_esc_pound equ 14 ; #
|
||||
st_vt100_esc_lparen equ 16 ; (
|
||||
st_vt100_esc_rparen equ 18 ; )
|
||||
|
||||
st_vt100_esc_bad equ 20
|
||||
st_vt100_csi_bad equ 22
|
||||
|
||||
ESC equ $1b
|
||||
|
||||
DPAGE equ $1f00
|
||||
|
||||
dum 0
|
||||
state ds 2
|
||||
x ds 2
|
||||
y ds 2
|
||||
|
||||
DECTM ds 2 ; top margin
|
||||
DECBM ds 2 ; bottom margin
|
||||
|
||||
LOCAL ds 2 ; local mode
|
||||
DECANM ds 2 ; ansi/vt52
|
||||
DECKPAM ds 2 ; alternate keypad
|
||||
DECCKM ds 2 ; cursor key modes
|
||||
DECOM ds 2 ; origin
|
||||
DECSCNM ds 2 ; screen mode
|
||||
DECAWM ds 2 ; wrap
|
||||
DECARM ds 2 ; auto repeat
|
||||
DECCOLM ds 2 ; character per line (80/132)
|
||||
|
||||
|
||||
LNM ds 2 ; new line
|
||||
SGR ds 2 ; graphics, bit 1 = bold, 4 = underscore, 5 = blink, 7 = inverse
|
||||
|
||||
* not supported
|
||||
|
||||
*CHARSET ds 2 ;
|
||||
*GRAPHICS ds 2 ;
|
||||
|
||||
*DECINLM ds 2 ; interlace
|
||||
*DECSCLM ds 2 ; scroll mode
|
||||
|
||||
* DECDHL - double height line
|
||||
* DECDWL - double width line
|
||||
|
||||
|
||||
* parameters
|
||||
MAX_PCOUNT equ 8
|
||||
pcount ds 2
|
||||
parms ds MAX_PCOUNT
|
||||
pmod ds 2
|
||||
|
||||
; scratch registers
|
||||
r0 ds 2
|
||||
|
||||
|
||||
cursor_saved_char ds 2 ; saved char under the cursor
|
||||
cursor_base ds 4
|
||||
cursor_offset ds 2
|
||||
cursor_char ds 2 ; cursor character
|
||||
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
|
||||
|
||||
|
||||
* saved cursor
|
||||
saved_x 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
|
||||
err "too big"
|
||||
fin
|
||||
dend
|
|
@ -0,0 +1,177 @@
|
|||
|
||||
|
||||
|
||||
vt100
|
||||
mx %11
|
||||
and #$7f
|
||||
cmp #' '
|
||||
bcs :notctrl
|
||||
asl
|
||||
tax
|
||||
jmp (ctrl,x)
|
||||
:notctrl
|
||||
ldx state
|
||||
jmp (:state_table,x)
|
||||
|
||||
|
||||
|
||||
:state_table
|
||||
ext vt52_esc,vt52_dca
|
||||
ext vt100_esc,vt100_csi,vt100_csi_2
|
||||
ext vt100_esc_pound,vt100_esc_lparen,vt100_esc_rparen
|
||||
|
||||
dw char
|
||||
dw vt52_esc
|
||||
dw vt52_dca
|
||||
dw char
|
||||
dw vt100_esc
|
||||
dw vt100_csi
|
||||
dw vt100_csi_2
|
||||
dw vt100_esc_pound
|
||||
dw vt100_esc_lparen
|
||||
dw vt100_esc_rparen
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
vt100_csi_bad ent
|
||||
cmp #'@'
|
||||
blt :rts
|
||||
ldx #st_vt100
|
||||
stx state
|
||||
:rts rts
|
||||
|
||||
|
||||
|
||||
|
||||
esc_csi
|
||||
stz pcount
|
||||
stz params
|
||||
stz params+1
|
||||
stz csi_private
|
||||
lda #st_csi
|
||||
sta state
|
||||
rts
|
||||
|
||||
|
||||
csi
|
||||
inc state
|
||||
inc state
|
||||
cmp #'?'
|
||||
bne csi0
|
||||
lda #$80
|
||||
sta csi_private
|
||||
rts
|
||||
|
||||
csi0
|
||||
cmp #';'
|
||||
beq :semi
|
||||
cmp #'0'
|
||||
bcc csi_final
|
||||
cmp #'9'+1
|
||||
bcs csi_final
|
||||
:num
|
||||
and #$0f ; 0-9
|
||||
tay ; save
|
||||
ldx pcount
|
||||
lda params,x
|
||||
asl ; x 2
|
||||
sta params,x
|
||||
asl ; x 4
|
||||
asl ; x 8
|
||||
clc
|
||||
adc params,x
|
||||
sta params,x
|
||||
tya
|
||||
clc
|
||||
adc params,x
|
||||
sta params,x
|
||||
rts
|
||||
|
||||
|
||||
:semi
|
||||
ldx pcount
|
||||
inx
|
||||
cpx #MAX_PCOUNT
|
||||
bcs :srts
|
||||
stx pcount
|
||||
stz params,x
|
||||
|
||||
:srts
|
||||
rts
|
||||
|
||||
|
||||
csi_final
|
||||
* c, h, l have private modes.
|
||||
bit csi_private
|
||||
bmi :priv
|
||||
|
||||
cmp #:MIN_FINAL
|
||||
bcc :rts
|
||||
cmp #:MAX_FINAL+1
|
||||
bcs :rts
|
||||
asl
|
||||
tax
|
||||
jmp (:table,x)
|
||||
:rts rts
|
||||
|
||||
:priv
|
||||
cmp #:MIN_FINAL_PRIV
|
||||
bcc :rts
|
||||
cmp #:MAX_FINAL_PRIV+1
|
||||
bcs :rts
|
||||
asl
|
||||
tax
|
||||
jmp (:table_priv,x)
|
||||
|
||||
|
||||
csi
|
||||
*
|
||||
* ESC [ encountered.
|
||||
*
|
||||
* ? -> DEC private
|
||||
* 0-9 -> parameter value
|
||||
* ; parameter delim
|
||||
* other - final character.
|
||||
|
||||
cmp #'0'
|
||||
blt :notnum
|
||||
cmp #'9'+1
|
||||
bge :notnum
|
||||
|
||||
sep #$30
|
||||
and #$0f
|
||||
tay
|
||||
ldx pcount
|
||||
lda parms,x
|
||||
asl
|
||||
pha
|
||||
asl
|
||||
asl
|
||||
clc
|
||||
adc 1,s
|
||||
sta 1,s
|
||||
tya
|
||||
adc 1,s
|
||||
ply
|
||||
sta parms,x
|
||||
sep #$30
|
||||
]rts rts
|
||||
:notnum
|
||||
cmp #';'
|
||||
bne :notsemi
|
||||
ldx pcount
|
||||
cpx #MAXPCOUNT
|
||||
bge ]rts
|
||||
inx
|
||||
stx pcount
|
||||
stz parms,
|
||||
stz parms+1,x
|
||||
]rts rts
|
||||
:notsemi
|
||||
cmp #'?'
|
||||
bne :final
|
||||
sta ptype
|
||||
rts
|
||||
:final
|
|
@ -0,0 +1,199 @@
|
|||
|
||||
lst off
|
||||
cas se
|
||||
|
||||
rel
|
||||
xc
|
||||
xc
|
||||
|
||||
use apple2gs.equ
|
||||
|
||||
|
||||
mx %11
|
||||
|
||||
|
||||
|
||||
*
|
||||
*
|
||||
* keypress @ 44.1 - 28 samples of $40, 29 samples of $b0
|
||||
*
|
||||
* beep - repeat keypress 53 times
|
||||
*
|
||||
* by adjusting rate, only need 1 sample each.
|
||||
*
|
||||
* w/ 2 oscillators, scan rate = 223.7 kHz ~5x 44.1
|
||||
* 28 samples * 5 = 142
|
||||
* res = 7. (1 << 16) / 142 = ~ 461
|
||||
* freq = 461, res = 7, wave size = 256 --> n * 461 >> 16
|
||||
*
|
||||
*
|
||||
|
||||
|
||||
*
|
||||
* vt52
|
||||
* keypress - ~730 samples, $40, curve to 0 or $b0, curve to 0
|
||||
* beep 14 keypresses
|
||||
*
|
||||
*
|
||||
|
||||
|
||||
bic mac
|
||||
if #=]1
|
||||
and ]1!$ffff
|
||||
else
|
||||
err 1 ; immediate only.
|
||||
fin
|
||||
<<<
|
||||
|
||||
docwait mac
|
||||
if MX<2
|
||||
err 1 ; 8-bit m only
|
||||
fin
|
||||
wait lda SGCONTROL
|
||||
bmi wait
|
||||
<<<
|
||||
|
||||
docmode mac
|
||||
docwait
|
||||
bic #%01000000 ; DOC mode
|
||||
ora #%00100000 ; auto-incr
|
||||
ora #%0000_1111 ; max volume.
|
||||
sta SGCONTROL
|
||||
<<<
|
||||
|
||||
rammode mac
|
||||
docwait
|
||||
ora #%01100000 ; RAM mode, auto-incr
|
||||
sta SGCONTROL
|
||||
<<<
|
||||
|
||||
|
||||
init_audio ent
|
||||
|
||||
docmode
|
||||
|
||||
* 4 oscillators. -- (2 for key, 2 for beep -- stereo!)
|
||||
lda #$e1
|
||||
sta SGADDRL
|
||||
|
||||
lda #4*2
|
||||
sta SGDATA
|
||||
|
||||
* control registers
|
||||
* just set them off. channels will be set when they fire.
|
||||
|
||||
lda #$a0
|
||||
sta SGADDRL
|
||||
lda #%0000_0_01_1 ; ch 0, interrupts off, 1-shot, halted.
|
||||
sta SGDATA
|
||||
sta SGDATA
|
||||
sta SGDATA
|
||||
sta SGDATA
|
||||
|
||||
|
||||
|
||||
* freq low
|
||||
lda #$00
|
||||
sta SGADDRL
|
||||
lda #<650
|
||||
sta SGDATA
|
||||
sta SGDATA
|
||||
sta SGDATA
|
||||
sta SGDATA
|
||||
|
||||
* freq high
|
||||
lda #$20
|
||||
sta SGADDRL
|
||||
lda #>650
|
||||
sta SGDATA
|
||||
sta SGDATA
|
||||
sta SGDATA
|
||||
sta SGDATA
|
||||
|
||||
* volume
|
||||
lda #$40
|
||||
sta SGADDRL
|
||||
lda #$ff
|
||||
sta SGDATA
|
||||
sta SGDATA
|
||||
sta SGDATA
|
||||
sta SGDATA
|
||||
|
||||
* wave table
|
||||
lda #$80
|
||||
sta SGADDRL
|
||||
lda #0 ; page 0
|
||||
sta SGDATA
|
||||
sta SGDATA
|
||||
inc ; page 1
|
||||
sta SGDATA
|
||||
sta SGDATA
|
||||
|
||||
|
||||
|
||||
* wave table size
|
||||
lda #$c0
|
||||
sta SGADDRL
|
||||
lda #%00_000_111 ; 256 bytes, 16-bit shift
|
||||
sta SGDATA
|
||||
sta SGDATA
|
||||
sta SGDATA
|
||||
sta SGDATA
|
||||
|
||||
|
||||
; now copy the data....
|
||||
rammode
|
||||
stz SGADDRL
|
||||
stz SGADDRH
|
||||
|
||||
ldy #key_size
|
||||
ldx #0
|
||||
]loop lda key_data,x
|
||||
sta SGDATA
|
||||
inx
|
||||
dey
|
||||
bpl ]loop
|
||||
|
||||
stz SGADDRL
|
||||
lda #1
|
||||
sta SGADDRH
|
||||
ldy #beep_size
|
||||
ldx #0
|
||||
]loop lda beep_data,x
|
||||
sta SGDATA
|
||||
inx
|
||||
dey
|
||||
bpl ]loop
|
||||
|
||||
rts
|
||||
|
||||
|
||||
beep ent
|
||||
; fire osc 2 + 3
|
||||
docmode
|
||||
|
||||
lda #$a0+2
|
||||
sta SGADDRL
|
||||
lda #%0000_0_01_0 ; ch 0, interrupts off, 1-shot, running.
|
||||
ldx #%0001_0_01_0 ; ch 1, interrupts off, 1-shot, running.
|
||||
sta SGDATA
|
||||
stx SGDATA
|
||||
|
||||
rts
|
||||
|
||||
|
||||
key_data
|
||||
db $01
|
||||
db $ff
|
||||
db $00
|
||||
key_size equ *-key_data
|
||||
|
||||
beep_data
|
||||
lup 53
|
||||
db $01
|
||||
db $ff
|
||||
--^
|
||||
db $0
|
||||
beep_size equ *-beep_data
|
||||
|
||||
sav vt100.beep.L
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,899 @@
|
|||
|
||||
|
||||
lst off
|
||||
cas se
|
||||
|
||||
rel
|
||||
xc
|
||||
xc
|
||||
|
||||
use vt.equ
|
||||
use debug
|
||||
|
||||
mx %11
|
||||
|
||||
ext reset_tab,reset_all_tabs
|
||||
ext recalc_cursor,recalc_cursor_x,recalc_cursor_y
|
||||
ext erase_line_0,erase_line_1,erase_line_2
|
||||
ext erase_screen_0,erase_screen_1,erase_screen_2
|
||||
ext update_sgr
|
||||
|
||||
ext write_modem,write_modem_str
|
||||
|
||||
|
||||
vt100_csi ent
|
||||
debug vt100_csi
|
||||
|
||||
* 0123456789;ycnlhgrqJKmABCDHf
|
||||
|
||||
* based on testing -
|
||||
* everything except '0' - '?' and control chars
|
||||
* will finish.
|
||||
* '?' only matters for h/l
|
||||
* a misplaced ? (or anything in '0' - '?', except 0-9;)
|
||||
* will cancel the sequence AFTER it's finished.
|
||||
* < = > ? are allowed as an initial modifier but only '?' is private
|
||||
* a mis-placed < = > ? will prevent 0x20-0x2f from terminating the sequence.
|
||||
|
||||
|
||||
ldx #st_vt100
|
||||
stx state
|
||||
|
||||
stz pcount
|
||||
stz parms
|
||||
stz parms+1 ; some assume 2 parms.
|
||||
stz pmod
|
||||
|
||||
* tay ; save for modifier
|
||||
cmp #:MIN
|
||||
blt :rts
|
||||
cmp #:MAX+1
|
||||
bge :rts
|
||||
sec
|
||||
sbc #:MIN
|
||||
asl
|
||||
tax
|
||||
jmp (:table,x)
|
||||
|
||||
*
|
||||
:rts rts
|
||||
|
||||
|
||||
|
||||
:MIN equ 48
|
||||
:MAX equ 121
|
||||
:table
|
||||
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 digit ; :
|
||||
dw semi
|
||||
dw :xmod ; <
|
||||
dw :xmod ; =
|
||||
dw :xmod ; >
|
||||
dw :modifier ; ?
|
||||
dw :rts ; @
|
||||
dw csi_A ; A
|
||||
dw csi_B ; B
|
||||
dw csi_C ; C
|
||||
dw csi_D ; D
|
||||
dw :rts ; E
|
||||
dw :rts ; F
|
||||
dw :rts ; G
|
||||
dw csi_H ; H
|
||||
dw :rts ; I
|
||||
dw csi_J ; J
|
||||
dw csi_K ; K
|
||||
dw :rts ; L
|
||||
dw :rts ; 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 :rts ; [
|
||||
dw :rts ; \
|
||||
dw :rts ; ]
|
||||
dw :rts ; ^
|
||||
dw :rts ; _
|
||||
dw :rts ; `
|
||||
dw :rts ; a
|
||||
dw :rts ; b
|
||||
dw csi_c ; c
|
||||
dw :rts ; d
|
||||
dw :rts ; e
|
||||
dw csi_f ; f
|
||||
dw csi_g ; g
|
||||
dw csi_h ; h
|
||||
dw :rts ; i
|
||||
dw :rts ; j
|
||||
dw :rts ; k
|
||||
dw csi_l ; l
|
||||
dw csi_m ; m
|
||||
dw csi_n ; n
|
||||
dw :rts ; o
|
||||
dw :rts ; p
|
||||
dw csi_q ; q
|
||||
dw csi_r ; r
|
||||
dw :rts ; s
|
||||
dw :rts ; t
|
||||
dw :rts ; u
|
||||
dw :rts ; v
|
||||
dw :rts ; w
|
||||
dw :rts ; x
|
||||
dw csi_y ; y
|
||||
|
||||
|
||||
:digit
|
||||
ldx #st_vt100_csi_2
|
||||
stx state
|
||||
|
||||
lsr ; undo asl
|
||||
sta parms
|
||||
rts
|
||||
:modifier
|
||||
ldx #st_vt100_csi_2
|
||||
stx state
|
||||
|
||||
lda #$80
|
||||
sta pmod
|
||||
rts
|
||||
|
||||
:xmod
|
||||
* ignored.
|
||||
ldx #st_vt100_csi_2
|
||||
stx state
|
||||
rts
|
||||
|
||||
vt100_csi_bad ent
|
||||
cmp #'@'
|
||||
blt :rts
|
||||
ldx #st_vt100
|
||||
stx state
|
||||
:rts rts
|
||||
|
||||
|
||||
|
||||
vt100_csi_2 ent
|
||||
debug vt100_csi_2
|
||||
|
||||
ldx #st_vt100
|
||||
stx state
|
||||
|
||||
cmp #:MIN
|
||||
blt :rts
|
||||
cmp #:MAX+1
|
||||
bge :rts
|
||||
sec
|
||||
sbc #:MIN
|
||||
asl
|
||||
tax
|
||||
jmp (:table,x)
|
||||
|
||||
:rts rts
|
||||
|
||||
:MIN equ 48
|
||||
:MAX equ 121
|
||||
:table
|
||||
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 digit ; :
|
||||
dw semi
|
||||
dw :modifier ; <
|
||||
dw :modifier ; =
|
||||
dw :modifier ; >
|
||||
dw :modifier ; ?
|
||||
dw :rts ; @
|
||||
dw csi_A ; A
|
||||
dw csi_B ; B
|
||||
dw csi_C ; C
|
||||
dw csi_D ; D
|
||||
dw :rts ; E
|
||||
dw :rts ; F
|
||||
dw :rts ; G
|
||||
dw csi_H ; H
|
||||
dw :rts ; I
|
||||
dw csi_J ; J
|
||||
dw csi_K ; K
|
||||
dw :rts ; L
|
||||
dw :rts ; 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 :rts ; [
|
||||
dw :rts ; \
|
||||
dw :rts ; ]
|
||||
dw :rts ; ^
|
||||
dw :rts ; _
|
||||
dw :rts ; `
|
||||
dw :rts ; a
|
||||
dw :rts ; b
|
||||
dw csi_c ; c
|
||||
dw :rts ; d
|
||||
dw :rts ; e
|
||||
dw csi_f ; f
|
||||
dw csi_g ; g
|
||||
dw csi_h ; h
|
||||
dw :rts ; i
|
||||
dw :rts ; j
|
||||
dw :rts ; k
|
||||
dw csi_l ; l
|
||||
dw csi_m ; m
|
||||
dw csi_n ; n
|
||||
dw :rts ; o
|
||||
dw :rts ; p
|
||||
dw csi_q ; q
|
||||
dw csi_r ; r
|
||||
dw :rts ; s
|
||||
dw :rts ; t
|
||||
dw :rts ; u
|
||||
dw :rts ; v
|
||||
dw :rts ; w
|
||||
dw csi_x ; x
|
||||
dw csi_y ; y
|
||||
|
||||
:modifier
|
||||
ldx #st_vt100_csi_bad
|
||||
stx state
|
||||
rts
|
||||
|
||||
semi
|
||||
ldx #st_vt100_csi_2
|
||||
stx state
|
||||
|
||||
ldx pcount
|
||||
cpx #MAX_PCOUNT
|
||||
bge :big
|
||||
|
||||
inx
|
||||
stx pcount
|
||||
:big stz parms,x
|
||||
:rts rts
|
||||
|
||||
* parameter digit. clamped to 255 (250+ rounds up to 255)
|
||||
* in 132 is the largest valid parameter so this is ok.
|
||||
digit
|
||||
ldx #st_vt100_csi_2
|
||||
stx state
|
||||
|
||||
lsr ; undo asl
|
||||
sta r0
|
||||
ldx pcount
|
||||
lda parms,x
|
||||
* cmp #255
|
||||
* beq :rts
|
||||
cmp #25
|
||||
bge :v
|
||||
|
||||
tay
|
||||
lda :mult,y
|
||||
* clc ; cleared via cmp
|
||||
adc r0
|
||||
sta parms,x
|
||||
|
||||
|
||||
:rts
|
||||
rts
|
||||
:v
|
||||
lda #$255
|
||||
sta parms,x
|
||||
rts
|
||||
|
||||
:mult db 0,10,20,30,40,50,60,70,80,90
|
||||
db 100,110,120,130,140,150,160,170,180,190
|
||||
db 200,210,220,230,240,250
|
||||
|
||||
|
||||
|
||||
csi_h
|
||||
; esc [ ... h (vt100)
|
||||
; esc [ ? ... h (private)
|
||||
ldy #$80
|
||||
bra mode_common
|
||||
|
||||
csi_l
|
||||
; esc [ ... l (vt100)
|
||||
; esc [ ? ... l (private)
|
||||
ldy #0
|
||||
|
||||
mode_common
|
||||
inc pcount
|
||||
ldx #0
|
||||
:loop lda parms,x
|
||||
cmp #:MIN
|
||||
blt :next
|
||||
cmp #:MAX+1
|
||||
bge :next
|
||||
phx
|
||||
asl
|
||||
tax
|
||||
jsr (:table,x)
|
||||
plx
|
||||
|
||||
:next inx
|
||||
cpx pcount
|
||||
blt :loop
|
||||
:rts rts
|
||||
|
||||
:MIN equ 0
|
||||
:MAX equ 20
|
||||
:table
|
||||
dw :rts ; error
|
||||
dw mode_DECCKM
|
||||
dw mode_DECANM
|
||||
dw mode_DECCOLM ; DECCOLM
|
||||
dw :rts ; DECSCLM
|
||||
dw mode_DECSCNM
|
||||
dw mode_DECOM
|
||||
dw mode_DECAWM
|
||||
dw mode_DECARM
|
||||
dw :rts ; DECINLM
|
||||
dw :rts ; 10
|
||||
dw :rts ; 11
|
||||
dw :rts ; 12
|
||||
dw :rts ; 13
|
||||
dw :rts ; 14
|
||||
dw :rts ; 15
|
||||
dw :rts ; 16
|
||||
dw :rts ; 17
|
||||
dw :rts ; 18
|
||||
dw :rts ; 19
|
||||
dw mode_LNM
|
||||
*:mask dw 0,$40,$40,$40,$40,$40,$40,$40,$40,$40
|
||||
* dw 0,0,0,0,0,0,0,0,0,0,0
|
||||
|
||||
|
||||
mode_DECCKM
|
||||
bit pmod
|
||||
bpl :rts
|
||||
|
||||
sty DECCKM
|
||||
:rts rts
|
||||
|
||||
mode_DECANM
|
||||
bit pmod
|
||||
bpl :rts
|
||||
|
||||
sty DECANM
|
||||
cpy #0
|
||||
bne :rts
|
||||
* switch to vt52 mode
|
||||
ldx #st_vt52
|
||||
stx state
|
||||
:rts rts
|
||||
|
||||
|
||||
mode_DECCOLM
|
||||
* 80/132 mode.
|
||||
* 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
|
||||
bit pmod
|
||||
bpl :rts
|
||||
|
||||
* todo - invert on-screen characters?
|
||||
sty DECSCNM
|
||||
:rts rts
|
||||
|
||||
mode_DECOM
|
||||
bit pmod
|
||||
bpl :rts
|
||||
|
||||
sty DECOM
|
||||
; move to the new home position
|
||||
stz x
|
||||
stz y
|
||||
cpy #0
|
||||
beq :rts
|
||||
lda DECTM
|
||||
sta y
|
||||
|
||||
phy
|
||||
jsr recalc_cursor
|
||||
ply
|
||||
|
||||
:rts rts
|
||||
|
||||
mode_DECAWM
|
||||
bit pmod
|
||||
bpl :rts
|
||||
|
||||
sty DECAWM
|
||||
:rts rts
|
||||
|
||||
mode_DECARM
|
||||
bit pmod
|
||||
bpl :rts
|
||||
|
||||
sty DECARM
|
||||
:rts rts
|
||||
|
||||
mode_LNM
|
||||
bit pmod
|
||||
bmi :rts
|
||||
|
||||
sty LNM
|
||||
:rts rts
|
||||
|
||||
|
||||
csi_m
|
||||
* esc [ ... m
|
||||
* 0 - attributes off
|
||||
* 1 - bold
|
||||
* 4 - underscore
|
||||
* 5 - blink
|
||||
* 7 - inverted
|
||||
|
||||
inc pcount
|
||||
ldx #0
|
||||
:loop lda parms,x
|
||||
cmp #8
|
||||
bge :next
|
||||
tay
|
||||
lda SGR
|
||||
and :and,y
|
||||
ora :or,y
|
||||
sta SGR
|
||||
|
||||
:next inx
|
||||
cpx pcount
|
||||
blt :loop
|
||||
|
||||
jmp update_sgr
|
||||
|
||||
|
||||
|
||||
:and db $00,$ff,$ff,$ff,$ff,$ff,$ff,$ff
|
||||
|
||||
:or db %0000_0000,%0000_0010,%0000_0000,%0000_0000
|
||||
db %0001_0000,%0010_0000,%0000_0000,%1000_0000
|
||||
|
||||
|
||||
|
||||
csi_g
|
||||
* ESC [ g, ESC [ 0 g - clear tab at column
|
||||
* ESC [ 3 g - clear all tabs
|
||||
|
||||
lda parms
|
||||
beq :0
|
||||
cmp #3
|
||||
beq :3
|
||||
rts
|
||||
|
||||
:0 ldx x
|
||||
jmp reset_tab
|
||||
:3 jmp reset_all_tabs
|
||||
|
||||
|
||||
p1 mac
|
||||
lda parms
|
||||
bne ok
|
||||
lda #1
|
||||
ok sta parms
|
||||
<<<
|
||||
|
||||
* cursor movement.
|
||||
* if private mode, no effect.
|
||||
csi_A
|
||||
* up
|
||||
|
||||
* if cursor is outside the scrolling region, it is not locked to the scrolling region.
|
||||
|
||||
bit pmod
|
||||
bmi :rts
|
||||
|
||||
p1
|
||||
|
||||
lda y
|
||||
cmp DECTM
|
||||
beq :rts
|
||||
bcc :simple
|
||||
|
||||
sec
|
||||
sbc parms
|
||||
bcc :top
|
||||
cmp DECTM
|
||||
* bcc :top
|
||||
* bra :sta
|
||||
bcs :sta
|
||||
|
||||
:top lda DECTM
|
||||
bra :sta
|
||||
:rts rts
|
||||
|
||||
|
||||
:simple
|
||||
* lda y
|
||||
sec
|
||||
sbc parms
|
||||
* bcc :0 ; clear indicate underflow.
|
||||
bcc :sta
|
||||
:0 lda #0
|
||||
:sta sta y
|
||||
jmp recalc_cursor_y
|
||||
|
||||
csi_B
|
||||
* down
|
||||
|
||||
bit pmod
|
||||
bmi :rts
|
||||
|
||||
p1
|
||||
|
||||
lda y
|
||||
cmp DECBM
|
||||
beq :rts
|
||||
bge :simple
|
||||
|
||||
clc
|
||||
adc parms
|
||||
bcs :bottom ; overflow
|
||||
cmp DECBM
|
||||
bcc :sta
|
||||
|
||||
:bottom lda DECBM
|
||||
bra :sta
|
||||
:rts rts
|
||||
|
||||
:simple
|
||||
clc
|
||||
adc parms
|
||||
bcs :23 ; overflow
|
||||
cmp #24
|
||||
bcc :sta
|
||||
|
||||
:23 lda #23
|
||||
:sta sta y
|
||||
jmp recalc_cursor_y
|
||||
|
||||
csi_C
|
||||
* right
|
||||
* in column 80, no effect.
|
||||
|
||||
bit pmod
|
||||
bmi :rts
|
||||
|
||||
lda x
|
||||
cmp #79
|
||||
bcs :rts
|
||||
|
||||
p1
|
||||
lda x
|
||||
* and #$7f
|
||||
|
||||
clc
|
||||
adc parms
|
||||
bcs :79 ; overflow
|
||||
cmp #80
|
||||
bcc :sta
|
||||
|
||||
:79 lda #79
|
||||
:sta sta x
|
||||
jmp recalc_cursor_x
|
||||
:rts rts
|
||||
|
||||
csi_D
|
||||
* left
|
||||
|
||||
bit pmod
|
||||
bmi :rts
|
||||
|
||||
p1
|
||||
|
||||
lda x
|
||||
and #$7f
|
||||
|
||||
sec
|
||||
sbc parms
|
||||
* bcc :0 ; underflow
|
||||
bcs :sta
|
||||
:0 lda #0
|
||||
:sta sta x
|
||||
jmp recalc_cursor_x
|
||||
:rts rts
|
||||
|
||||
|
||||
csi_f
|
||||
csi_H ; direct cursor addressing
|
||||
|
||||
debug csi_H
|
||||
|
||||
|
||||
* honors origin
|
||||
* large numbers are clamped
|
||||
* 0 or 1 treated as 1 (1-based counting)
|
||||
|
||||
* based on testing, esc [ 253-255 H will position outside the scrolling
|
||||
* region when DECOM is active (to first 3 lines, respectively)
|
||||
* this is not emulated.
|
||||
|
||||
* y
|
||||
lda parms
|
||||
beq :yy
|
||||
dec
|
||||
:yy bit DECOM
|
||||
bmi :org
|
||||
cmp #23
|
||||
blt :yyy
|
||||
lda #23
|
||||
:yyy sta y
|
||||
bra :x
|
||||
|
||||
|
||||
:org
|
||||
clc
|
||||
adc DECTM
|
||||
cmp DECBM
|
||||
blt :org1
|
||||
lda DECBM
|
||||
:org1 sta y
|
||||
|
||||
* x
|
||||
:x
|
||||
ldx parms+1
|
||||
beq :xx
|
||||
dex
|
||||
:xx
|
||||
cpx #79
|
||||
blt :xxx
|
||||
ldx #79
|
||||
:xxx stx x
|
||||
|
||||
jmp recalc_cursor
|
||||
|
||||
csi_r ; scrolling region
|
||||
debug csi_r
|
||||
* based on testing
|
||||
* 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 )
|
||||
* 24 is assumed value for second parameter
|
||||
* invalid parameters exit without updating
|
||||
|
||||
* based on testing, row parameters are not affected by DECOM.
|
||||
|
||||
lda parms
|
||||
beq :p1
|
||||
dec parms
|
||||
:p1
|
||||
|
||||
lda parms+1
|
||||
beq :p2
|
||||
dec parms+1
|
||||
bra :check
|
||||
|
||||
:p2 lda #23
|
||||
sta parms+1
|
||||
|
||||
:check
|
||||
* 23 max
|
||||
ldx parms+0
|
||||
cpx #23+1
|
||||
bge :rts
|
||||
|
||||
ldx parms+1
|
||||
cpx #23+1
|
||||
bge :rts
|
||||
|
||||
|
||||
* must be at least 1 line
|
||||
lda parms+1
|
||||
sec
|
||||
sbc parms
|
||||
beq :rts
|
||||
bmi :rts
|
||||
|
||||
* move cursor to origin.
|
||||
lda parms
|
||||
sta DECTM
|
||||
sta y
|
||||
lda parms+1
|
||||
sta DECBM
|
||||
stz x
|
||||
bit DECOM
|
||||
bmi :j
|
||||
stz y
|
||||
:j jmp recalc_cursor
|
||||
|
||||
:rts rts
|
||||
|
||||
csi_J ; erase screen
|
||||
|
||||
lda parms
|
||||
cmp #2+1
|
||||
bcs :rts
|
||||
asl
|
||||
tax
|
||||
jmp (:table,x)
|
||||
|
||||
:rts rts
|
||||
|
||||
:table
|
||||
dw erase_screen_0
|
||||
dw erase_screen_1
|
||||
dw erase_screen_2
|
||||
|
||||
csi_K ; erase line
|
||||
|
||||
lda parms
|
||||
cmp #2+1
|
||||
bcs :rts
|
||||
asl
|
||||
tax
|
||||
jmp (:table,x)
|
||||
|
||||
:rts rts
|
||||
|
||||
:table
|
||||
dw erase_line_0
|
||||
dw erase_line_1
|
||||
dw erase_line_2
|
||||
|
||||
csi_q ; LEDs
|
||||
rts
|
||||
csi_n ; status report
|
||||
|
||||
bit LOCAL
|
||||
bmi :rts
|
||||
lda parms
|
||||
cmp #5
|
||||
beq :dsr
|
||||
cmp #6
|
||||
beq :cpr
|
||||
:rts rts
|
||||
:dsr ; report status
|
||||
lda #ESC
|
||||
jsr write_modem
|
||||
lda #'['
|
||||
jsr write_modem
|
||||
lda #'0'
|
||||
jsr write_modem
|
||||
lda #'n'
|
||||
jmp write_modem
|
||||
:cpr ; cursor report
|
||||
* returned y is in terms of DECOM.
|
||||
lda #ESC
|
||||
jsr write_modem
|
||||
lda #'['
|
||||
jsr write_modem
|
||||
|
||||
lda y
|
||||
bit DECOM
|
||||
bpl :y
|
||||
sec
|
||||
sbc DECTM
|
||||
|
||||
:y inc
|
||||
jsr write_digit
|
||||
lda #';'
|
||||
jsr write_modem
|
||||
lda x
|
||||
inc
|
||||
jsr write_digit
|
||||
lda #'R'
|
||||
jmp write_modem
|
||||
|
||||
|
||||
write_digit
|
||||
* digit must be in the range 1-80
|
||||
cmp #10
|
||||
bcs :multi
|
||||
:0 ora #'0'
|
||||
jmp write_modem
|
||||
:multi
|
||||
ldx #8
|
||||
]loop cmp :table,x
|
||||
bcs :ok
|
||||
dex
|
||||
bra ]loop
|
||||
|
||||
:ok sec
|
||||
sbc :table,x
|
||||
pha ; save
|
||||
txa
|
||||
ora #'0'
|
||||
jsr write_modem
|
||||
pla
|
||||
bra :0
|
||||
|
||||
:table db 0,10,20,30,40,50,60,70,80
|
||||
|
||||
csi_c ; what are you?
|
||||
* DA - Device Attributes
|
||||
|
||||
mx %11
|
||||
|
||||
php
|
||||
rep #$10 ; long x/y
|
||||
ldy #:response
|
||||
jsr write_modem_str
|
||||
plp
|
||||
rts
|
||||
|
||||
:response asc 1b,'[?1;0c',00 ; No options.
|
||||
|
||||
csi_y ; invoke confidence test
|
||||
* ???
|
||||
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
|
|
@ -0,0 +1,122 @@
|
|||
|
||||
lst off
|
||||
cas se
|
||||
rel
|
||||
xc
|
||||
xc
|
||||
|
||||
use vt.equ
|
||||
|
||||
|
||||
*control chars
|
||||
ext draw_char,update_cursor
|
||||
|
||||
control ent
|
||||
|
||||
asl
|
||||
tax
|
||||
jmp (:table,x)
|
||||
|
||||
:table
|
||||
dw :rts ; ^@
|
||||
dw :rts ; ^A
|
||||
dw :rts ; ^B
|
||||
dw :rts ; ^C
|
||||
dw :rts ; ^D
|
||||
dw enq ; ^E
|
||||
dw :rts ; ^F
|
||||
dw bel ; ^G
|
||||
dw bs ; ^H
|
||||
dw tab ; ^I
|
||||
dw lf ; ^J
|
||||
dw vt ; ^K
|
||||
dw ff ; ^L
|
||||
dw cr ; ^M
|
||||
dw so ; ^N
|
||||
dw si ; ^O
|
||||
dw :rts ; ^P
|
||||
dw xon ; ^Q
|
||||
dw :rts ; ^R
|
||||
dw xoff ; ^S
|
||||
dw :rts ; ^T
|
||||
dw :rts ; ^U
|
||||
dw :rts ; ^V
|
||||
dw :rts ; ^W
|
||||
dw can ; ^X
|
||||
dw :rts ; ^Y
|
||||
dw sub ; ^Z
|
||||
dw esc ; ^[
|
||||
dw :rts ; ^\
|
||||
dw :rts ; ^]
|
||||
dw :rts ; ^^
|
||||
dw :rts ; ^_
|
||||
|
||||
:rts rts
|
||||
|
||||
enq
|
||||
* send answer back message.
|
||||
* answer back message is a user-controllable string of text sent as-is
|
||||
* (with no specific terminator character)
|
||||
rts
|
||||
bel
|
||||
* todo - trigger nice ensoniq beep.
|
||||
rts
|
||||
|
||||
|
||||
bs
|
||||
* backspace, no wrap
|
||||
lda x
|
||||
beq :rts
|
||||
and #$7f
|
||||
dec
|
||||
sta x
|
||||
jmp update_cursor
|
||||
:rts rts
|
||||
|
||||
tab
|
||||
* go to next tab stop
|
||||
* tab at 80 does not reset overflow.
|
||||
rts
|
||||
|
||||
lf
|
||||
vt
|
||||
ff
|
||||
* vt and ff interpreted as lf
|
||||
* LNM: also do cr.
|
||||
bit LNM
|
||||
bpl :lnm
|
||||
stz x
|
||||
:lnm
|
||||
lda y
|
||||
cmp BM ; bottom margin
|
||||
bne :iny
|
||||
jmp scroll_up
|
||||
:iny inc y
|
||||
jmp update_cursor
|
||||
|
||||
cr
|
||||
stz x
|
||||
jmp update_cursor
|
||||
|
||||
|
||||
so ; G1 character set
|
||||
si ; G0 character set
|
||||
rts
|
||||
|
||||
xon
|
||||
xoff
|
||||
* flow control...
|
||||
rts
|
||||
can
|
||||
sub
|
||||
ext draw_char_raw
|
||||
* cancel esc sequence and display error character
|
||||
stz state
|
||||
lda #$57 ; mouse text block
|
||||
jmp draw_char_raw
|
||||
rts
|
||||
|
||||
esc
|
||||
lda #st_esc
|
||||
sta state
|
||||
rts
|
|
@ -0,0 +1,320 @@
|
|||
|
||||
lst off
|
||||
rel
|
||||
xc
|
||||
xc
|
||||
|
||||
use vt.equ
|
||||
|
||||
mx %11
|
||||
|
||||
|
||||
ext recalc_cursor,recalc_cursor_x,recalc_cursor_y
|
||||
ext scroll_up,scroll_down
|
||||
ext reset
|
||||
ext update_sgr
|
||||
|
||||
vt100_esc ent
|
||||
* #[()=>cH78DEM
|
||||
* based on testing, unspecified chars in the 0x20-0x2f range cause it
|
||||
* to gobble chars until 0x30- terminator (which ends the sequence but
|
||||
* does not take an action)
|
||||
|
||||
* esc 1 -> hangs? [undocumented]
|
||||
|
||||
ldx #st_vt100
|
||||
stx state
|
||||
|
||||
cmp #:MIN
|
||||
blt :bad
|
||||
cmp #:MAX+1
|
||||
bge :rts
|
||||
sec
|
||||
sbc #:MIN
|
||||
asl
|
||||
tax
|
||||
jmp (:table,x)
|
||||
|
||||
:bad
|
||||
ldx #st_vt100_esc_bad
|
||||
stx state
|
||||
:rts
|
||||
rts
|
||||
|
||||
:MIN equ 35
|
||||
:MAX equ 99
|
||||
|
||||
:table
|
||||
dw :pound ; #
|
||||
dw :bad ; $
|
||||
dw :bad ; %
|
||||
dw :bad ; &
|
||||
dw :bad ; '
|
||||
dw :lparen ; (
|
||||
dw :rparen ; )
|
||||
dw :bad ; *
|
||||
dw :bad ; +
|
||||
dw :bad ; ,
|
||||
dw :bad ; -
|
||||
dw :bad ; .
|
||||
dw :bad ; /
|
||||
dw :rts ; 0
|
||||
dw :rts ; 1
|
||||
dw :rts ; 2
|
||||
dw :rts ; 3
|
||||
dw :rts ; 4
|
||||
dw :rts ; 5
|
||||
dw :rts ; 6
|
||||
dw esc_7 ; 7
|
||||
dw esc_8 ; 8
|
||||
dw :rts ; 9
|
||||
dw :rts ; :
|
||||
dw :rts ; ;
|
||||
dw :rts ; <
|
||||
dw esc_eq ; =
|
||||
dw esc_gt ; >
|
||||
dw :rts ; ?
|
||||
dw :rts ; @
|
||||
dw :rts ; A
|
||||
dw :rts ; B
|
||||
dw :rts ; C
|
||||
dw esc_D ; D
|
||||
dw esc_E ; E
|
||||
dw :rts ; F
|
||||
dw :rts ; G
|
||||
dw esc_H ; H
|
||||
dw :rts ; I
|
||||
dw :rts ; J
|
||||
dw :rts ; K
|
||||
dw :rts ; L
|
||||
dw esc_M ; 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 :csi ; [
|
||||
dw :rts ; \
|
||||
dw :rts ; ]
|
||||
dw :rts ; ^
|
||||
dw :rts ; _
|
||||
dw :rts ; `
|
||||
dw :rts ; a
|
||||
dw :rts ; b
|
||||
dw esc_c ; c
|
||||
|
||||
|
||||
|
||||
:lparen
|
||||
ldx #st_vt100_esc_lparen
|
||||
stx state
|
||||
rts
|
||||
|
||||
:rparen
|
||||
ldx #st_vt100_esc_rparen
|
||||
stx state
|
||||
rts
|
||||
|
||||
:pound
|
||||
ldx #st_vt100_esc_pound
|
||||
stx state
|
||||
rts
|
||||
|
||||
:csi
|
||||
ldx #st_vt100_csi
|
||||
stx state
|
||||
rts
|
||||
|
||||
|
||||
esc_7 ; save cursor position, graphic rendition, and character set.
|
||||
* based on testing, DECOM is also saved/restored.
|
||||
lda x
|
||||
sta saved_x
|
||||
lda y
|
||||
sta saved_y
|
||||
lda DECOM
|
||||
sta saved_decom
|
||||
lda SGR
|
||||
sta saved_sgr
|
||||
|
||||
rts
|
||||
esc_8 ; restore cursor position, graphic rendition, and character set.
|
||||
|
||||
lda saved_x
|
||||
sta x
|
||||
lda saved_y
|
||||
sta y
|
||||
lda saved_decom
|
||||
sta DECOM
|
||||
lda saved_sgr
|
||||
sta SGR
|
||||
|
||||
jsr update_sgr
|
||||
jmp recalc_cursor
|
||||
|
||||
esc_eq ; enter alternate keypad mode
|
||||
lda #$80
|
||||
sta DECKPAM
|
||||
rts
|
||||
esc_gt ; exit alternate keypad mode
|
||||
stz DECKPAM
|
||||
rts
|
||||
|
||||
esc_H ; set tab stop
|
||||
ext set_tab
|
||||
ldx x
|
||||
bmi :rts
|
||||
jmp set_tab
|
||||
:rts rts
|
||||
|
||||
esc_E ; next line
|
||||
* This sequence causes the active position to move to the first position
|
||||
* on the next line downward. If the active position is at the bottom
|
||||
* margin, a scroll up is performed.
|
||||
stz x
|
||||
jsr recalc_cursor_x
|
||||
; drop through
|
||||
esc_D ; index
|
||||
* This sequence causes the active position to move downward one line
|
||||
* without changing the column position. If the active position is at the
|
||||
* bottom margin, a scroll up is performed.
|
||||
|
||||
lda y
|
||||
cmp DECBM
|
||||
beq :scroll
|
||||
cmp #23
|
||||
beq :rts
|
||||
inc y
|
||||
jmp recalc_cursor_y
|
||||
|
||||
:scroll jmp scroll_down
|
||||
:rts rts
|
||||
|
||||
|
||||
esc_M ; reverse index
|
||||
* Move the active position to the same horizontal position on the
|
||||
* preceding line. If the active position is at the top margin, a scroll
|
||||
* down is performed.
|
||||
|
||||
lda y
|
||||
cmp DECTM
|
||||
beq :scroll
|
||||
cmp #0
|
||||
beq :rts
|
||||
dec y
|
||||
jmp recalc_cursor_y
|
||||
|
||||
:scroll jmp scroll_up
|
||||
:rts rts
|
||||
|
||||
|
||||
esc_c ; TODO - reset terminal.
|
||||
jmp reset
|
||||
|
||||
|
||||
vt100_esc_bad ent
|
||||
cmp #'0'
|
||||
blt :rts
|
||||
ldx #st_vt100
|
||||
stx state
|
||||
:rts
|
||||
rts
|
||||
|
||||
|
||||
|
||||
vt100_esc_pound ent
|
||||
|
||||
* esc # 3 - make line double height (top half)
|
||||
* esc # 4 - make line double height (bottom half)
|
||||
* esc # 5 - make line single width, single height
|
||||
* esc # 6 - make line double width
|
||||
|
||||
* esc # 8 - screen alignment - fill screen with E (SGR not honored)
|
||||
* based on testing, this also resets the scrolling region and homes
|
||||
* the cursor.
|
||||
|
||||
* based on testing, 0+ are term characters, 0x20-0x2f puts it in
|
||||
* esc_bad state
|
||||
|
||||
ldx #st_vt100
|
||||
stx state
|
||||
|
||||
cmp #:MIN
|
||||
blt :bad
|
||||
cmp #:MAX+1
|
||||
bge :rts
|
||||
sec
|
||||
sbc #:MIN
|
||||
asl
|
||||
tax
|
||||
jmp (:table,x)
|
||||
|
||||
:bad ldx #st_vt100_esc_bad
|
||||
stx state
|
||||
:rts rts
|
||||
|
||||
:MIN equ 48
|
||||
:MAX equ 57
|
||||
|
||||
:table
|
||||
dw :rts ; 0
|
||||
dw :rts ; 1
|
||||
dw :rts ; 2
|
||||
dw :rts ; 3
|
||||
dw :rts ; 4
|
||||
dw :rts ; 5
|
||||
dw :rts ; 6
|
||||
dw :rts ; 7
|
||||
dw :e ; 8
|
||||
dw :rts ; 9
|
||||
|
||||
:e
|
||||
* TODO - does this reset DECOM?
|
||||
ext fill_screen
|
||||
stz x
|
||||
stz y
|
||||
stz DECTM
|
||||
lda #23
|
||||
sta DECBM
|
||||
jsr recalc_cursor
|
||||
|
||||
lda #"E"
|
||||
jmp fill_screen
|
||||
|
||||
|
||||
vt100_esc_lparen ent
|
||||
vt100_esc_rparen ent
|
||||
|
||||
* ( sets G0, ) sets G1
|
||||
* A - UK set
|
||||
* B - ASCII set
|
||||
* 0 - Special Graphics
|
||||
* 1 - Alternate Char ROM Standard Char Set
|
||||
* 2 - Alternate Char ROM Special Graphics
|
||||
|
||||
* SO, aka Control-N aka 0x0e set the G1 char set
|
||||
* SI, aka Control-O aka 0x0f set the G0 char set
|
||||
|
||||
* not currently supported.
|
||||
* TODO - mouse text support?
|
||||
|
||||
ldx #st_vt100
|
||||
stx state
|
||||
|
||||
cmp #'0'
|
||||
blt :bad
|
||||
rts
|
||||
|
||||
:bad ldx #st_vt100_esc_bad
|
||||
stx state
|
||||
:rts rts
|
||||
|
||||
sav vt100.esc.L
|
|
@ -0,0 +1,465 @@
|
|||
|
||||
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
|
||||
bpl :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
|
|
@ -0,0 +1,30 @@
|
|||
|
||||
ovr all
|
||||
* binary linker
|
||||
lkv 0
|
||||
org $2000
|
||||
|
||||
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
|
||||
asm vt100.key.S
|
||||
asm vt100.beep.S
|
||||
asm vt100.cda.S
|
||||
|
||||
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
|
||||
lnk vt100.key.L
|
||||
lnk vt100.beep.L
|
||||
lnk vt100.cda.L
|
||||
|
||||
typ $ff
|
||||
sav vt100.system
|
|
@ -0,0 +1,477 @@
|
|||
|
||||
lst off
|
||||
rel
|
||||
xc
|
||||
xc
|
||||
|
||||
tbx on ; qasm
|
||||
|
||||
mx %11
|
||||
use vt.equ
|
||||
use apple2gs.equ
|
||||
use debug
|
||||
|
||||
ext scroll_down
|
||||
ext recalc_cursor,recalc_cursor_x,recalc_cursor_y
|
||||
ext modem_io,modem_vector,reset_modem_buffer
|
||||
ext modem_startup,modem_shutdown
|
||||
ext keypress
|
||||
ext disable_cursor,enable_cursor,cursor_vector
|
||||
ext erase_screen,fill_screen
|
||||
ext init_tabs
|
||||
ext init_audio
|
||||
ext cda_startup,cda_shutdown
|
||||
|
||||
main debug main
|
||||
|
||||
clc
|
||||
xce
|
||||
cli
|
||||
|
||||
pea DPAGE
|
||||
pld
|
||||
|
||||
jsr init
|
||||
jsr enable_cursor
|
||||
|
||||
|
||||
lda #4
|
||||
tsb VGCINT ; enable 1-sec interrupt.
|
||||
stz SCANINT ; reset 1-sec interrupt
|
||||
|
||||
|
||||
loop
|
||||
jsr keypress ; check for a keypress, write data to out buffer.
|
||||
jsr modem_io ;
|
||||
bcc :nope
|
||||
pha
|
||||
jsr disable_cursor
|
||||
pla
|
||||
jsr vt100
|
||||
bra loop
|
||||
|
||||
:nope ; no modem data, re-enable the cursor.
|
||||
jsr enable_cursor
|
||||
bra loop
|
||||
|
||||
init
|
||||
mx %11
|
||||
|
||||
lda #" "
|
||||
jsr fill_screen ; erase first to prevent flash if going 40->80 columns.
|
||||
|
||||
sta TXTSET
|
||||
sta SET80VID
|
||||
sta SETALTCHAR
|
||||
rep #$30
|
||||
|
||||
jsr init_mem
|
||||
|
||||
|
||||
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
|
||||
|
||||
sei
|
||||
lda cursor_vector
|
||||
stal IRQ1SEC
|
||||
lda cursor_vector+2
|
||||
stal IRQ1SEC+2
|
||||
|
||||
lda modem_vector
|
||||
stal IRQSERIAL
|
||||
lda modem_vector+2
|
||||
stal IRQSERIAL+2
|
||||
|
||||
cli
|
||||
|
||||
lda #0 ; clear high byte
|
||||
|
||||
sep #$30
|
||||
|
||||
lda #"_"
|
||||
sta cursor_char
|
||||
|
||||
|
||||
lda #23
|
||||
sta DECBM
|
||||
lda #$80
|
||||
* sta LOCAL
|
||||
sta DECANM ; ANSI (vt100) on
|
||||
sta DECARM ; key repeat on
|
||||
|
||||
* lda #st_vt52
|
||||
lda #st_vt100
|
||||
sta state
|
||||
|
||||
* jsr erase_screen
|
||||
jsr modem_startup
|
||||
jsr init_tabs
|
||||
jsr init_audio
|
||||
jsr cda_startup
|
||||
rts
|
||||
|
||||
|
||||
MasterID dw 0
|
||||
init_mem
|
||||
*
|
||||
* see prodos technote #27
|
||||
*
|
||||
* _InstallCDA uses the memory manager ; otherwise I wouldn't bother
|
||||
* This is here to prevent MM from stomping on our memory.
|
||||
*
|
||||
|
||||
mx %00
|
||||
|
||||
stz MasterID
|
||||
_TLStartUp
|
||||
pha
|
||||
_MMStartUp
|
||||
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
|
||||
|
||||
vt100
|
||||
mx %11
|
||||
and #$7f
|
||||
cmp #' '
|
||||
bcs :notctrl
|
||||
asl
|
||||
tax
|
||||
jmp (:ctrl_table,x)
|
||||
:notctrl
|
||||
ldx state
|
||||
jmp (:state_table,x)
|
||||
|
||||
|
||||
|
||||
:state_table
|
||||
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 draw_char,draw_char_raw
|
||||
|
||||
dw draw_char
|
||||
dw vt52_esc
|
||||
dw vt52_dca
|
||||
dw draw_char
|
||||
dw vt100_esc
|
||||
dw vt100_csi
|
||||
dw vt100_csi_2
|
||||
dw vt100_esc_pound
|
||||
dw vt100_esc_lparen
|
||||
dw vt100_esc_rparen
|
||||
dw vt100_esc_bad
|
||||
dw vt100_csi_bad
|
||||
|
||||
|
||||
:ctrl_table
|
||||
dw ctrl_00,ctrl_01,ctrl_02,ctrl_03
|
||||
dw ctrl_04,ctrl_05,ctrl_06,ctrl_07
|
||||
dw ctrl_08,ctrl_09,ctrl_0a,ctrl_0b
|
||||
dw ctrl_0c,ctrl_0d,ctrl_0e,ctrl_0f
|
||||
dw ctrl_10,ctrl_11,ctrl_12,ctrl_13
|
||||
dw ctrl_14,ctrl_15,ctrl_16,ctrl_17
|
||||
dw ctrl_18,ctrl_19,ctrl_1a,ctrl_1b
|
||||
dw ctrl_1c,ctrl_1d,ctrl_1e,ctrl_1f
|
||||
|
||||
|
||||
|
||||
ctrl_00
|
||||
ctrl_01
|
||||
ctrl_02
|
||||
ctrl_03
|
||||
ctrl_04
|
||||
ctrl_05 ; answer ENQ
|
||||
ctrl_06
|
||||
ctrl_0e ; G1 character set
|
||||
ctrl_0f ; G0 character set
|
||||
ctrl_10
|
||||
ctrl_11 ; XON
|
||||
ctrl_12
|
||||
ctrl_13 ; XOFF
|
||||
ctrl_14
|
||||
ctrl_15
|
||||
ctrl_16
|
||||
ctrl_17
|
||||
ctrl_19
|
||||
ctrl_1c
|
||||
ctrl_1d
|
||||
ctrl_1e
|
||||
ctrl_1f
|
||||
rts
|
||||
|
||||
|
||||
ctrl_07 ; ring the bell.
|
||||
ext beep
|
||||
jmp beep
|
||||
|
||||
ctrl_1b ; escape -
|
||||
* vt100 - aborts current escape sequence and starts a new one.
|
||||
* vt52 - esc esc aborts and starts new
|
||||
* vt50 - esc esc aborts
|
||||
bit DECANM
|
||||
bpl :vt52
|
||||
lda #st_vt100_esc
|
||||
sta state
|
||||
rts
|
||||
|
||||
:vt52
|
||||
lda #st_vt52_esc
|
||||
sta state
|
||||
rts
|
||||
|
||||
ctrl_18
|
||||
ctrl_1a
|
||||
* vt100 - abort current escape sequence
|
||||
* and display error character.
|
||||
*
|
||||
* 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
|
||||
bpl :vt52
|
||||
lda #st_vt100
|
||||
sta state
|
||||
rts
|
||||
|
||||
:vt52
|
||||
lda #st_vt52
|
||||
sta state
|
||||
rts
|
||||
|
||||
ctrl_08 ; back space
|
||||
lda x
|
||||
beq :rts
|
||||
and #$7f
|
||||
dec
|
||||
sta x
|
||||
jmp recalc_cursor_x
|
||||
:rts rts
|
||||
|
||||
ctrl_09 ; tab
|
||||
* vt100 has adjustable tabs.
|
||||
ext next_tab_stop
|
||||
ldx x
|
||||
bmi :rts
|
||||
jsr next_tab_stop
|
||||
stx x
|
||||
jmp recalc_cursor_x
|
||||
:rts rts
|
||||
|
||||
ctrl_0a ; line feed - cursor down w/ scroll
|
||||
ctrl_0b ; vertical tab
|
||||
ctrl_0c ; form feed.
|
||||
|
||||
* if LNM is active, equivalent to CR, LF
|
||||
|
||||
bit #LNM
|
||||
bpl :lf
|
||||
stz x
|
||||
jsr recalc_cursor_x
|
||||
|
||||
:lf
|
||||
lda y
|
||||
cmp DECBM
|
||||
bne :simple
|
||||
|
||||
* lda #" " ; needs to factor in reverse video
|
||||
* sta cursor_saved_char
|
||||
jmp scroll_down
|
||||
* if LNM mode, need to update cursor as well.
|
||||
|
||||
:simple
|
||||
cmp #23
|
||||
beq :rts
|
||||
inc y
|
||||
jmp recalc_cursor_y
|
||||
|
||||
:rts rts
|
||||
|
||||
ctrl_0d ; carriage return - cursor to column 0.
|
||||
stz x
|
||||
jmp recalc_cursor_x
|
||||
|
||||
|
||||
sav vt100.main.L
|
|
@ -0,0 +1,419 @@
|
|||
|
||||
lst off
|
||||
rel
|
||||
xc
|
||||
xc
|
||||
|
||||
mx %11
|
||||
cas se
|
||||
use vt.equ
|
||||
use debug
|
||||
|
||||
SCCBREG equ $c038
|
||||
SCCAREG equ $c039
|
||||
SCCBDATA equ $c03a
|
||||
SCCADATA equ $c03b
|
||||
|
||||
|
||||
SerFlag equ $e10104 ;
|
||||
|
||||
*
|
||||
* scc speed:
|
||||
*
|
||||
* time constant = ( clock / (2 * clock mode * baud rate)) - 2
|
||||
* baud rate = clock / ( 2 * clock mode * (time constant + 2))
|
||||
*
|
||||
* clock mode = 1x, 16x, 32x, or 64x (selected via write register 4 bits 6/7)
|
||||
* clock = 3.6864 MHz crystal (scc runs at 14.31818 / 4 = ~ 3.58 Mhz)
|
||||
* time constant = write register 12 (low) + 13 (high)
|
||||
*
|
||||
*
|
||||
* see IIgs TN #18 - Do-It-Yourself SCC Access
|
||||
|
||||
modem_startup ent
|
||||
enable_modem ent
|
||||
* sep #$30
|
||||
|
||||
php
|
||||
sei
|
||||
|
||||
stz read_q_head
|
||||
stz read_q_tail
|
||||
stz write_q_head
|
||||
stz write_q_tail
|
||||
|
||||
|
||||
* zero out the buffer [for CDA debugger]
|
||||
ldx #0
|
||||
]loop stz read_buffer,x
|
||||
inx
|
||||
bne ]loop
|
||||
|
||||
|
||||
lda SCCBREG ; sync access
|
||||
ldx #0
|
||||
|
||||
]loop
|
||||
lda :table,x
|
||||
bmi :done
|
||||
sta SCCBREG
|
||||
inx
|
||||
lda :table,x
|
||||
sta SCCBREG
|
||||
inx
|
||||
bra ]loop
|
||||
:done
|
||||
|
||||
* adjust SerFlag so serial IRQs will be handled.
|
||||
lda >SerFlag
|
||||
ora #%00_000_111 ; channel B interrupts.
|
||||
sta >SerFlag
|
||||
|
||||
plp
|
||||
rts
|
||||
|
||||
: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
|
||||
* a: byte to send
|
||||
tay ; save
|
||||
* ldx #0
|
||||
php
|
||||
|
||||
|
||||
:mask = %0010_0100 ; tx buffer empty, clear to send
|
||||
:wait
|
||||
cli ; guard scc register access.
|
||||
sei
|
||||
stz SCCBREG
|
||||
lda SCCBREG
|
||||
and #:mask
|
||||
cmp #:mask
|
||||
bne :wait
|
||||
|
||||
sty SCCBDATA
|
||||
plp
|
||||
rts
|
||||
|
||||
|
||||
read_modem_sync 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
|
||||
|
||||
* debugging...
|
||||
|
||||
|
||||
sec
|
||||
:rts rts
|
||||
|
||||
|
||||
write_buffer equ $1d00
|
||||
read_buffer equ $1e00
|
||||
|
||||
modem_vector ent
|
||||
jml modem_int
|
||||
modem_int
|
||||
*
|
||||
* called in 8-bit native mode, interrupts disabled.
|
||||
* d = unknown
|
||||
* a/x/y don't need to be preserved.
|
||||
* return carry clear if handled, carry set if not.
|
||||
|
||||
* doesn't access direct page.
|
||||
|
||||
* check/clear overrun?
|
||||
|
||||
*
|
||||
* n.b. - vt100 would drop $00 and $7f characters here - I drop them later.
|
||||
*
|
||||
|
||||
mx %11
|
||||
|
||||
phb
|
||||
phk
|
||||
plb
|
||||
|
||||
lda SCCBREG ; sync
|
||||
stz SCCBREG
|
||||
lda SCCBREG
|
||||
and #%0000_0001 ; rx ready.
|
||||
beq :nope
|
||||
|
||||
:read
|
||||
lda SCCBDATA
|
||||
ldx DPAGE+read_q_head
|
||||
sta read_buffer,x
|
||||
inc DPAGE+read_q_head
|
||||
|
||||
* more?
|
||||
stz SCCBREG
|
||||
lda SCCBREG
|
||||
and #%0000_0001 ; rx ready.
|
||||
bne :read
|
||||
clc
|
||||
bra :finish
|
||||
|
||||
:nope
|
||||
|
||||
sec
|
||||
:finish
|
||||
* reset errors.
|
||||
lda #%00_110_000
|
||||
stz SCCBREG
|
||||
sta SCCBREG
|
||||
|
||||
* reset highest ius
|
||||
lda #%00_111_000
|
||||
stz SCCBREG
|
||||
sta SCCBREG
|
||||
|
||||
plb
|
||||
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_async ent
|
||||
|
||||
mx %11
|
||||
|
||||
php
|
||||
sei
|
||||
ldx read_q_tail
|
||||
cpx read_q_head
|
||||
beq :nope
|
||||
|
||||
lda read_buffer,x
|
||||
inc read_q_tail
|
||||
plp
|
||||
sec
|
||||
rts
|
||||
|
||||
:nope
|
||||
plp
|
||||
clc
|
||||
rts
|
||||
|
||||
reset_modem_buffer ent
|
||||
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
|
||||
|
||||
sav vt100.modem.L
|
|
@ -0,0 +1,830 @@
|
|||
|
||||
lst off
|
||||
|
||||
rel
|
||||
xc
|
||||
xc
|
||||
use vt.equ
|
||||
use apple2gs.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
|
||||
|
||||
|
||||
update_sgr ent
|
||||
|
||||
stz draw_inverse
|
||||
lda SGR
|
||||
beq :rts
|
||||
lda #$80
|
||||
sta draw_inverse
|
||||
|
||||
:rts rts
|
||||
|
||||
|
||||
|
||||
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?
|
||||
ldy cursor_offset
|
||||
lda [cursor_base],y
|
||||
sta cursor_saved_char
|
||||
lda cursor_char
|
||||
sta [cursor_base],y
|
||||
|
||||
:80 lda #$80
|
||||
trb cursor_state
|
||||
|
||||
:rts plp
|
||||
rts
|
||||
|
||||
|
||||
cursor_vector ent
|
||||
jml cursor_int
|
||||
|
||||
NumInts equ $e01d67
|
||||
|
||||
cursor_int
|
||||
* cursor interrupt - blink the cursor.
|
||||
|
||||
mx %11
|
||||
|
||||
phb
|
||||
phd
|
||||
phk
|
||||
plb
|
||||
|
||||
|
||||
* check if CDA active.
|
||||
* $ff = inactive, $00 = active
|
||||
lda >NumInts
|
||||
bpl :rts
|
||||
|
||||
pea DPAGE
|
||||
pld
|
||||
|
||||
ldy cursor_offset
|
||||
|
||||
lda cursor_state
|
||||
bmi :rts
|
||||
eor #$40
|
||||
sta cursor_state
|
||||
beq :off
|
||||
:on
|
||||
lda [cursor_base],y
|
||||
sta cursor_saved_char
|
||||
lda cursor_char
|
||||
sta [cursor_base],y
|
||||
|
||||
bra :rts
|
||||
|
||||
:off
|
||||
lda cursor_saved_char
|
||||
sta [cursor_base],y
|
||||
|
||||
:rts stz SCANINT ; reset 1-sec interrupt
|
||||
pld
|
||||
plb
|
||||
clc
|
||||
rtl
|
||||
|
||||
|
||||
|
||||
|
||||
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_char_raw ; nothing to do for lowercase
|
||||
cmp #$40 ; @, first uppercase
|
||||
bcc draw_char_raw ; nothing to do for special
|
||||
|
||||
:uc and #%10111111 ; ~ $40
|
||||
bra draw_char_raw
|
||||
|
||||
|
||||
:normal ora #$80
|
||||
|
||||
draw_char_raw ent
|
||||
* entry point for writing character to screen w/o processing it
|
||||
|
||||
|
||||
* sta cursor_saved_char
|
||||
|
||||
* 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
|
||||
|
||||
* based on testing, will not advance to column 80 unless DECAWM is enabled.
|
||||
|
||||
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 DECAWM ; set bit 7 if DECAWM.
|
||||
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
|
||||
jmp advance_x
|
||||
|
||||
:scroll
|
||||
pha ; save
|
||||
|
||||
jsr scroll_down
|
||||
jsr recalc_cursor_x
|
||||
pla
|
||||
sta [cursor_base] ; offset 0
|
||||
jmp advance_x
|
||||
|
||||
|
||||
* erase screen commands are not affected by origin or scrolling region.
|
||||
|
||||
erase_screen ent
|
||||
erase_screen_2 ent
|
||||
* erase the entire screen.
|
||||
|
||||
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.
|
||||
* +64 bytes of screen hole data.
|
||||
mx %11
|
||||
|
||||
sta >$000400
|
||||
sta >$010400
|
||||
|
||||
php
|
||||
rep #$30
|
||||
|
||||
|
||||
ldx #$0400
|
||||
ldy #$0401
|
||||
lda #40*3-2
|
||||
mvn $010000,$010000
|
||||
|
||||
ldx #$0400
|
||||
ldy #$0480
|
||||
lda #40*3-1
|
||||
mvn $010000,$010000
|
||||
|
||||
ldx #$0400
|
||||
ldy #$0500
|
||||
lda #40*3-1
|
||||
mvn $010000,$010000
|
||||
|
||||
ldx #$0400
|
||||
ldy #$0580
|
||||
lda #40*3-1
|
||||
mvn $010000,$010000
|
||||
|
||||
ldx #$0400
|
||||
ldy #$0600
|
||||
lda #40*3-1
|
||||
mvn $010000,$010000
|
||||
|
||||
ldx #$0400
|
||||
ldy #$0680
|
||||
lda #40*3-1
|
||||
mvn $010000,$010000
|
||||
|
||||
ldx #$0400
|
||||
ldy #$0700
|
||||
lda #40*3-1
|
||||
mvn $010000,$010000
|
||||
|
||||
ldx #$0400
|
||||
ldy #$0780
|
||||
lda #40*3-1
|
||||
mvn $010000,$010000
|
||||
|
||||
*
|
||||
ldx #$0400
|
||||
ldy #$0401
|
||||
lda #40*3-2
|
||||
mvn $000000,$000000
|
||||
|
||||
ldx #$0400
|
||||
ldy #$0480
|
||||
lda #40*3-1
|
||||
mvn $000000,$000000
|
||||
|
||||
ldx #$0400
|
||||
ldy #$0500
|
||||
lda #40*3-1
|
||||
mvn $000000,$000000
|
||||
|
||||
ldx #$0400
|
||||
ldy #$0580
|
||||
lda #40*3-1
|
||||
mvn $000000,$000000
|
||||
|
||||
ldx #$0400
|
||||
ldy #$0600
|
||||
lda #40*3-1
|
||||
mvn $000000,$000000
|
||||
|
||||
ldx #$0400
|
||||
ldy #$0680
|
||||
lda #40*3-1
|
||||
mvn $000000,$000000
|
||||
|
||||
ldx #$0400
|
||||
ldy #$0700
|
||||
lda #40*3-1
|
||||
mvn $000000,$000000
|
||||
|
||||
ldx #$0400
|
||||
ldy #$0780
|
||||
lda #40*3-1
|
||||
mvn $000000,$000000
|
||||
|
||||
|
||||
|
||||
|
||||
* 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-1
|
||||
ldx #]1
|
||||
ldy #]2
|
||||
mvn $010000,$010000
|
||||
|
||||
lda #40-1
|
||||
ldx #]1
|
||||
ldy #]2
|
||||
mvn $000000,$000000
|
||||
|
||||
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-1
|
||||
ldx #]1
|
||||
ldy #]2
|
||||
mvn $010000,$010000
|
||||
|
||||
lda #40-1
|
||||
ldx #]1
|
||||
ldy #]2
|
||||
mvn $000000,$000000
|
||||
|
||||
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
|
||||
|
||||
sep #$20 ; short m
|
||||
|
||||
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_0 ent
|
||||
* erase cursor to end of screen.
|
||||
mx %11
|
||||
jsr erase_line_0
|
||||
php
|
||||
rep #$30
|
||||
|
||||
lda y
|
||||
inc
|
||||
cmp #24
|
||||
bcs :exit
|
||||
asl
|
||||
tay
|
||||
lda erase_char
|
||||
|
||||
:loop
|
||||
|
||||
sty r0
|
||||
ldx text,y
|
||||
ldy #19
|
||||
:loop0
|
||||
sta >$000000,x
|
||||
inx
|
||||
inx
|
||||
dey
|
||||
bpl :loop0
|
||||
|
||||
ldy r0
|
||||
ldx text,y
|
||||
ldy #19
|
||||
:loop1
|
||||
sta >$010000,x
|
||||
inx
|
||||
inx
|
||||
dey
|
||||
bpl :loop1
|
||||
|
||||
ldy r0
|
||||
iny
|
||||
iny
|
||||
cpy #24*2
|
||||
bcc :loop
|
||||
|
||||
:exit
|
||||
plp
|
||||
rts
|
||||
|
||||
erase_screen_1 ent
|
||||
* erase beginning of screen to cursor.
|
||||
mx %11
|
||||
jsr erase_line_1
|
||||
|
||||
php
|
||||
rep #$30
|
||||
|
||||
lda y
|
||||
dec
|
||||
bmi :exit
|
||||
asl
|
||||
tay
|
||||
lda erase_char
|
||||
|
||||
:loop
|
||||
|
||||
sty r0
|
||||
ldx text,y
|
||||
ldy #19
|
||||
:loop0
|
||||
sta >$000000,x
|
||||
inx
|
||||
inx
|
||||
dey
|
||||
bpl :loop0
|
||||
|
||||
ldy r0
|
||||
ldx text,y
|
||||
ldy #19
|
||||
:loop1
|
||||
sta >$010000,x
|
||||
inx
|
||||
inx
|
||||
dey
|
||||
bpl :loop1
|
||||
|
||||
ldy r0
|
||||
dey
|
||||
dey
|
||||
bpl :loop
|
||||
|
||||
|
||||
:exit
|
||||
plp
|
||||
rts
|
||||
rts
|
||||
|
||||
sav vt100.screen.L
|
|
@ -0,0 +1,77 @@
|
|||
|
||||
lst off
|
||||
rel
|
||||
xc
|
||||
xc
|
||||
|
||||
use vt.equ
|
||||
|
||||
mx %11
|
||||
|
||||
init_tabs ent
|
||||
|
||||
ldx #80-1
|
||||
:zloop stz tabs,x
|
||||
dex
|
||||
bpl :zloop
|
||||
|
||||
lda #$80
|
||||
ldy #8
|
||||
:loop ldx :table,y
|
||||
sta tabs,x
|
||||
dey
|
||||
bpl :loop
|
||||
|
||||
rts
|
||||
:table db 8*1,8*2,8*3,8*4,8*5,8*6,8*7,8*8,8*9
|
||||
|
||||
set_tab ent
|
||||
* input x = x
|
||||
|
||||
* ldx x
|
||||
cpx #80
|
||||
bge :rts
|
||||
lda #$80
|
||||
sta tabs,x
|
||||
:rts rts
|
||||
|
||||
reset_tab ent
|
||||
* input x = x
|
||||
|
||||
* ldx x
|
||||
cpx #80
|
||||
bge :rts
|
||||
stz tabs,x
|
||||
:rts rts
|
||||
|
||||
|
||||
reset_all_tabs ent
|
||||
|
||||
ldx #80-1
|
||||
:loop stz tabs,x
|
||||
dex
|
||||
bpl :loop
|
||||
rts
|
||||
|
||||
next_tab_stop ent
|
||||
* input x = x
|
||||
|
||||
* ldx x
|
||||
inx
|
||||
cpx #79
|
||||
bge :79
|
||||
|
||||
:loop bit tabs,x
|
||||
bmi :rts
|
||||
inx
|
||||
cpx #80
|
||||
bcc :loop
|
||||
|
||||
|
||||
:79 ldx #79
|
||||
:rts rts
|
||||
|
||||
|
||||
tabs ds 80
|
||||
|
||||
sav vt100.tabs.L
|
|
@ -0,0 +1,253 @@
|
|||
lst off
|
||||
|
||||
rel
|
||||
xc
|
||||
xc
|
||||
use vt.equ
|
||||
|
||||
mx %11
|
||||
|
||||
*
|
||||
* vt52 emulation for the vt100
|
||||
*
|
||||
* ESC < exits
|
||||
|
||||
|
||||
|
||||
|
||||
ext write_modem,draw_char
|
||||
ext advance_x,recalc_cursor,recalc_cursor_x,recalc_cursor_y
|
||||
ext scroll_up,scroll_down
|
||||
|
||||
vt52_esc ent
|
||||
* ABCDFGHIJKYZ<>=
|
||||
|
||||
|
||||
ldx #st_vt52
|
||||
stx state
|
||||
|
||||
cmp #:MIN
|
||||
blt :rts
|
||||
cmp #:MAX+1
|
||||
bge :rts
|
||||
sec
|
||||
sbc #:MIN
|
||||
asl
|
||||
tax
|
||||
jmp (:table,x)
|
||||
|
||||
:rts
|
||||
rts
|
||||
|
||||
|
||||
:MIN equ 60
|
||||
:MAX equ 90
|
||||
:table
|
||||
dw esc_lt ; <
|
||||
dw esc_eq ; =
|
||||
dw esc_gt ; >
|
||||
dw :rts ; ?
|
||||
dw :rts ; @
|
||||
dw esc_A ; A
|
||||
dw esc_B ; B
|
||||
dw esc_C ; C
|
||||
dw esc_D ; D
|
||||
dw :rts ; E
|
||||
dw esc_F ; F
|
||||
dw esc_G ; G
|
||||
dw esc_H ; H
|
||||
dw esc_I ; I
|
||||
dw esc_J ; J
|
||||
dw esc_K ; K
|
||||
dw :rts ; L
|
||||
dw :rts ; 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 esc_Y ; Y
|
||||
dw esc_Z ; Z
|
||||
|
||||
|
||||
|
||||
esc_lt
|
||||
* based on testing, this also resets graphics mode
|
||||
* (which we don't support anyhow.)
|
||||
lda #$80
|
||||
sta DECANM
|
||||
* stz MOUSETEXT
|
||||
lda #st_vt100
|
||||
sta state
|
||||
rts
|
||||
|
||||
|
||||
esc_eq ; enter alternate keypad mode
|
||||
lda #$80
|
||||
sta DECKPAM
|
||||
rts
|
||||
|
||||
esc_gt ; exit alternate keypad mode
|
||||
stz DECKPAM
|
||||
rts
|
||||
|
||||
* cursor movement respects the scrolling region.
|
||||
esc_A ; cursor up.
|
||||
lda y
|
||||
beq :rts
|
||||
cmp DECTM
|
||||
beq :rts
|
||||
dec y
|
||||
jmp recalc_cursor_y
|
||||
|
||||
:rts rts
|
||||
|
||||
|
||||
esc_B ; cursor down
|
||||
lda y
|
||||
cmp #23
|
||||
beq :rts
|
||||
cmp DECBM
|
||||
beq :rts
|
||||
inc y
|
||||
jmp recalc_cursor_y
|
||||
|
||||
:rts rts
|
||||
|
||||
|
||||
esc_C ; cursor right
|
||||
|
||||
lda x
|
||||
cmp #79
|
||||
bcs :rts
|
||||
inc x
|
||||
jmp recalc_cursor_x
|
||||
:rts rts
|
||||
|
||||
esc_D ; cursor left
|
||||
|
||||
lda x
|
||||
beq :rts
|
||||
and #$7f
|
||||
dec
|
||||
sta x
|
||||
jmp recalc_cursor_x
|
||||
:rts rts
|
||||
|
||||
esc_I ; cursor up w/ line scroll
|
||||
* based on testing, scrolling only occurs within the
|
||||
* scroll region.
|
||||
lda y
|
||||
cmp DECTM
|
||||
beq :scroll
|
||||
cmp #0
|
||||
beq :rts
|
||||
dec y
|
||||
jmp recalc_cursor_y
|
||||
|
||||
:scroll jmp scroll_up
|
||||
:rts rts
|
||||
|
||||
esc_J
|
||||
* erase cursor to end of screen.
|
||||
ext erase_screen_0
|
||||
jmp erase_screen_0
|
||||
rts
|
||||
esc_K
|
||||
* erase cursor to end of line
|
||||
ext erase_line_0
|
||||
jmp erase_line_0
|
||||
|
||||
esc_H ; cursor home
|
||||
; based on testing, does not respect scrolling region but does
|
||||
; respect origin mode.
|
||||
stz x
|
||||
lda DECTM
|
||||
sta y
|
||||
|
||||
:go jmp recalc_cursor
|
||||
|
||||
|
||||
esc_F ; enter graphics mode
|
||||
* lda #%0010
|
||||
* tsb mode
|
||||
lda #$80
|
||||
* tsb MOUSETEXT
|
||||
rts
|
||||
esc_G ; exit graphics mode
|
||||
* lda #%0010
|
||||
* trb mode
|
||||
* stz MOUSETEXT
|
||||
rts
|
||||
|
||||
esc_Y ; direct cursor address
|
||||
* vt100 - does not take effect until the end.
|
||||
* based on testing, there is internal state information,
|
||||
* so esc Y a esc B esc Y b is equivalent to esc Y a b
|
||||
*
|
||||
* if width exceeded, clamps at right margin.
|
||||
* if height exceeded, does not change.
|
||||
lda #st_vt52_dca
|
||||
sta state
|
||||
rts
|
||||
|
||||
esc_Z ; terminal identity.
|
||||
; return ESC / Z
|
||||
; based on testing, no display in local mode
|
||||
bit LOCAL
|
||||
bmi :local
|
||||
lda #ESC
|
||||
jsr write_modem
|
||||
lda #'/'
|
||||
jsr write_modem
|
||||
lda #'Z'
|
||||
jmp write_modem
|
||||
|
||||
:local rts
|
||||
* lda #'Z'
|
||||
* jmp draw_char
|
||||
|
||||
|
||||
|
||||
vt52_dca ent
|
||||
* this differs from esc [ H in that invalid
|
||||
* values are ignored rather than clamped.
|
||||
* based on testing, does not respect DECOM.
|
||||
* based on testing, state is saved if ESC aborts, even
|
||||
* if switching to vt100 mode and back or ^X to cancel.
|
||||
|
||||
sec
|
||||
sbc #' '
|
||||
|
||||
bit :tmp
|
||||
bmi :go
|
||||
ora #$80
|
||||
sta :tmp
|
||||
rts
|
||||
|
||||
:go ; a = x
|
||||
cmp #80
|
||||
bge :y
|
||||
sta x
|
||||
:y lda :tmp
|
||||
and #$7f
|
||||
cmp #24
|
||||
bge :update
|
||||
sta y
|
||||
:update
|
||||
stz :tmp
|
||||
lda #st_vt52
|
||||
sta state
|
||||
jmp recalc_cursor
|
||||
|
||||
|
||||
:tmp ds 2
|
||||
|
||||
|
||||
sav vt100.vt52.L
|
131
vt52.S
131
vt52.S
|
@ -21,6 +21,7 @@ START equ *
|
|||
*
|
||||
*
|
||||
|
||||
ESC equ $1b
|
||||
|
||||
|
||||
SET80VID equ $c00d
|
||||
|
@ -159,7 +160,7 @@ keypress
|
|||
:remap
|
||||
lda :arrowtable+1,x
|
||||
sta key
|
||||
lda #$1b
|
||||
lda #ESC
|
||||
jsr dispatch
|
||||
bra :ctrl
|
||||
|
||||
|
@ -187,41 +188,104 @@ keypress
|
|||
rts
|
||||
|
||||
keypad
|
||||
* 0-9, Enter, . PF1-3 are the only valid keypad keys
|
||||
|
||||
lda mode
|
||||
bit #mAltKeyPad
|
||||
beq :normal
|
||||
lda key
|
||||
cmp #'0'
|
||||
bcc :notnum
|
||||
cmp #'9'+1
|
||||
bcs :notnum
|
||||
:qq
|
||||
* 0-9 sends ESC ? p-y which is num | 0x40
|
||||
lda #$1b
|
||||
jsr dispatch
|
||||
lda #'?'
|
||||
jsr dispatch
|
||||
lda key
|
||||
ora #$40
|
||||
jmp dispatch
|
||||
:notnum
|
||||
cmp #$0d
|
||||
beq :qq
|
||||
cmp #'.'
|
||||
beq :qq
|
||||
|
||||
|
||||
cmp #:MIN
|
||||
bcc :rts
|
||||
cmp #:MAX+1
|
||||
bcc :ok
|
||||
:rts rts
|
||||
:ok
|
||||
tay ; save
|
||||
sec
|
||||
sbc #:MIN
|
||||
tax
|
||||
lda :table,x
|
||||
beq :rts ; dead
|
||||
bmi :normal
|
||||
:pf
|
||||
bit mode ; don't bother in local mode
|
||||
bmi :rts
|
||||
pha ; save
|
||||
lda #ESC
|
||||
jsr write_modem
|
||||
pla ; restore
|
||||
jmp write_modem
|
||||
|
||||
:normal
|
||||
* todo - PF1/2/3 should send ESC P/Q/R
|
||||
lda key
|
||||
; y still has key value
|
||||
lda mode
|
||||
and #mAltKeyPad
|
||||
bne :alt
|
||||
tya
|
||||
jmp dispatch
|
||||
:alt
|
||||
phy ; save
|
||||
bit mode
|
||||
bmi :local
|
||||
lda #ESC
|
||||
jsr write_modem
|
||||
lda #'?'
|
||||
jsr write_modem
|
||||
:local
|
||||
pla
|
||||
ora #$40
|
||||
jmp dispatch
|
||||
|
||||
:table db $1b,'P'
|
||||
db '=','Q'
|
||||
db '/','R'
|
||||
:MIN equ 13
|
||||
:MAX equ 61
|
||||
|
||||
|
||||
; 0x80 = ESC ? c + $40 in alt mode
|
||||
:table
|
||||
db $80 ; ^M Enter -> \r, ESC ? M
|
||||
db $0 ; ^N
|
||||
db $0 ; ^O
|
||||
db $0 ; ^P
|
||||
db $0 ; ^Q
|
||||
db $0 ; ^R
|
||||
db $0 ; ^S
|
||||
db $0 ; ^T
|
||||
db $0 ; ^U
|
||||
db $0 ; ^V
|
||||
db $0 ; ^W
|
||||
db $0 ; ^X
|
||||
db $0 ; ^Y
|
||||
db $0 ; ^Z
|
||||
db 'P' ; ^[ PF1 -> ESC P
|
||||
db $0 ; ^\
|
||||
db $0 ; ^]
|
||||
db $0 ; ^^
|
||||
db $0 ; ^_
|
||||
db $0 ;
|
||||
db $0 ; !
|
||||
db $0 ; "
|
||||
db $0 ; #
|
||||
db $0 ; $
|
||||
db $0 ; %
|
||||
db $0 ; &
|
||||
db $0 ; '
|
||||
db $0 ; (
|
||||
db $0 ; )
|
||||
db $0 ; *
|
||||
db $0 ; +
|
||||
db $0 ; ,
|
||||
db $0 ; -
|
||||
db $80 ; .
|
||||
db 'R' ; / PF3 -> ESC R
|
||||
db $80 ; 0
|
||||
db $80 ; 1
|
||||
db $80 ; 2
|
||||
db $80 ; 3
|
||||
db $80 ; 4
|
||||
db $80 ; 5
|
||||
db $80 ; 6
|
||||
db $80 ; 7
|
||||
db $80 ; 8
|
||||
db $80 ; 9
|
||||
db $0 ; :
|
||||
db $0 ; ;
|
||||
db $0 ; <
|
||||
db 'Q' ; = PF2 -> ESC Q
|
||||
|
||||
|
||||
|
||||
|
@ -480,7 +544,6 @@ clear_eol
|
|||
sta [text01],y
|
||||
sta (text00),y
|
||||
iny
|
||||
cpy #40
|
||||
bra :even
|
||||
:rts plp
|
||||
rts
|
||||
|
@ -842,7 +905,7 @@ ctrl_1b ; escape -
|
|||
ctrl_09 ; tab
|
||||
|
||||
lda x
|
||||
cmp #73
|
||||
cmp #72
|
||||
bcs :one
|
||||
|
||||
clc
|
||||
|
@ -958,7 +1021,7 @@ esc_Z ; identify terminal.
|
|||
; return ESC / K
|
||||
bit mode
|
||||
bmi :local
|
||||
lda #$1b
|
||||
lda #ESC
|
||||
jsr write_modem
|
||||
lda #'/'
|
||||
jsr write_modem
|
||||
|
|
Loading…
Reference in New Issue