-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathWHICHCGA.ASM
484 lines (415 loc) · 9.59 KB
/
WHICHCGA.ASM
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
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
org 0x100
%include "../defaults_common.asm"
demoAPI EQU 0F8h
; Determine if loader is present, and abort if not
; First, check to see if the API is even present.
; If not, don't try to call anything since it will hang the system.
xor bx,bx
mov es,bx
mov di,(demoAPI * 4)+2 ;check to see if our INT is empty
cmp [word es:di],bx ;int. vector empty?
je exitShort ;abort if so
mov ax,0700h ;check int. vector to see if it's ours
int demoAPI
cmp ax,0C0DEh ;magic cookie received?
jne exitShort ;abort if not
jmp mstart
exitShort:
jmp exitEffect
mstart:
mov ax,1
int 0x10
mov ax,0xb800
mov es,ax
mov ax,cs
mov si,which_cga
xor di,di
mov cx,40*192
cld
rep movsw
mov cx,8192-40*192
xor ax,ax
rep stosw
; Mode 08
; 1 +HRES 0
; 2 +GRPH 0
; 4 +BW 0
; 8 +VIDEO ENABLE 8
; 0x10 +1BPP 0
; 0x20 +ENABLE BLINK 0
mov dx,0x3d8
mov al,0x08
out dx,al
; Palette 00
; 1 +OVERSCAN B 0
; 2 +OVERSCAN G 0
; 4 +OVERSCAN R 0
; 8 +OVERSCAN I 0
; 0x10 +BACKGROUND I 0
; 0x20 +COLOR SEL 0
mov dx,0x3d9
mov al,0
out dx,al
mov dx,0x3d4
; 0xff Horizontal Total 38
mov ax,0x3800
out dx,ax
; 0xff Horizontal Displayed 28
mov ax,0x2801
out dx,ax
; 0xff Horizontal Sync Position 2d
mov ax,0x2d02
out dx,ax
; 0x0f Horizontal Sync Width 0a
mov ax,0x0a03
out dx,ax
; 0x7f Vertical Total 3e
mov ax,0x3e04
out dx,ax
; 0x1f Vertical Total Adjust 00
mov ax,0x0005
out dx,ax
; 0x7f Vertical Displayed 02
mov ax,0x0206
out dx,ax
; 0x7f Vertical Sync Position 19
mov ax,0x1a07
out dx,ax
; 0x03 Interlace Mode 02
mov ax,0x0208
out dx,ax
; 0x1f Max Scan Line Address 00
mov ax,0x0009
out dx,ax
; Cursor Start 06
; 0x1f Cursor Start 6
; 0x60 Cursor Mode 0
mov ax,0x060a
out dx,ax
; 0x1f Cursor End 07
mov ax,0x070b
out dx,ax
; 0x3f Start Address (H) 00
mov ax,0x000c
out dx,ax
; 0xff Start Address (L) 00
mov ax,0x000d
out dx,ax
; 0x3f Cursor (H) 03
mov ax,0x030e
out dx,ax
; 0xff Cursor (L) c0
mov ax,0xc00f
out dx,ax
mov dl,0xda
mov cx,5*60
whichFrameLoop:
waitForVerticalSync
waitForNoVerticalSync
cli
; During line 0-1 we set up the start address for line 2 and change the vertical total to 0x01
waitForDisplayEnable
mov dl,0xd4
mov ax,0x0104 ; 4: Vertical total: 2 rows/frame
out dx,ax
mov dl,0xda ; 2 0 2
waitForDisplayDisable
waitForDisplayEnable
mov dl,0xd4
mov ax,0x000c
out dx,ax
mov ax,0x500d
out dx,ax
mov dl,0xda ; 2 0 2
waitForDisplayDisable
; During lines 2..197 we set up the start address for the next line
push cx
mov cx,98
mov bx,0x00a0
whichRowLoop:
waitForDisplayEnable
waitForDisplayDisable
waitForDisplayEnable
mov dl,0xd4
mov ah,bh
mov al,0x0c
out dx,ax
mov ah,bl
inc ax
out dx,ax
mov dl,0xda ; 2 0 2
waitForDisplayDisable
add bx,0x50
loop whichRowLoop
pop cx
; During line 198 we set up the start address for line 0 and change the vertical total to 0x3e
waitForDisplayEnable
mov dl,0xd4
mov ax,0x3e04 ; 4: Vertical total: 63 rows/frame
out dx,ax
mov dl,0xda
waitForDisplayDisable
waitForDisplayEnable
mov dl,0xd4
mov ax,0x000c
out dx,ax
inc ax
out dx,ax
mov dl,0xda
waitForDisplayDisable
sti
loop whichFrameLoop1
jmp whichDone
whichFrameLoop1:
jmp whichFrameLoop
whichDone:
mov ax,3
int 0x10
lockstep
refreshOn
initCGA 9,0,2
sti
mov ax,0xb800
mov es,ax
mov ax,cs
mov ds,ax
mov si,screenData
xor di,di
mov cx,80*100
rep movsw
xor bp,bp ; 1 for switch phase
mov bh,0
resetVars:
mov cx,0x1400 ; cl = border colour index (0..15), ch = (hsync width << 1) | phase (0..33)
mov byte[model],0
call setModel
xor si,si ; si = frames since last keypress
mov dx,0x3da
jmp noSwitchPhase2
rasterLoop:
waitForDisplayEnable
cmp bp,1
jne noSwitchPhase
xor bp,bp
mov dl,0xd4
mov ax,0x7200
out dx,ax
mov dl,0xda
waitForDisplayDisable
waitForDisplayEnable
mov dl,0xd4
mov ax,0x7100
out dx,ax
mov dl,0xda
noSwitchPhase:
waitForVerticalSync
mov dl,ch
mov ah,1
int 0x16
jnz gotKeypress
jmp doneKey
gotKeypress:
xor si,si
mov ah,0
int 0x16
push ax
xor di,di
mov ah,2
int 0x16
test al,3
jz notShifted
mov di,shiftUpTable - upTable
notShifted:
pop ax
mov bh,0
cmp al,0x0d
jne notEnter
jmp doneCalibration
notEnter:
cmp al,0x20
jne notSpace
xor byte[model],1
call setModel
notSpace:
cmp ah,0x48
jne notUp
mov bl,ch
mov ch,[bx+di+upTable]
jmp doneKey
notUp:
cmp ah,0x50
jne notDown
mov bl,ch
mov ch,[bx+di+downTable]
jmp doneKey
notDown:
cmp ah,0x4b
jne notLeft
mov bl,cl
mov cl,[bx+di+leftTable]
jmp doneKey
notLeft:
cmp ah,0x4d
jne doneKey
mov bl,cl
mov cl,[bx+di+rightTable]
doneKey:
xor dl,ch
test dl,1
jz noSwitchPhase2
mov bp,1
noSwitchPhase2:
push si
mov bl,ch
add bl,bl
mov si,[bx+hsyncTable]
mov di,138+14*160
call plotCharacter
mov bl,ch
add bl,bl
mov si,[bx+phaseTable]
mov di,146+14*160
call plotCharacter
mov bl,cl
add bl,bl
mov si,[bx+borderTable]
mov di,138+20*160
call plotCharacter
pop si
mov dl,0xd9
mov al,cl
out dx,al
mov dl,0xd4
mov al,3
mov ah,ch
shr ah,1
out dx,ax
mov dl,0xda
inc si
cmp si,15*60
jl noResetVars
xor bp,bp
xor si,si
test ch,1
jz resetVars2
mov bp,1
resetVars2:
jmp resetVars
noResetVars:
jmp rasterLoop
doneCalibration:
initCGA 1
; Set background color and hsync width values to loader API
mov ah,3
int demoAPI
mov [si+25],cl ; background color
mov al,ch
shr al,1
mov [si+24],al ; hsync width
and ch,1
mov [si+26],ch ; phase
mov al,[cs:model]
mov [si+27],al ; model
exitEffect:
ret
plotCharacter:
movsw
movsw
movsw
add si, 160-6
add di, 160-6
movsw
movsw
movsw
add si, 160-6
add di, 160-6
movsw
movsw
movsw
add si, 160-6
add di, 160-6
movsw
movsw
movsw
ret
setModel:
push si
push cx
cmp byte[model],0
je setOldModel
mov si,slice_new
mov di,39*160
mov cx,36*80
rep movsw
mov si,slice_newtext
mov di,8*160+138
mov cx,9
rep movsw
add di,160-9*2
mov cx,9
rep movsw
add di,160-9*2
mov cx,9
rep movsw
add di,160-9*2
mov cx,9
rep movsw
jmp doneSetModel
setOldModel:
mov si,screenData + 39*160
mov di,39*160
mov cx,36*80
rep movsw
mov si,screenData + 8*160+138
mov di,8*160+138
mov cx,9
rep movsw
add si,160-9*2
add di,160-9*2
mov cx,9
rep movsw
add si,160-9*2
add di,160-9*2
mov cx,9
rep movsw
add si,160-9*2
add di,160-9*2
mov cx,9
rep movsw
doneSetModel:
pop cx
pop si
ret
model: db 0 ; 0 for old, 1 for new
; hsync position = 138, 8
; phase position = 146, 8
; border position= 138, 13
c0 equ screenData + 160*113
ca equ screenData + 160*101
slice_new equ screenData + 160*118
slice_newtext equ slice_new + 160*36
which_cga equ slice_newtext + 72
hsyncTable:
dw c0, c0, c0+6, c0+6, c0+12, c0+12, c0+18, c0+18, c0+24, c0+24, c0+30, c0+30, c0+36, c0+36, c0+42, c0+42, c0+48, c0+48, c0+54, c0+54, ca, ca, ca+6, ca+6, ca+12, ca+12, ca+18, ca+18, ca+24, ca+24, ca+30, ca+30
phaseTable:
dw c0, c0+6, c0, c0+6, c0, c0+6, c0, c0+6, c0, c0+6, c0, c0+6, c0, c0+6, c0, c0+6, c0, c0+6, c0, c0+6, c0, c0+6, c0, c0+6, c0, c0+6, c0, c0+6, c0, c0+6, c0, c0+6
borderTable:
dw c0, c0+6, c0+12, c0+18, c0+24, c0+30, c0+36, c0+42, c0+48, c0+54, ca, ca+6, ca+12, ca+18, ca+24, ca+30
; 0 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
upTable:
db 1, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 0
downTable:
db 31, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30
leftTable:
db 15, 0, 0, 0, 0, 0, 0, 6, 7, 8, 8, 8, 8, 8, 8, 14
rightTable:
db 6, 6, 6, 6, 6, 6, 7, 8, 14, 14, 14, 14, 14, 14, 15, 0
shiftUpTable:
db 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 34, 25, 26, 27, 28, 29, 30, 31, 0
shiftDownTable:
db 31, 0, 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
shiftLeftTable:
db 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14
shiftRightTable:
db 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0
screenData: