-
Notifications
You must be signed in to change notification settings - Fork 0
/
vt100.esc.S
320 lines (262 loc) · 4.55 KB
/
vt100.esc.S
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
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