OpenCores
URL https://opencores.org/ocsvn/next186_soc_pc/next186_soc_pc/trunk

Subversion Repositories next186_soc_pc

[/] [next186_soc_pc/] [trunk/] [SW/] [BIOS_Next186/] [BIOS_Next186.asm] - Blame information for rev 3

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 ndumitrach
; This file is part of the Next186 SoC PC project
2
; http://opencores.org/project,next186
3
 
4
; Filename: BIOS_Next186.asm
5
; Description: Part of the Next186 SoC PC project, ROM BIOS code
6
; Version 1.0
7
; Creation date: Feb-Jun 2013
8
 
9
; Author: Nicolae Dumitrache
10
; e-mail: ndumitrache@opencores.org
11
 
12
; -------------------------------------------------------------------------------------
13
 
14
; Copyright (C) 2013 Nicolae Dumitrache
15
 
16
; This source file may be used and distributed without
17
; restriction provided that this copyright statement is not
18
; removed from the file and that any derivative work contains
19
; the original copyright notice and the associated disclaimer.
20
 
21
; This source file is free software; you can redistribute it
22
; and/or modify it under the terms of the GNU Lesser General
23
; Public License as published by the Free Software Foundation;
24
; either version 2.1 of the License, or (at your option) any
25
; later version.
26
 
27
; This source is distributed in the hope that it will be
28
; useful, but WITHOUT ANY WARRANTY; without even the implied
29
; warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
30
; PURPOSE. See the GNU Lesser General Public License for more
31
; details.
32
 
33
; You should have received a copy of the GNU Lesser General
34
; Public License along with this source; if not, download it
35
; from http://www.opencores.org/lgpl.shtml
36
 
37
; -----------------------------------------------------------------------
38
 
39
; Additional Comments:
40
; Assembled with MASM v6.14.8444
41
; Next186 SoC PC have no ROM, only RAM. The bootstrap code is the initial value of cache
42
;  (last half 1K = 4 lines of 256bytes each), initially marked as "dirty", in order to
43
;  be saved in RAM at first flush
44
; The bootstrap code may load the BIOS from SD, or from RS232, and place it at F000:E000
45
 
46
 
47
 
48
.186
49
.model tiny
50
.code
51
 
52
SCANCODE1   equ 1
53
 
54
;-------------------------- BIOS data area (BDA) -----------------
55
;40:0000   2  Base port address of first RS-232 adapter (COM1) See COM Ports
56
;40:0002   2  Port of COM2
57
;40:0004   2  Port of COM3
58
;40:0006   2  Port of COM4
59
;40:0008   2  Base port addr of first parallel printer (LPT1)  Printer Ports
60
;40:000A   2  Port of LPT2
61
;40:000C   2  Port of LPT3
62
;40:000E   2  Port of LPT4
63
;40:0010   2  Equipment/hardware installed/active; see Equipment List
64
;40:0012   1  Errors in PCjr infrared keyboard link
65
;40:0013   2  Total memory in K-bytes (same as obtained via INT 12H)
66
;40:0015   2  Scratch pad for manufacturing error tests
67
;
68
;40:0017   2  Keyboard status bits; see Keyboard Shift Status Flags
69
;40:0019   1  Current (accumulating) value of Alt+numpad pseudo-key input;
70
;             normally 0.  When [Alt] is released, value is stored in
71
;             keyboard buffer at 001e.
72
;40:001a   2  Addr of keyboard buffer head (keystroke at that addr is next)
73
;40:001c   2  Address of keyboard buffer tail
74
;40:001e  32  Keyboard buffer.  BIOS stores keystrokes here (head and tail
75
;             point to addresses from 041eH to 043dH inclusive).
76
;
77
;40:003e   1  Diskette drive needs recalibration (bit 0=A, bit 1=B, etc.)
78
;             bits 4-5 indicate which drive is currently selected
79
;40:003f   1  Diskette motor is running (bit 0=drive A, bit 1=B, etc.)
80
;40:0040   1  Time until motor off. INT 08H turns motor off when this is 0.
81
;40:0041   1  Diskette error status; same as status returned by INT 13H
82
;40:0042   7  Diskette controller status information area
83
;
84
;40:0049   1  Current active video mode.  See Video Modes and INT 10H.
85
;40:004a   2  Screen width in text columns
86
;40:004c   2  Length (in bytes) of video area (regen size)
87
;40:004e   2  Offset from video segment of active video memory page
88
;40:0050  16  Cursor location (8 byte-pairs; low byte=clm, hi byte=row)
89
;40:0060   2  Cursor size/shape.  Low byte=end scan line; hi byte=start line.
90
;40:0062   1  Current active video page number
91
;40:0063   2  Port address for 6845 video controller chip; see CGA I/O Ports
92
;40:0065   1  Current value of 6845 video ctrlr CRT_MODE (port 3x8H register)
93
;40:0066   1  Current value of 6845 video ctrlr CRT_PALETTE (port 3x9H reg)
94
;
95
;40:0067   5  Cassette data area or POST data area
96
;               40:0067: 1 byte mouse buffer counter (DataCounter)
97
;               40:0068: 1 byte mouse packet size (PacketSize): 0 for 3 bytes, 1 for 4 bytes (Intellimouse)
98
;               40:0069: 1 byte palette paging status
99
;               40:006a: 1 byte PalPagingCounter - guards pal paging re-entrance
100
;
101
;40:006c   4  Timer tick counter (count of 55ms ticks since CPU reset)
102
;40:0070   1  Timer overflow flag (timer has rolled over 24 hr)
103
;40:0071   1  Ctrl-Break flag.  Bit 7=1 when break was pressed.  This never
104
;             gets reset unless you do it yourself.
105
;
106
;40:0072   2  1234H means Ctrl+Alt+Del reboot is in progress.  BIOS checks
107
;             this to avoid doing a "cold boot" with the time-consuming POST
108
;             4321H means reset, preserving memory
109
;             5678H, 9abcH, and abcdH (are internal PC Convertible codes)
110
;
111
;40:0074   4  PCjr diskette or AT hard disk control area
112
;  (0074)   1 Status of last fixed-disk drive operation
113
;  (0075)   1 Number of hard disk drives for AT
114
;  (0077)   1 Hard disk port for XT.  See XT Hard Disk Ports.
115
;40:0078   4  Printer time-out values (478H=Lpt1, 478H=Lpt2...)
116
;40:007c   4  RS-232 time-out values  (47cH=Com1, 47dH=Com2...)
117
;
118
;40:0080   2  AT PS/2 keyboard buffer offset start address (usually 01eH)
119
;40:0082   2                                   end address (usually 003eH)
120
;
121
;40:0084   1  EGA text rows-1  (maximum valid row value)
122
;40:0085   2  EGA bytes per character (scan-lines/char used in active mode)
123
;40:0087   1  EGA flags; see EgaMiscInfoRec
124
;40:0088   1  EGA flags; see EgaMiscInfo2Rec
125
;40:0089   1  VGA flags; see VgaFlagsRec
126
;             See also:  EGA/VGA Data Areas
127
;
128
;40:008b   1  AT PS/2 Media control: data rate, step rate
129
;40:008c   1  AT PS/2 Hard disk drive controller status
130
;40:008d   1  AT PS/2 Hard disk drive error status
131
;40:008e   1  AT PS/2 Hard disk drive interrupt control
132
;
133
;40:0090   1  AT PS/2 Disk media state bits for drive 0
134
;40:0091   1                                for drive 1
135
;40:0092   1  AT PS/2 Disk operation started flag for drive 0
136
;40:0093   1                                      for drive 1
137
 
138
;40:0094   1  AT PS/2 Present cylinder number for drive 0
139
;40:0095   1                                  for drive 1
140
        ; 2 - Number of 512bytes sectors of HD0
141
;
142
;40:0096   1  AT Keyboard flag bit 4=1 (10H) if 101-key keyboard is attached
143
;40:0097   1  AT Keyboard flag for LED 'key lock' display
144
;             bits 0-2 are ScrollLock, NumLock, CapsLock
145
;
146
;40:0098   4  AT Pointer to 8-bit user wait flag; see INT 15H 86H
147
;40:009c   4  AT Microseconds before user wait is done
148
;40:00a0   1  AT User wait activity flag:
149
;                01H=busy, 80H=posted, 00H=acknowledged
150
;
151
;40:00a1   7  AT Reserved for network adapters
152
;               40:00a1: 4 bytes far pointer to mouse callback (HandlerPtr)
153
;               40:00a5: 3 bytes mouse buffer (DataBuffer)
154
;
155
;40:00a8   4  EGA Address of table of pointers; see EgaSavePtrRec
156
;40:00ac  68  Reserved
157
;40:00f0  16  (IAC) Inter-Aapplication Communication area.  Programs may use
158
;             this area to store status, etc.  Might get overwritten by
159
;             another program.
160
 
161
; http://www.ctyme.com/intr/int.htm
162
 
163
; video memory: 8 physical segments at 0a000h, 0b000h, 0c000h, 0d000h, 0e000h, 0f000h, 10000h, 11000h
164
; Memory segments mapping
165
; 1Mb virtual seg address   physical seg address
166
;       0000h                   0000h
167
;       1000h                   1000h
168
;       2000h                   2000h
169
;       3000h                   3000h
170
;       4000h                   4000h
171
;       5000h                   5000h
172
;       6000h                   6000h
173
;       7000h                   7000h
174
;       8000h                   8000h
175
;       9000h                   9000h
176
;       a000h                   a000h       - video
177
;       b000h                   b000h       - video
178
;       c000h                   12000h
179
;       d000h                   13000h
180
;       e000h                   14000h
181
;       f000h                   15000h
182
 
183
 
184
        org 0e000h
185
bios:
186
biosmsg     db 'Next186 Spartan3AN SoC PC BIOS (C) 2013 Nicolae Dumitrache', 0
187
msgmb       db 'MB SD Card', 13, 10, 0
188
msgkb       db 'PS2 KB detected', 13, 10, 0
189
 
190
 
191
; Graphics character set
192
font8x8:         ; TODO define and place font
193
font8x16:        ; TODO define and place font
194
 
195
        org 0e05bh
196
coldboot:
197
warmboot:
198
        cli
199
        cld
200
        mov     ax, 30h
201
        mov     ss, ax
202
        mov     sp, 100h
203
 
204
        push    0
205
        popf
206
 
207
        mov     al, 36h
208
        out     43h, al
209
        xor     ax, ax
210
        out     40h, al
211
        out     40h, al      ; 18Hz PIT CH0
212
        out     61h, al      ; speaker off
213
        not     al
214
        out     21h, al      ; disable all interrupts
215
 
216
 
217
; ------------------ MAP init
218
        call    flush
219
        mov     ax, 15h     ; BIOS physical segment 15h mapped on virtual segment 0ch
220
        out     8ch, ax
221
        push    0c000h
222
        pop     es
223
        push    0f000h
224
        pop     ds
225
        xor     si, si
226
        xor     di, di
227
        mov     cx, 8000h
228
        rep     movsw       ; copy BIOS virtual segment 0fh over physical segment 15h
229
 
230
        call    flush
231
        mov     dx, 80h
232
        xor     ax, ax
233
mapi:
234
        out     dx, ax
235
        inc     ax
236
        inc     dx
237
        cmp     al, 0ch
238
        jne     short mapi1
239
        add     al, 6
240
mapi1:
241
        cmp     al, 16h
242
        jne     short mapi
243
 
244
; -------------------- Interrupt table init
245
        push    0
246
        pop     ds
247
        push    ds
248
        pop     es
249
        xor     si, si
250
        mov     di, 4
251
        mov     word ptr [si], offset defint
252
        mov     word ptr [si+2], cs
253
        mov     cx, 256-2
254
        rep     movsw
255
        mov     word ptr ds:[7*4], offset int07
256
        mov     word ptr ds:[8*4], offset int08
257
        mov     word ptr ds:[9*4], offset int09
258
        mov     word ptr ds:[10h*4], offset int10
259
        mov     word ptr ds:[11h*4], offset int11
260
        mov     word ptr ds:[12h*4], offset int12
261
        mov     word ptr ds:[13h*4], offset int13
262
        mov     word ptr ds:[15h*4], offset int15
263
        mov     word ptr ds:[16h*4], offset int16
264
        mov     word ptr ds:[18h*4], offset int18
265
        mov     word ptr ds:[19h*4], offset int19
266
        mov     word ptr ds:[1ah*4], offset int1a
267
        mov     word ptr ds:[70h*4], offset int70
268
        mov     word ptr ds:[74h*4], offset int74
269
 
270
; ------------------- BDA init
271
        push    40h
272
        pop     ds
273
        push    ds
274
        pop     es
275
        xor     di, di
276
        xor     si, si
277
        xor     ax, ax
278
        mov     cl, 80h
279
        rep     stosw
280
        mov     byte ptr [si+10h], 24h   ; equipment word (color 80x25, PS2 mouse present)
281
        mov     word ptr [si+13h], 640   ; memory size in KB
282
        add     word ptr [si+1ah], 1eh   ; next char pointer in kb buffer
283
        add     word ptr [si+1ch], 1eh   ; last char pointer in kb buffer
284
        mov     word ptr [si+60h], 0e0fh ; cursor shape
285
        mov     word ptr [si+63h], 3d4h  ; video port address
286
        add     word ptr [si+80h], 1eh   ; start kb buffer
287
        add     word ptr [si+82h], 3eh   ; end kb buffer
288
        mov     word ptr [si+87h], 0940h ; video adapter options (512Kb video)
289
        mov     word ptr [si+89h], 0b71h ; VGA video flags: 400 line text mode, default palette loading on (0), blinking on
290
        mov     byte ptr [si+96h], 10h   ; 101 keyboard installed
291
 
292
; ------------------- Graph mode init
293
        mov     ax, 3
294
        int     10h
295
 
296
 ; ------------------- KB init ----------------
297
        mov     al, 0aeh
298
        out     64h, al     ; enable kb
299
        mov     al, 0a7h
300
        out     64h, al     ; disable mouse
301
        mov     cx, 25
302
kbi1:
303
        call    getps2byte
304
        loop    short kbi1  ; wait for kb timeout
305
        mov     ah, 0ffh    ; reset kb
306
        clc                 ; kb command
307
        call    sendcmd
308
        jc      short nokb
309
        mov     cl, 25
310
kbi2:
311
        dec     cx
312
        jcxz    short nokb
313
        call    getps2byte
314
        jc      short kbi2  ; wait for BAT
315
        cmp     al, 0aah
316
        jne     short nokb
317
        mov     ah, 0f2h    ; kb id
318
        call    sendcmd     ; CF = 0
319
        jc      short nokb
320
        call    getps2byte
321
        cmp     al, 0abh
322
        jne     short nokb
323
        call    getps2byte
324
        cmp     al, 83h
325
; set scan code 1
326
IFDEF SCANCODE1
327
        jne     short nokb
328
        mov     ah, 0f0h    ; kb scan set
329
        call    sendcmd
330
        jc      short nokb
331
        mov     ah, 1       ; scan set 1
332
        call    sendcmd
333
        jnc     short kbok
334
ELSE
335
        je     short kbok
336
ENDIF
337
 
338
nokb:
339
        mov     byte ptr KbdFlags3, 0   ; kb not present
340
kbok:
341
        mov     al, 0adh
342
        out     64h, al      ; disable kb interface
343
 
344
; ------------------- Mouse init ----------------
345
        mov     al, 0a8h
346
        out     64h, al      ; enable mouse
347
mousei0:
348
        call    getps2byte
349
        jnc     short mousei0
350
        mov     ah, 0ffh
351
        call    sendcmd      ; reset mouse (CF = 1)
352
        jc      short nomouse
353
        mov     cl, 25
354
mousei1:
355
        dec     cx
356
        jcxz    short nomouse
357
        call    getps2byte
358
        jc      short mousei1
359
        cmp     al, 0aah     ; BAT
360
        jne     short nomouse
361
        call    getps2byte
362
        cmp     al, 0        ; mouse ID
363
        je      short mouseok
364
nomouse:
365
        mov     al, 0a7h
366
        out     64h, al      ; disable mouse
367
        and     byte ptr EquipmentWord, not 4 ; ps2 mouse not present in equipement word
368
mouseok:
369
        call    enableKbIfPresent
370
 
371
        mov     al, 20h
372
        out     64h, al
373
        in      al, 60h
374
        or      al, 3
375
        mov     ah, al
376
        mov     al, 60h
377
        out     64h, al
378
        mov     al, ah
379
        out     60h, al     ; enable 8042 mouse and kb interrupts
380
 
381
        mov     ax,1000-1   ; 1ms
382
        out     70h, ax     ; set RTC frequency
383
 
384
        mov     al, 0e4h
385
        out     21h, al     ; enable all PIC interrupts (8h, 9h, 70h, 74h)
386
        sti                 ; enable CPU interrupts
387
 
388
; ---------------------   HDD init
389
        call    sdinit
390
        mov     HDSize, ax
391
        push    cs
392
        pop     es
393
        mov     si, offset biosmsg
394
        call    prts
395
        mov     si, offset bioscont
396
        call    prts
397
        mov     ax, HDSize
398
        shr     ax, 1
399
        call    dispAX
400
        mov     si, offset msgmb
401
        call    prts
402
        test    byte ptr KbdFlags3, 10h
403
        jz      nokbmsg
404
        mov     si, offset msgkb
405
        call    prts
406
nokbmsg:
407
        test    byte ptr EquipmentWord, 4
408
        jz      nomousemsg
409
        mov     si, offset msgmouse
410
        call    prts
411
nomousemsg:
412
 
413
;-------------- HD bootstrap
414
        mov     ax, 305h
415
        xor     bx, bx
416
        int     16h     ; set typematic rate and delay to fastest
417
        int     19h
418
 
419
msgmouse    db 'PS2 Mouse detected', 13, 10, 0
420
bioscont    db 13, 10, 'CPU: 80186 33Mhz (33MIPS, 66Mhz 32bit bus)', 13, 10
421
            db 'RAM: 64MB DDR2 133Mhz', 13, 10
422
            db 'Cache: 8x256 bytes data/inst', 13, 10
423
            db 'HD0: ', 0
424
 
425
; ---------------------------- INT 07 ---------------------
426
int07 proc near ; coprocessor ESC sequence
427
        push    ax
428
        push    bx
429
        push    ds
430
        push    bp
431
        mov     bp, sp
432
        lds     bx, [bp+8]
433
int07_pfx:
434
        mov     al, [bx]
435
        inc     bx
436
        and     al, 0f8h
437
        cmp     al, 0d8h        ; ESC code
438
        jne     short int07_pfx
439
 
440
        cmp     byte ptr [bx], 0c0h ; mod reg r/m of ESC 8087 instruction
441
        sbb     al, al
442
        and     al, [bx]
443
        and     ax, 0c7h
444
        cmp     al, 6
445
        jne     int072
446
        mov     al, 80h
447
int072:
448
        shr     al, 6
449
        inc     ax
450
        add     ax, bx
451
        mov     [bp+8], ax
452
        pop     bp
453
        pop     ds
454
        pop     bx
455
        pop     ax
456
        iret
457
int07 endp
458
 
459
 
460
; ---------------------------- INT 08 ---------------------
461
int08 proc near
462
        push    ds
463
        push    bx
464
        push    40h
465
        pop     ds
466
        mov     bx, 6ch
467
        add     word ptr [bx], 1
468
        adc     word ptr [bx+2], 0
469
        cmp     word ptr [bx+2], 18h
470
        jne     short int081
471
        cmp     word ptr [bx], 0b0h
472
        jne     short int081
473
        mov     word ptr [bx], 0
474
        mov     word ptr [bx+2], 0
475
        mov     byte ptr [bx+4], 1
476
int081:
477
        int     1ch
478
        sti
479
        push    ax
480
        mov     ah, 4
481
kloop:
482
        in      al, 64h
483
        test    al, 1
484
        jz      short nokey
485
        dec     ah
486
        jnz     short kloop
487
        test    al, 20h
488
        jz      short kbdata
489
        int     74h
490
        jmp     short nokey
491
kbdata:
492
        int     9h
493
nokey:
494
        pop     ax
495
        pop     bx
496
        pop     ds
497
        iret
498
int08 endp
499
 
500
; --------------------- INT 09 - keyboard ------------------
501
KbdFlags1       equ     
502
KbdFlags2       equ     
503
AltKpd          equ     
504
CtrlBreak       equ     
505
KbdFlags3       equ     
506
KbdFlags4       equ     
507
 
508
; Bits for the KbdFlags1
509
RShfDown        equ     1
510
LShfDown        equ     2
511
CtrlDown        equ     4
512
AltDown         equ     8
513
ScrLock         equ     10h
514
NumLock         equ     20h
515
CapsLock        equ     40h
516
Insert          equ     80h
517
 
518
; Bits for the KbdFlags2
519
LCtrDown        equ     1
520
LAltDown        equ     2
521
SysReqDown      equ     4
522
Pause           equ     8
523
ScrLockDown     equ     10h
524
NumLockDown     equ     20h
525
CapsLockDown    equ     40h
526
InsDown         equ     80h
527
 
528
; Bits for the KbdFlags3
529
LastE1          equ     1
530
LastE0          equ     2
531
RCtrDown        equ     4
532
RAltDown        equ     8
533
LastF0          equ     20h
534
 
535
; Bits for the KbdFlags4
536
ScrLockLED      equ     1
537
NumLockLED      equ     2
538
CapsLockLED     equ     4
539
SetRepeat       equ     8       ; Set auto repeat command in progress
540
AckReceived     equ     10h
541
LEDUpdate       equ     40h
542
 
543
IFDEF SCANCODE1
544
 
545
int09 proc near
546
        pusha
547
        push    ds
548
        push    es
549
        push    40h
550
        pop     ds
551
        in      al, 60h         ; al contains the scan code
552
        mov     dx, KbdFlags1
553
        mov     cx, KbdFlags3
554
        cmp     al, 0fah        ; ACK
555
        jne     short noACK
556
; ------------ manage ACK response
557
        test    ch, LEDUpdate
558
        jz      short ToggleACK ; no LED update
559
        test    ch, AckReceived
560
        jnz     short SecondACK ; second ACK received
561
        mov     ah, ch          ; LED update command sent, ACK received, need to send second byte
562
        and     ah, ScrLockLED or NumLockLED or CapsLockLED
563
        mov     bl, 0
564
        call    sendps2byte
565
        jmp     short ToggleACK
566
SecondACK:
567
        xor     ch, LEDUpdate   ; second ACK, clear LED update bit
568
ToggleACK:
569
        xor     ch, AckReceived ; toggle ACK bit
570
SetFlags1:
571
        jmp     SetFlags
572
 
573
; ------------ no ACK
574
noACK:
575
        mov     ah,4fh
576
        stc
577
        int     15h
578
        jnc     int09Exit
579
        cmp     al, 0e0h
580
        jne     short noE0
581
        or      cl, LastE0
582
        jmp     short SetFlags1
583
noE0:
584
        cmp     al, 0e1h
585
        jne     short noE1
586
        or      cl, LastE1
587
        jmp     short SetFlags1
588
noE1:
589
        cmp     al, 53h     ; is DEL?
590
        jne     short noDEL
591
        mov     ah, dl
592
        and     ah, CtrlDown or AltDown
593
        cmp     ah, CtrlDown or AltDown
594
        jne     NormalKey   ; is DEL, but no CTRL+ALt+DEL
595
        mov     word ptr ds:[72h], 1234h    ; warm boot flag
596
        db      0eah
597
        dw      0, 0ffffh       ; reboot
598
noDEL:
599
        test    cl, LastE0
600
        jnz     short noRSUp    ; ignore fake shifts
601
        cmp     al, 2ah         ; left shift
602
        jne     short noLSDown
603
        or      dl, LShfDown
604
        jmp     short SetFlagsKey2
605
noLSDown:
606
        cmp     al, 2ah or 80h
607
        jne     short noLSUp
608
        and     dl, not LShfDown
609
        jmp     short SetFlagsKey2
610
noLSUp:
611
        cmp     al, 36h         ; right shift
612
        jne     short noRSDown
613
        or      dl, RShfDown
614
        jmp     short SetFlagsKey2
615
noRSDown:
616
        cmp     al, 36h or 80h
617
        jne     short noRSUP
618
        and     dl, not RShfDown
619
        jmp     short SetFlagsKey2
620
noRSUp:
621
        cmp     al, 38h         ; ALT
622
        jne     short noALTDown
623
        test    cl, LastE0
624
        jz      short LALTDn
625
        or      cl, RAltDown
626
        or      dl, AltDown
627
        jmp     short SetFlagsKey2
628
LALTDn:
629
        or      dx, (LAltDown shl 8) or AltDown
630
        jmp     short SetFlagsKey2
631
noALTDown:
632
        cmp     al, 38h or 80h
633
        jne     short noALTUp
634
        test    cl, LastE0
635
        jz      short LALTUp
636
        and     cl, not RAltDown
637
        and     dl, not AltDown
638
        jmp     short ALTup
639
LALTUp:
640
        and     dx, not ((LAltDown shl 8) or AltDown)
641
ALTUp:
642
        xor     ax, ax
643
        xchg    al, AltKpd
644
        test    al, al
645
        jz      short SetFlagsKey2
646
        jmp     pushKey
647
noALTUp:
648
        cmp     al, 1dh         ; CTL
649
        jne     short noCTLDown
650
        test    cl, lastE0
651
        jz      short LCTLDn
652
        or      cl, RCtrDown
653
        or      dl, CtrlDown
654
SetFlagsKey2:
655
        jmp     short SetFlagsKey1
656
LCTLDn:
657
        or      dx, (LCtrDown shl 8) or CtrlDown
658
        jmp     short SetFlagsKey1
659
noCTLDown:
660
        cmp     al, 1dh or 80h
661
        jne     short noCTLUp
662
        test    cl, LastE0
663
        jz      short LCTLUp
664
        and     cl, not RCtrDown
665
        and     dl, not CtrlDown
666
        jmp     short SetFlagsKey1
667
LCTLUp:
668
        and     dx,  not ((LCtrDown shl 8) or CtrlDown)
669
        jmp     short SetFlagsKey1
670
noCTLUp:
671
        mov     bx, 3a00h + CapsLock
672
        call    KeyLock
673
        jnc     short SetFlagsKey1
674
 
675
        mov     bx, 4600h + ScrLock
676
        push    dx          ; save ScrLock state bit (dl)
677
        call    KeyLock
678
        pop     bx          ; restore ScrLock state bit (bl)
679
        jc      short noScrLock
680
        test    dl, CtrlDown
681
        jz      short SetFlagsKey1; no break, just ScollLock
682
        mov     dl, bl      ; restore ScrLock flag
683
        test    bh, ScrLockDown
684
        jnz     short SetFlagsKey1
685
        mov     byte ptr CtrlBreak, 80h   ; CTRL+BREAK flag
686
        mov     ax, Buffer
687
        mov     HeadPtr, ax
688
        mov     TailPtr, ax
689
        int     1bh
690
        xor     ax, ax
691
        jmp     pushkey
692
noScrLock:
693
        test    cl, LastE0  ; INS
694
        jnz     short testINS
695
        test    dl, RShfDown or LShfDown
696
        jnz     short testINS
697
        test    dl, NumLock
698
        jnz     short NoIns
699
testINS:
700
        mov     bx, 5200h + Insert
701
        call    KeyLock
702
noIns:
703
        mov     bx, 4500h + NumLock
704
        push    dx          ; save NumLock state bit (dl)
705
        call    KeyLock
706
        pop     bx          ; restore NumLock state bit (bl)
707
        jc      short NormalKey   ; CTRL+NumLock = Pause
708
        test    dl, CtrlDown
709
        jz      short SetFlagsKey1
710
        mov     dl, bl      ; restore NumLock flag
711
        or      dh, Pause   ; set Pause bit
712
SetFlagsKey1:
713
        jmp     SetFlagsKey
714
E0Key:
715
        mov     di, offset E0KeyList
716
        push    cx
717
        mov     cx, E0KeyIndex - E0KeyList
718
        cld
719
        push    cs
720
        pop     es
721
        repne   scasb
722
        pop     cx
723
        jne     short SetFlagsKey
724
        mov     al, es:[di + E0KeyIndex - E0KeyList - 1]
725
        jmp     short KeyDown
726
NormalKey:
727
        test    al, 80h
728
        jnz     short SetFlagsKey ; key up
729
        test    cl, LastE0
730
        jnz     short E0Key
731
        cmp     al, 59h
732
        sbb     ah, ah
733
        and     al, ah
734
        mov     bx, offset KeyIndex
735
        xlat    cs:[bx]
736
KeyDown:
737
        xor     bx, bx
738
        test    dl, RShfDown or LShfDown
739
        jz      short noShift
740
        mov     bl, 2
741
noShift:
742
        cmp     al, 26
743
        ja      short noCaps
744
        test    dl, CapsLock
745
        jz      short noNum
746
        xor     bl, 2
747
        jmp     short noNum
748
noCaps:
749
        cmp     al, 37
750
        ja      short noNum
751
        test    dl, NumLock
752
        jnz     short NumDown
753
        mov     bl, 2
754
NumDown:
755
        xor     bl, 2
756
noNum:
757
        test    dl, CtrlDown
758
        jz      short noCtrl
759
        mov     bl, 4
760
noCtrl:
761
        test    dl, AltDown
762
        jz      short noAlt
763
        mov     bl, 6
764
noAlt:
765
        cbw
766
        shl     ax, 3
767
        add     bx, ax
768
        mov     ax, cs:KeyCode[bx]
769
        cmp     ax, 000ah
770
        ja      short pushKey
771
        dec     ax
772
        js      short SetFlagsKey     ; ax was 0
773
        mov     ah, AltKpd
774
        aad
775
        mov     AltKpd, al
776
        jmp     short SetFlagsKey
777
pushKey:
778
        push    cx
779
        mov     cx, ax
780
        mov     ah, 5
781
        int     16h
782
        pop     cx
783
        and     dh, not Pause    ; clear Pause bit
784
SetFlagsKey:
785
        and     cl, not (LastE0 or LastE1)    ; not prefix key code, clear all prefixes
786
SetFlags:
787
        mov     al, dl
788
        shr     al, 4
789
        xor     al, ch
790
        and     al, 7
791
        jz      short SF1   ; no LEDs to update
792
        test    ch, SetRepeat or AckReceived or LEDUpdate
793
        jnz     short SF1   ; can not update LEDS, so just write the flags and exit
794
        or      al, LEDUpdate
795
        xor     ch, al      ; insert the LEDs in KbdFlags4
796
        mov     ah, 0edh    ; set LED
797
        mov     bl, 0
798
        call    sendps2byte
799
SF1:
800
        mov     KbdFlags1, dx
801
        mov     KbdFlags3, cx
802
 
803
int09Exit:
804
        pop     es
805
        pop     ds
806
        popa
807
        iret
808
int09 endp
809
 
810
ELSE    ; SCANCODE2
811
 
812
int09 proc near
813
        pusha
814
        push    ds
815
        push    es
816
        push    40h
817
        pop     ds
818
        in      al, 60h         ; al contains the scan code
819
        mov     dx, KbdFlags1
820
        mov     cx, KbdFlags3
821
        cmp     al, 0fah        ; ACK
822
        jne     short noACK
823
; ------------ manage ACK response
824
        test    ch, LEDUpdate
825
        jz      short ToggleACK ; no LED update
826
        test    ch, AckReceived
827
        jnz     short SecondACK ; second ACK received
828
        mov     ah, ch          ; LED update command sent, ACK received, need to send second byte
829
        and     ah, ScrLockLED or NumLockLED or CapsLockLED
830
        mov     bl, 0
831
        call    sendps2byte
832
        jmp     short ToggleACK
833
SecondACK:
834
        xor     ch, LEDUpdate   ; second ACK, clear LED update bit
835
ToggleACK:
836
        xor     ch, AckReceived ; toggle ACK bit
837
SetFlags1:
838
        jmp     SetFlags
839
 
840
; ------------ no ACK
841
noACK:
842
        cmp     al, 0e0h
843
        jne     short noE0
844
        or      cl, LastE0
845
        jmp     short SetFlags1
846
noE0:
847
        cmp     al, 0e1h
848
        jne     short noE1
849
        or      cl, LastE1
850
        jmp     short SetFlags1
851
noE1:
852
        cmp     al, 0f0h
853
        jne     short noF0
854
        or      cl, LastF0
855
        jmp     short SetFlags1
856
noF0:
857
        cmp     al, 71h     ; is DEL?
858
        jne     short noDEL
859
        mov     ah, dl
860
        and     ah, CtrlDown or AltDown
861
        cmp     ah, CtrlDown or AltDown
862
        je      short noF01
863
NormalKey1:
864
        jmp     NormalKey
865
noF01:
866
        mov     word ptr ds:[72h], 1234h    ; warm boot flag
867
        db      0eah
868
        dw      0, 0ffffh       ; reboot
869
noDEL:
870
        cmp     al, 83h         ; is F7
871
        je      short NormalKey1
872
        ja      short SetFlags1
873
        test    cl, LastF0      ; key up?
874
        jz      short noKeyUp
875
        or      al, 80h         ; key up flag
876
noKeyUp:
877
        test    cl, LastE0
878
        jnz     short noRSUp    ; ignore fake shifts
879
        cmp     al, 12h         ; left shift
880
        jne     short noLSDown
881
        or      dl, LShfDown
882
        jmp     short SetFlagsKey2
883
noLSDown:
884
        cmp     al, 12h or 80h
885
        jne     short noLSUp
886
        and     dl, not LShfDown
887
        jmp     short SetFlagsKey2
888
noLSUp:
889
        cmp     al, 59h         ; right shift
890
        jne     short noRSDown
891
        or      dl, RShfDown
892
        jmp     short SetFlagsKey2
893
noRSDown:
894
        cmp     al, 59h or 80h
895
        jne     short noRSUP
896
        and     dl, not RShfDown
897
        jmp     short SetFlagsKey2
898
noRSUp:
899
        cmp     al, 11h         ; ALT
900
        jne     short noALTDown
901
        test    cl, LastE0
902
        jz      short LALTDn
903
        or      cl, RAltDown
904
        or      dl, AltDown
905
        jmp     short SetFlagsKey2
906
LALTDn:
907
        or      dx, (LAltDown shl 8) or AltDown
908
        jmp     short SetFlagsKey2
909
noALTDown:
910
        cmp     al, 11h or 80h
911
        jne     short noALTUp
912
        test    cl, LastE0
913
        jz      short LALTUp
914
        and     cl, not RAltDown
915
        and     dl, not AltDown
916
        jmp     short ALTup
917
LALTUp:
918
        and     dx, not ((LAltDown shl 8) or AltDown)
919
ALTUp:
920
        xor     ax, ax
921
        xchg    al, AltKpd
922
        test    al, al
923
        jz      short SetFlagsKey2
924
        jmp     pushKey
925
noALTUp:
926
        cmp     al, 14h         ; CTL
927
        jne     short noCTLDown
928
        test    cl, lastE0
929
        jz      short LCTLDn
930
        or      cl, RCtrDown
931
        or      dl, CtrlDown
932
SetFlagsKey2:
933
        jmp     short SetFlagsKey1
934
LCTLDn:
935
        or      dx, (LCtrDown shl 8) or CtrlDown
936
        jmp     short SetFlagsKey1
937
noCTLDown:
938
        cmp     al, 14h or 80h
939
        jne     short noCTLUp
940
        test    cl, LastE0
941
        jz      short LCTLUp
942
        and     cl, not RCtrDown
943
        and     dl, not CtrlDown
944
        jmp     short SetFlagsKey1
945
LCTLUp:
946
        and     dx,  not ((LCtrDown shl 8) or CtrlDown)
947
        jmp     short SetFlagsKey1
948
noCTLUp:
949
        mov     bx, 5800h + CapsLock
950
        call    KeyLock
951
        jnc     short SetFlagsKey1
952
 
953
        mov     bx, 7e00h + ScrLock
954
        push    dx          ; save ScrLock state bit (dl)
955
        call    KeyLock
956
        pop     bx          ; restore ScrLock state bit (bl)
957
        jc      short noScrLock
958
        test    dl, CtrlDown
959
        jz      short SetFlagsKey1; no break, just ScollLock
960
        mov     dl, bl      ; restore ScrLock flag
961
        test    bh, ScrLockDown
962
        jnz     short SetFlagsKey1
963
        mov     byte ptr CtrlBreak, 80h   ; CTRL+BREAK flag
964
        mov     ax, Buffer
965
        mov     HeadPtr, ax
966
        mov     TailPtr, ax
967
        int     1bh
968
        xor     ax, ax
969
        jmp     pushkey
970
noScrLock:
971
        test    cl, LastE0  ; INS
972
        jnz     short testINS
973
        test    dl, RShfDown or LShfDown
974
        jnz     short testINS
975
        test    dl, NumLock
976
        jnz     short NoIns
977
testINS:
978
        mov     bx, 7000h + Insert
979
        call    KeyLock
980
noIns:
981
        mov     bx, 7700h + NumLock
982
        push    dx          ; save NumLock state bit (dl)
983
        call    KeyLock
984
        pop     bx          ; restore NumLock state bit (bl)
985
        jc      short noPause
986
        test    dl, CtrlDown
987
        jz      short SetFlagsKey1
988
        mov     dl, bl      ; restore NumLock flag
989
        or      dh, Pause   ; set Pause bit
990
SetFlagsKey1:
991
        jmp     SetFlagsKey
992
E0Key:
993
        mov     di, offset E0KeyList
994
        push    cx
995
        mov     cx, E0KeyIndex - E0KeyList
996
        cld
997
        push    cs
998
        pop     es
999
        repne   scasb
1000
        pop     cx
1001
        jne     short SetFlagsKey
1002
        mov     al, es:[di + E0KeyIndex - E0KeyList - 1]
1003
        jmp     short KeyDown
1004
noPause:
1005
        and     al, 07fh    ; delete up bit
1006
NormalKey:
1007
        test    cl, LastF0
1008
        jnz     short SetFlagsKey ; key up
1009
        test    cl, LastE0
1010
        jnz     short E0Key
1011
        mov     bx, offset KeyIndex
1012
        xlat    cs:[bx]
1013
KeyDown:
1014
        xor     bx, bx
1015
        test    dl, RShfDown or LShfDown
1016
        jz      short noShift
1017
        mov     bl, 2
1018
noShift:
1019
        cmp     al, 26
1020
        ja      short noCaps
1021
        test    dl, CapsLock
1022
        jz      short noNum
1023
        xor     bl, 2
1024
        jmp     short noNum
1025
noCaps:
1026
        cmp     al, 37
1027
        ja      short noNum
1028
        test    dl, NumLock
1029
        jnz     short NumDown
1030
        mov     bl, 2
1031
NumDown:
1032
        xor     bl, 2
1033
noNum:
1034
        test    dl, CtrlDown
1035
        jz      short noCtrl
1036
        mov     bl, 4
1037
noCtrl:
1038
        test    dl, AltDown
1039
        jz      short noAlt
1040
        mov     bl, 6
1041
noAlt:
1042
        cbw
1043
        shl     ax, 3
1044
        add     bx, ax
1045
        mov     ax, cs:KeyCode[bx]
1046
        cmp     ax, 000ah
1047
        ja      short pushKey
1048
        dec     ax
1049
        js      short SetFlagsKey     ; ax was 0
1050
        mov     ah, AltKpd
1051
        aad
1052
        mov     AltKpd, al
1053
        jmp     short SetFlagsKey
1054
pushKey:
1055
        push    cx
1056
        mov     cx, ax
1057
        mov     al, ah      ; scan code
1058
        mov     ah,4fh
1059
        stc
1060
        int     15h
1061
        jnc     nopush
1062
        mov     ah, 5
1063
        int     16h
1064
nopush:
1065
        pop     cx
1066
        and     dh, not Pause    ; clear Pause bit
1067
SetFlagsKey:
1068
        and     cl, not (LastE0 or LastE1 or LastF0)    ; not prefix key code, clear all prefixes
1069
SetFlags:
1070
        mov     al, dl
1071
        shr     al, 4
1072
        xor     al, ch
1073
        and     al, 7
1074
        jz      short SF1   ; no LEDs to update
1075
        test    ch, SetRepeat or AckReceived or LEDUpdate
1076
        jnz     short SF1   ; can not update LEDS, so just write the flags and exit
1077
        or      al, LEDUpdate
1078
        xor     ch, al      ; insert the LEDs in KbdFlags4
1079
        mov     ah, 0edh    ; set LED
1080
        mov     bl, 0
1081
        call    sendps2byte
1082
SF1:
1083
        mov     KbdFlags1, dx
1084
        mov     KbdFlags3, cx
1085
 
1086
int09Exit:
1087
        pop     es
1088
        pop     ds
1089
        popa
1090
        iret
1091
int09 endp
1092
 
1093
ENDIF
1094
 
1095
KeyLock proc near   ; input: BH = expected scan code, al = scan code, BL = key lock flag. Returns CF=1 to continue, CF=0 to exit
1096
        xor     bh, al
1097
        jnz     short s2
1098
        mov     ah, dh
1099
        or      dh, bl      ; set flag
1100
        xor     ah, dh      ; get flag difference
1101
        xor     dl, ah      ; toggle only if key was not already down
1102
        ret
1103
s2:     cmp     bh, 80h
1104
        stc
1105
        jne     short exit
1106
        xor     dh, bl      ; key up
1107
exit:
1108
        ret
1109
KeyLock endp
1110
 
1111
 
1112
; --------------------- INT 10h - Video ----------------
1113
ActiveVideoMode     equ   ; 1  byte
1114
ScreenWidth         equ   ; 2  Screen width in text columns
1115
RegenLength         equ   ; 2  Length (in bytes) of video area (regen size)
1116
PageOffset          equ   ; 2  Offset from video segment of active video memory page
1117
CursorPos           equ   ; 16 Cursor location (8 byte-pairs; low byte=col, hi byte=row)
1118
CursorShape         equ   ; 2  Cursor size/shape.  Low byte=end scan line; hi byte=start line.
1119
ActivePage          equ   ; 1  Current active video page number
1120
PortAddress         equ   ; 2  Port address for 6845 video controller chip; see CGA I/O Ports
1121
CrtMode             equ   ; 1  Current value of 6845 video ctrlr CRT_MODE (port 3x8H register)
1122
CrtPalette          equ   ; 1  Current value of 6845 video ctrlr CRT_PALETTE (port 3x9H reg)
1123
ScreenRows          equ   ; 1  EGA text rows-1  (maximum valid row value)
1124
ScanLinesChar       equ   ; 2  EGA bytes per character (scan-lines/char used in active mode)
1125
EgaMiscInfo         equ   ; 1  EGA flags; see EgaMiscInfoRec
1126
EgaMiscInfo2        equ   ; 1  EGA flags; see EgaMiscInfo2Rec
1127
VgaFlags            equ   ; 1  VGA flags; see VgaFlagsRec
1128
VgaFlags2           equ   ; 1  VGA flags2
1129
PalPaging           equ   ; 1  Palette paging status: bit7=0 for 4x64, 1 for 16x16. bit3:0=active page
1130
PalPagingCounter    equ   ; 1  Palette paging counter
1131
 
1132
 
1133
int10 proc near
1134
        sti                     ; no interrupt reentrant
1135
        cld
1136
        push    ds
1137
        push    si
1138
        push    40h
1139
        pop     ds
1140
        cmp     ah, 4fh
1141
        je      short svga
1142
        cmp     ah, 1ch
1143
        ja      short exit
1144
        mov     si, ax
1145
        shr     si, 7
1146
        and     si, 1feh
1147
        call    cs:vidtbl[si]
1148
exit:
1149
        pop     si
1150
        pop     ds
1151
        iret
1152
svga:
1153
        cmp     al, 5
1154
        je      short VESAMemControl
1155
        cmp     al, 1
1156
        jb      short VESAGetInfo
1157
        je      short VESAGetModeInfo
1158
        cmp     al, 3
1159
        jb      short VESASetMode
1160
        je      short VESAGetMode
1161
        mov     ax, 100h
1162
        jmp     short exit
1163
 
1164
; ---------------- VESA fn00
1165
VESAGetInfo:
1166
        push    cx
1167
        push    di
1168
        mov     si, offset VESAInfo
1169
        mov     cx, 10
1170
        rep     movsw es:[di], cs:[si]
1171
        mov     cl, 118     ; 236 bytes 0
1172
VESASupportedClear:
1173
        xor     ax, ax
1174
        rep     stosw
1175
        pop     di
1176
        pop     cx
1177
VESASupported:
1178
        mov     ah, 0       ; success
1179
VESASupportedErr:
1180
        mov     al, 4fh
1181
        jmp     short exit
1182
 
1183
; ---------------- VESA fn01
1184
VESAGetModeInfo:
1185
        cmp     cx, 101h
1186
VESAGetModeInfo1:
1187
        mov     ah, 1       ; error
1188
        jne     short VESASupportedErr
1189
        push    cx
1190
        push    di
1191
        mov     cx, 9
1192
        mov     si, offset VESAModeInfo
1193
        rep     movsw es:[di], cs:[si]
1194
        mov     cl, 119
1195
        jmp     short VESASupportedClear
1196
 
1197
; ---------------- VESA fn02
1198
VESASetMode:
1199
        imul    ax, bx, 2
1200
        cmp     ax, 101h*2
1201
        jne     short VESASetMode1
1202
        lea     ax, [bx+23ffh]
1203
        xchg    ah, al
1204
        int     10h
1205
        jmp     short VESASupported
1206
VESASetMode1:
1207
        mov     al, bl
1208
        mov     ah, 0
1209
        int     10h
1210
        jmp     short VESASupported
1211
 
1212
; ---------------- VESA fn03
1213
VESAGetMode:
1214
        mov     bh, EgaMiscInfo
1215
        and     bh, 80h
1216
        mov     bl, ActiveVideoMode
1217
        cmp     bl, 25h
1218
        je      short VESAGetMode1
1219
        or      bl, bh
1220
        mov     bh, 0
1221
        jmp     short VESASupported
1222
VESAGetMode1:
1223
        add     bx, 257-25
1224
        jmp     short VESASupported
1225
 
1226
; ---------------- VESA fn05
1227
VESAMemControl:
1228
        test    bx, not 101h                ; BX validation
1229
        jnz     short VESAGetModeInfo1      ; error
1230
        push    cs
1231
        call    VESAMemControlCB
1232
        jmp     short VESASupported
1233
VESAMemControlCB:
1234
        push    ax
1235
        push    dx
1236
        mov     ax, bx
1237
        and     ax, 1
1238
        add     al, 8ah
1239
        xchg    ax, dx
1240
        and     ax, 7
1241
        add     al, 0ah
1242
        test    bh, bh
1243
        jnz     getpageinfo
1244
        call    flush
1245
        out     dx, ax
1246
        pop     dx
1247
        pop     ax
1248
        retf
1249
getpageinfo:
1250
        in      ax, dx
1251
        sub     al, 0ah
1252
        and     ax, 7
1253
        xchg    ax, dx
1254
        pop     ax
1255
        pop     ax
1256
        retf
1257
 
1258
VESAInfo    db  'VESA'
1259
            dw  100h, VESAOEM, 0f000h, 2, 0, VESAModes, 0f000h, 8
1260
VESAOEM     db  'Nicolae Dumitrache', 0
1261
VESAModes   dw  101h, 0ffffh
1262
VESAModeInfo:
1263
;Bit(s)  Description - mode attributes
1264
;0      mode supported by present hardware configuration
1265
;1      optional information available (must be =1 for VBE v1.2+)
1266
;2      BIOS output supported
1267
;3      set if color, clear if monochrome
1268
;4      set if graphics mode, clear if text mode
1269
;---VBE v2.0+ ---
1270
;5      mode is not VGA-compatible
1271
;6      bank-switched mode not supported
1272
;7      linear framebuffer mode supported
1273
;8      double-scan mode available (e.g. 320x200 and 320x240)
1274
;---VBE v3.0 ---
1275
;9      interlaced mode available
1276
;10     hardware supports triple buffering
1277
;11     hardware supports stereoscopic display
1278
;12     dual display start address support
1279
;13-15  reserved
1280
        dw  0000000010011001b
1281
;Bit(s)  Description - window attributes
1282
;0      exists
1283
;1      readable
1284
;2      writable
1285
;3-7    reserved
1286
        db  00000111b, 00000111b
1287
        dw  64, 64, 0a000h, 0b000h, VESAMemControlCB, 0f000h, 640
1288
 
1289
 
1290
; --------------- fn 00h, set video mode
1291
setmode:
1292
        pusha
1293
        push    es
1294
        add     al, al      ; CF = cls bit
1295
        rcl     byte ptr EgaMiscInfo, 1
1296
        ror     byte ptr EgaMiscInfo, 1
1297
        cmp     al, 3*2
1298
        ja      short setmode1
1299
        mov     al, 0b6h        ; reset sound generator
1300
        out     43h, al
1301
        mov     al, 0
1302
        out     42h, al
1303
        out     42h, al
1304
        mov     ax, 0806h   ; text mode (80x25, 16 colors), flash enabled
1305
        mov     word ptr ScreenWidth, 80
1306
        mov     word ptr RegenLength, 1000h
1307
        mov     byte ptr ScreenRows, 25-1
1308
        mov     word ptr ScanLinesChar, 16
1309
        mov     bx, 0b800h  ; segment
1310
        mov     cx, 4000h   ; video len/2
1311
        mov     si, 0720h   ; clear value
1312
        jmp     short setmode2
1313
setmode1:
1314
        cmp     al, 13h*2
1315
        jne     short setmode3
1316
        mov     ah, 41h     ; graphic mode, 320x200, 256 colors
1317
        mov     word ptr ScreenWidth, 40
1318
        mov     word ptr RegenLength, 2000h
1319
        jmp     short setmode21
1320
setmode3:
1321
        cmp     al, 25h*2
1322
        jne     short setmodeexit
1323
        mov     ah, 1       ; graphic mode, 640x400, 256 colors
1324
        mov     word ptr ScreenWidth, 80
1325
        mov     word ptr RegenLength, 2000h
1326
setmode21:
1327
        mov     bx, 0a000h  ; segment
1328
        mov     cx, 8000h   ; video len/2 - clears only the first segment (TODO clear full screen)
1329
        xor     si, si      ; clear value
1330
setmode2:
1331
        shr     al, 1
1332
        mov     ActiveVideoMode, al
1333
        push    ax
1334
        push    cx
1335
        push    ds
1336
        pop     es
1337
        xor     ax, ax
1338
        mov     di, offset CursorPos
1339
        mov     cx, 8
1340
        rep     stosw           ; reset cursor position for all pages
1341
        mov     ax, 0500h
1342
        int     10h             ; set page0
1343
        pop     cx
1344
        pop     ax
1345
        test    byte ptr EgaMiscInfo, 80h
1346
        jnz     short setmode4    ; no clear video memory
1347
        mov     es, bx
1348
        xchg    ax, si
1349
        xor     di, di
1350
        rep     stosw
1351
        xchg    ax, si
1352
        call    palpageset
1353
        mov     byte ptr PalPaging, cl  ; reset paging
1354
setmode4:
1355
        mov     dx, 3c0h
1356
        mov     al, 10h
1357
        out     dx, al
1358
        mov     al, ah
1359
        out     dx, al          ; set video mode
1360
        mov     ax, 1123h
1361
        int     10h             ; set ROM 8x8 font for graphics mode
1362
        mov     ah, 1
1363
        xor     cx, cx
1364
        int     10h             ; show cursor
1365
        test    byte ptr VgaFlags, 8     ; test default palette loading
1366
        jnz     short setmodeexit     ; no default palette
1367
        mov     ax, 1012h
1368
        xor     bx, bx
1369
        mov     cx, 100h
1370
        mov     dx, offset default_pal
1371
        push    cs
1372
        pop     es
1373
        int     10h             ; set default palette
1374
setmodeexit:
1375
        pop     es
1376
        popa
1377
nullproc:
1378
        ret
1379
 
1380
; --------------- fn 01h, set cursor shape and visibility (shape is ignored, always lines 14&15 of text mode char)
1381
cursor:     ; CH bit 6 or 5 -> cursor off
1382
        push    ax
1383
        push    dx
1384
        mov     dx, 3d4h
1385
        mov     al, 0ah
1386
        out     dx, al
1387
        mov     al, ch
1388
        shr     al, 1
1389
        or      al, ch
1390
        inc     dx
1391
        out     dx, al
1392
        pop     dx
1393
        pop     ax
1394
        ret
1395
 
1396
;---------------- fn 02h, set cursor pos
1397
curpos:
1398
        push    ax
1399
        push    bx
1400
        mov     al, bh
1401
        shr     bx, 7
1402
        and     bx, 0eh
1403
        mov     CursorPos[bx], dx
1404
        cmp     byte ptr ActiveVideoMode, 3
1405
        jne     short curpos1
1406
        cmp     al, ActivePage
1407
        jne     short curpos1
1408
        push    dx
1409
        xor     ax, ax
1410
        xchg    al, dh
1411
        imul    ax, 80
1412
        add     ax, dx
1413
        mov     dx, 3d4h
1414
        push    ax
1415
        mov     al, 0fh
1416
        out     dx, al
1417
        inc     dx
1418
        pop     ax
1419
        out     dx, al
1420
        dec     dx
1421
        mov     al, 0eh
1422
        out     dx, al
1423
        inc     dx
1424
        mov     al, ah
1425
        out     dx, al
1426
        pop     dx
1427
curpos1:
1428
        pop     bx
1429
        pop     ax
1430
        ret
1431
 
1432
;---------------- fn 03h, get cursor pos
1433
getcurpos:
1434
        push    bx
1435
        shr     bx, 7
1436
        and     bx, 0eh
1437
        mov     dx, CursorPos[bx]
1438
        mov     cx, CursorShape
1439
        pop     bx
1440
        ret
1441
 
1442
;---------------- fn 04h, light pen
1443
lightpen:
1444
        mov     ah, 0   ; not triggered
1445
        ret
1446
 
1447
;---------------- fn 05h, set active video page
1448
apage:
1449
        pusha
1450
        call    flush
1451
        and     al, 7
1452
        mov     bh, al
1453
        mov     ActivePage, al
1454
        mov     al, ActiveVideoMode
1455
        cmp     al, 3
1456
        jne     short apage1
1457
        mov     ax, 0ah
1458
        out     8ah, ax
1459
        inc     ax
1460
        out     8bh, ax
1461
        mov     ah, 3
1462
        int     10h        ; get cursor pos
1463
        mov     ah, 2
1464
        int     10h        ; set cursor pos
1465
        mov     ax, 200h   ; page size / 8
1466
        jmp     short apage2
1467
apage1:                    ; mode 13h and 25h
1468
        mov     ax, 0ah
1469
        add     al, bh
1470
        out     8ah, ax
1471
        inc     ax
1472
        cmp     al, 12h
1473
        jne     short apage4
1474
        mov     al, 0ah
1475
apage4: out     8bh, ax
1476
        mov     ax, 2000h  ; page size / 8
1477
apage2:
1478
        shr     bx, 8      ; page number
1479
        mul     bx
1480
        push    ax
1481
        shl     ax, 3
1482
        mov     PageOffset, ax
1483
        mov     dx, 3d4h
1484
        mov     al, 0dh
1485
        out     dx, al
1486
        inc     dx
1487
        pop     ax
1488
        out     dx, al
1489
        dec     dx
1490
        mov     al, 0ch
1491
        out     dx, al
1492
        inc     dx
1493
        mov     al, ah
1494
        out     dx, al
1495
        popa
1496
        ret
1497
 
1498
;---------------- fn 06h, scroll up / clr
1499
scrollup:
1500
        pusha
1501
        push    es
1502
        xchg    cx, dx
1503
        sub     cx, dx
1504
        inc     cx
1505
        cmp     byte ptr ActiveVideoMode, 13h
1506
        jae     short scrollup1
1507
        call    scr_params
1508
scrollup6:
1509
        push    0b800h          ; segment
1510
        pop     es
1511
        add     dl, dl
1512
        add     di, di
1513
        add     di, PageOffset  ; di = top left corner address
1514
        xchg    ax, cx          ; ah = 0
1515
        test    bl, bl
1516
        jz      short scrollup3       ; clear
1517
        sub     ah, bl
1518
        jb      short scrollup3       ; clear
1519
        add     si, di
1520
scrollup4:
1521
        mov     cl, al
1522
        rep     movsw es:[si], es:[di]
1523
        add     si, dx
1524
        add     di, dx
1525
        dec     ah
1526
        jns     short scrollup4       ; ch = lines - 1
1527
scrollup3:
1528
        add     ah, bl          ; clear rectangle: DI=address, ah=lines, al=columns, bh=attribute
1529
        xchg    ax, bx
1530
        mov     al, ' '
1531
scrollup5:
1532
        mov     cl, bl
1533
        rep     stosw
1534
        add     di, dx
1535
        dec     bh
1536
        jns     short scrollup5       ; ch = lines - 1
1537
scrollexit:
1538
        pop     es
1539
        popa
1540
        ret
1541
scrollup1:
1542
        ja     short scrollup2
1543
; TODO mode13h scroll up
1544
        jmp     short scrollexit
1545
scrollup2:
1546
; TODO mode25h scroll up
1547
        jmp     short scrollexit
1548
 
1549
;---------------- fn 07h, scroll dn / clr
1550
scrolldn:
1551
        std
1552
        pusha
1553
        push    es
1554
        neg     cx
1555
        add     cx, dx
1556
        inc     cx
1557
        cmp     byte ptr ActiveVideoMode, 13h
1558
        jae     short scrolldn1
1559
        call    scr_params
1560
        neg     dx
1561
        neg     si
1562
        jmp     short scrollup6
1563
 
1564
scrolldn1:
1565
        ja     short scrolldn2
1566
; TODO  mode13h scroll down
1567
        jmp     short scrollexit
1568
scrolldn2:
1569
; TODO  mode25h scroll down
1570
        jmp     short scrollexit
1571
 
1572
scr_params:
1573
        mov     bl, al          ; lines
1574
        xor     ax, ax
1575
        xchg    al, dh
1576
        imul    di, ax, 80
1577
        add     di, dx
1578
        mov     dl, 80          ; dh = 0
1579
        sub     dl, cl
1580
        mov     al, bl
1581
        imul    si, ax, 160
1582
        ret
1583
;---------------- fn 08h, read char/attr
1584
readchar:
1585
        push    bx
1586
        mov     al, ActiveVideoMode
1587
        cmp     al, 3
1588
        xor     ax, ax
1589
        jne     short readchar1
1590
        call    mode3chaddr
1591
        mov     ax, [bx]
1592
readcharexit:
1593
        pop     bx
1594
        ret
1595
readchar1:
1596
        cmp     al, 13h
1597
        jne     short readchar2
1598
; TODO mode13h
1599
        jmp     short readcharexit
1600
readchar2:
1601
; TODO mode25h
1602
        jmp     short readcharexit
1603
 
1604
mode3chaddr:    ; returns current char address in mode3 in ds:bx. Input: bh=page, ds=40h
1605
        push    ax
1606
        and     bx, 700h
1607
        lea     ax, [bx+0b800h]
1608
        shr     bx, 7
1609
        mov     bx, CursorPos[bx]
1610
        mov     ds, ax
1611
        xor     ax, ax
1612
        xchg    al, bh
1613
        imul    ax, 80
1614
        add     bx, ax
1615
        add     bx, bx
1616
        pop     ax
1617
        ret
1618
 
1619
;---------------- fn 09h, write char/attr
1620
writecharattr:
1621
        push    ax
1622
        push    es
1623
        push    bx
1624
        push    cx
1625
        cmp     byte ptr ActiveVideoMode, 3
1626
        jne     short writecharattr1
1627
        mov     ah, bl
1628
        call    mode3chaddr
1629
        push    ds
1630
        pop     es
1631
        xchg    di, bx
1632
        rep     stosw
1633
        xchg    di, bx
1634
writecharattrexit:
1635
        pop     cx
1636
        pop     bx
1637
        pop     es
1638
        pop     ax
1639
        ret
1640
writecharattr1:
1641
        cmp     byte ptr ActiveVideoMode, 13h
1642
        jne     short writecharattr2
1643
; TODO mode13h
1644
        jmp     short writecharattrexit
1645
writecharattr2:
1646
; TODO mode25h
1647
        jmp     short writecharattrexit
1648
 
1649
;---------------- fn 0ah, write char
1650
writechar:
1651
        jcxz    short writecharskip
1652
        push    bx
1653
        push    cx
1654
        cmp     byte ptr ActiveVideoMode, 3
1655
        jne     short writechar1
1656
        call    mode3chaddr
1657
writechar3:
1658
        mov     [bx], al
1659
        add     bx, 2
1660
        loop    short writechar3
1661
writecharexit:
1662
        pop     cx
1663
        pop     bx
1664
writecharskip:
1665
        ret
1666
writechar1:
1667
        cmp     byte ptr ActiveVideoMode, 13h
1668
        jne     short writechar2
1669
; TODO mode13h
1670
        jmp     short writecharexit
1671
writechar2:
1672
; TODO mode25h
1673
        jmp     short writecharexit
1674
 
1675
;---------------- fn 0eh, write char as TTY
1676
writecharTTY:
1677
        push    ax
1678
        push    bx
1679
        push    dx
1680
        mov     bl, ActivePage
1681
        mov     bh, 0
1682
        add     bx, bx
1683
        mov     dx, CursorPos[bx]
1684
        shl     bx, 7
1685
        mov     ah, 0ah
1686
        call    tty
1687
        mov     ah, 2       ; set cursor pos
1688
        int     10h
1689
        pop     dx
1690
        pop     bx
1691
        pop     ax
1692
        ret
1693
 
1694
tty:    ; dx=xy, bh=page, al=char, bl=attr, ah=0ah(no attr) or 09h(with attr)
1695
        test    word ptr KbdFlags2, Pause
1696
        jnz     short tty
1697
        push    cx
1698
        cmp     al, 7
1699
        je      short bell
1700
        cmp     al, 8
1701
        je      short bs
1702
        cmp     al, 0ah
1703
        je      short cr
1704
        cmp     al, 0dh
1705
        je      short lf
1706
        mov     cx, 1
1707
        int     10h         ; write char at cursor
1708
        inc     dx
1709
        cmp     dl, ScreenWidth
1710
        jae     short crlf
1711
tty1:
1712
        pop     cx
1713
        ret
1714
bell:
1715
; TODO bell code
1716
        jmp     short tty1
1717
bs:
1718
        sub     dl, 1
1719
        adc     dl, 0
1720
        jmp     short tty1
1721
lf:
1722
        mov     dl, 0
1723
        jmp     short tty1
1724
crlf:
1725
        mov     dl, 0
1726
cr:
1727
        inc     dh
1728
        cmp     dh, ScreenRows
1729
        jbe     short tty1
1730
        dec     dh
1731
;        mov     ah, 8
1732
;        int     10h         ; read attribute at cursor pos
1733
        push    bx          ; save active page in bh
1734
        push    dx
1735
;        xchg    ax, bx
1736
        mov     bh, 7       ; default attribute
1737
        mov     ax, 601h
1738
        mov     dh, ScreenRows
1739
        mov     dl, ScreenWidth
1740
        dec     dx
1741
        xor     cx, cx
1742
        int     10h         ; scroll up
1743
        pop     dx
1744
        pop     bx          ; restore active page in bh
1745
        jmp     short tty1
1746
 
1747
;---------------- fn 0fh, read video mode
1748
readmode:
1749
        mov     al, EgaMiscInfo
1750
        and     al, 80h
1751
        or      al, ActiveVideoMode
1752
        mov     ah, ScreenWidth
1753
        mov     bh, ActivePage
1754
        ret
1755
 
1756
 
1757
;---------------- fn 10h, palette
1758
paltable    dw  setonereg, palexit, setallreg, setblink, palexit, palexit, palexit, readonereg, readoverscan, readallreg, palexit, palexit, palexit, palexit, palexit, palexit
1759
            dw  setoneDAC, palexit, setblockDAC, paging, palexit, readoneDAC, palexit, readblockDAC, setPELmask, getPELmask, getpaging, grayscale
1760
 
1761
pal:
1762
        cmp     al, 1bh
1763
        ja      short palexit
1764
        mov     si, ax
1765
        add     si, si
1766
        add     byte ptr PalPagingCounter, ah   ; prevents  re-entrance on recursive  calls
1767
        call    palpage
1768
        call    cs:paltable[si-2000h]
1769
        call    palpage
1770
        sub     byte ptr PalPagingCounter, ah
1771
palexit:
1772
        ret
1773
 
1774
palpage:                    ; executes only if PalPagingCounter == ah
1775
        cmp     byte ptr PalPagingCounter, ah
1776
        jne     short palpageexit
1777
palpageset:
1778
        test    byte ptr PalPaging, 0fh
1779
        jz      short palpageexit
1780
        pusha
1781
        mov     bl, byte ptr PalPaging
1782
        add     bl, bl
1783
        jc      short page16
1784
        shl     bl, 2
1785
page16:
1786
        shl     bx, 11  ; bh=target page, bl=0 page
1787
palpage1:
1788
        mov     al, 15h
1789
        int     10h     ; read 0 page DAC reg
1790
        push    cx
1791
        push    dx
1792
        xchg    bl, bh
1793
        int     10h     ; read target page DAC register
1794
        xchg    bl, bh
1795
        mov     al, 10h
1796
        int     10h     ; write 0 page DAC register
1797
        pop     dx
1798
        pop     cx
1799
        xchg    bl, bh
1800
        int     10h     ; write target page DAC register
1801
        xchg    bl, bh
1802
        add     bx, 101h; next DAC reg
1803
        test    bl, 0fh
1804
        jnz     short palpage1
1805
        popa
1806
palpageexit:
1807
        ret
1808
 
1809
setonereg:
1810
        cmp     bl, 10h
1811
        jae     setonereg1
1812
        pusha
1813
        call    colfrombits
1814
        mov     cl, al
1815
        call    colfrombits
1816
        mov     ch, al
1817
        call    colfrombits
1818
        mov     dh, al
1819
        mov     al, 10h
1820
        int     10h
1821
        popa
1822
setonereg1:
1823
        ret
1824
 
1825
setallreg:
1826
        pusha
1827
        mov     al, 0
1828
        mov     si, dx
1829
        mov     bl, 15
1830
setallreg1:
1831
        mov     bh, es:[si+15]
1832
        int     10h
1833
        dec     si
1834
        dec     bl
1835
        jns     short setallreg1
1836
        popa
1837
        ret
1838
 
1839
setblink:
1840
        pusha
1841
        cmp     byte ptr ActiveVideoMode, 3
1842
        jne     short setblink1
1843
        mov     dx, 3c0h
1844
        mov     al, 10h
1845
        out     dx, al
1846
        mov     al, bl
1847
        and     al, 1
1848
        shl     al, 3
1849
        out     dx, al          ; set video mode (0 or 8)
1850
        shl     al, 2
1851
        xor     al, VgaFlags
1852
        and     al, 20h
1853
        xor     VgaFlags, al
1854
setblink1:
1855
        popa
1856
        ret
1857
 
1858
readonereg:
1859
        cmp     bl, 10h
1860
        jae     readonereg1
1861
        push    ax
1862
        push    cx
1863
        push    dx
1864
        mov     al, 15h
1865
        int     10h
1866
        mov     al, dh          ; al = R
1867
        and     al, 00110000b
1868
        shr     al, 2
1869
        add     al, 01111000b
1870
        and     al, 10000100b
1871
        mov     bh, al
1872
        xchg    ax, cx          ; ax = GB
1873
        and     ax, 0011000000110000b
1874
        shr     ax, 3
1875
        shr     al, 1
1876
        add     ax, 0011110000011110b
1877
        and     ax, 0100001000100001b
1878
        or      bh, ah
1879
        or      bh, al
1880
        rol     bh, 3
1881
        pop     dx
1882
        pop     cx
1883
        pop     ax
1884
readonereg1:
1885
        ret
1886
 
1887
readallreg:
1888
        pusha
1889
        mov     di, dx
1890
        mov     bl, 0
1891
readllreg1:
1892
        mov     al, 7
1893
        int     10h
1894
        mov     al, bh
1895
        stosb
1896
        inc     bx
1897
        cmp     bl, 16
1898
        jne     short readllreg1
1899
        mov     al, 0   ; overscan color
1900
        stosb
1901
        popa
1902
        ret
1903
 
1904
readoverscan:
1905
        mov     bh, 0
1906
        ret
1907
 
1908
setoneDAC:
1909
        push    ax
1910
        push    dx
1911
        xchg    ax, dx
1912
        mov     al, bl
1913
        mov     dx, 3c8h
1914
        out     dx, al
1915
        inc     dx
1916
        mov     al, ah
1917
        out     dx, al
1918
        mov     al, ch
1919
        out     dx, al
1920
        mov     al, cl
1921
        out     dx, al
1922
        pop     dx
1923
        pop     ax
1924
        ret
1925
 
1926
setblockDAC:
1927
        pusha
1928
        mov     si, dx
1929
        mov     dx, 3c8h
1930
        xchg    ax, bx
1931
        out     dx, al
1932
        inc     dx
1933
        imul    cx, 3
1934
        rep     outsb dx, es:[si]
1935
        popa
1936
        ret
1937
 
1938
paging:
1939
        push    bx
1940
        test    bl, bl
1941
        mov     bl, PalPaging
1942
        jnz     short paging1
1943
        add     bl, bl
1944
        ror     bx, 1
1945
        jmp     short paging2
1946
paging1:
1947
        and     bx, 0f80h       ; bl=old page, bh=new page
1948
        or      bl, bh
1949
paging2:
1950
        mov     PalPaging, bl
1951
        pop     bx
1952
        ret
1953
 
1954
readoneDAC:
1955
        push    ax
1956
        push    dx
1957
        mov     al, bl
1958
        mov     dx, 3c7h
1959
        out     dx, al
1960
        inc     dx
1961
        inc     dx
1962
        in      al, dx
1963
        mov     ah, al
1964
        in      al, dx
1965
        mov     ch, al
1966
        in      al, dx
1967
        mov     cl, al
1968
        pop     dx
1969
        mov     dh, ah
1970
        pop     ax
1971
        ret
1972
 
1973
readblockDAC:
1974
        pusha
1975
        mov     di, dx
1976
        mov     dx, 3c7h
1977
        xchg    ax, bx
1978
        out     dx, al
1979
        inc     dx
1980
        inc     dx
1981
        imul    cx, 3
1982
        rep     insb
1983
        popa
1984
        ret
1985
 
1986
setPELmask:
1987
        push    dx
1988
        xchg    ax, bx
1989
        mov     dx, 3c6h
1990
        out     dx, al
1991
        xchg    ax, bx
1992
        pop     dx
1993
        ret
1994
 
1995
getPELmask:
1996
        push    dx
1997
        xchg    ax, bx
1998
        mov     dx, 3c6h
1999
        in      al, dx
2000
        xchg    ax, bx
2001
        pop     dx
2002
        ret
2003
 
2004
getpaging:
2005
        mov     bh, PalPaging
2006
        mov     bl, 0
2007
        rol     bx, 1
2008
        shr     bh, 1
2009
        ret
2010
 
2011
grayscale:
2012
        jcxz    short grayscale2
2013
        pusha
2014
        mov     bh, cl
2015
grayscale1:
2016
        mov     al, 15h
2017
        int     10h
2018
        shr     dx, 8
2019
        imul    si, dx, 77
2020
        mov     dl, ch
2021
        imul    dx, 151
2022
        mov     ch, 0
2023
        imul    cx, 28
2024
        add     dx, si
2025
        add     dx, cx
2026
        mov     ch, dh
2027
        mov     cl, dh
2028
        mov     al, 10h
2029
        int     10h
2030
        inc     bl
2031
        dec     bh
2032
        jne     short grayscale1
2033
        popa
2034
grayscale2:
2035
        ret
2036
 
2037
colfrombits:    ; input: bh, output: al
2038
        shr     bh, 1
2039
        sbb     al, al
2040
        and     al, 2ah
2041
        test    bh, 4
2042
        jz      short col1
2043
        or      al, 15h
2044
col1:
2045
        ret
2046
 
2047
 
2048
;---------------- fn 11h, character generator
2049
loadUDF:
2050
        cmp     bx, 1000h
2051
        jne     loadUDFexit     ; only 16bytes chars and font block 0 supported
2052
        pusha
2053
        xchg    ax, dx
2054
        mov     dx, 03cbh
2055
        out     dx, ax
2056
        mov     si, bp
2057
        shl     cx, 4
2058
        rep     outsb dx, es:[si]
2059
        popa
2060
loadUDFexit:
2061
        ret
2062
 
2063
chargen:
2064
        test    al, not 10h     ; test for 00h and 10h
2065
        jz      short loadUDF
2066
        test    al, not 11h     ; test for 01h and 11h
2067
        jz      short loadROMfont
2068
        test    al, not 12h     ; test for 02h and 12h
2069
        jz      short loadROMfont
2070
        test    al, not 14h     ; test for 04h and 14h
2071
        jz      short loadROMfont
2072
        cmp     al, 20h
2073
        jb      loadUDFexit
2074
        je      short set1f
2075
        cmp     al, 21h
2076
        je      short setgrUDF
2077
        cmp     al, 24h
2078
        jbe     short setROMgrFont
2079
        cmp     al, 30h
2080
        je      short getfontinfo
2081
        ret
2082
 
2083
loadROMFont:
2084
        push    es
2085
        pusha
2086
        mov     bx, 1000h       ; 8x16 chars, block 0
2087
        mov     cx, 100h        ; all chars
2088
        xor     dx, dx
2089
        mov     bp, offset font8x16
2090
        push    cs
2091
        pop     es
2092
        mov     al, 0
2093
;        int     10h             ; loadUDF
2094
        popa
2095
        pop     es
2096
        ret
2097
 
2098
set1f:
2099
        xor     si, si
2100
        mov     ds, si
2101
        mov     [si+1fh*4], bp
2102
        mov     [si+1fh*4+2], es
2103
        ret
2104
 
2105
setgrUDF:
2106
        pusha
2107
        jcxz    short loadUDFexit
2108
        push    ds
2109
        xor     si, si
2110
        mov     ds, si
2111
        mov     [si+43h*4], bp
2112
        mov     [si+43h*4+2], es
2113
        pop     ds
2114
        mov     ax, 200
2115
        cmp     byte ptr ActiveVideoMode, 13h
2116
        jb      short setgrUDFexit
2117
        je      short setgrUDF1
2118
        mov     ax, 480         ; mode 25h, 480 lines
2119
setgrUDF1:
2120
        mov     ScanLinesChar, cx
2121
        cwd
2122
        div     cx
2123
        dec     ax
2124
        mov     ScreenRows, al
2125
setgrUDFexit:
2126
        popa
2127
        ret
2128
 
2129
setROMgrFont:
2130
        pusha
2131
        push    es
2132
        mov     cx, 8
2133
        push    cs
2134
        pop     es
2135
        mov     bp, offset font8x8
2136
        cmp     al, 23h
2137
        je      short setROMgrFont1
2138
        mov     bp, offset font8x16
2139
setROMgrFont1:
2140
        mov     al, 21h
2141
        int     10h     ; set graphic UDF
2142
        dec     ax
2143
        mov     bp, offset font8x8 + 128*8
2144
        int     10h     ; set INT 1fh
2145
        pop     es
2146
        popa
2147
        ret
2148
 
2149
getfontinfo:
2150
        mov     cx, ScanLinesChar
2151
        mov     dl, ScreenRows
2152
        cmp     bh, 1
2153
        ja      short getfontinfo1
2154
        push    0
2155
        pop     ds
2156
        les     bp, ds:[1fh*4]
2157
        jb      short getfontinfoexit
2158
        les     bp, ds:[43h*4]
2159
        ret
2160
getfontinfo1:
2161
        cmp     bh, 7
2162
        ja      short getfontinfoexit
2163
        mov     si, bx
2164
        shr     si, 8
2165
        add     si, si
2166
        mov     bp, cs:fontinfo[si-4]
2167
        push    cs
2168
        pop     es
2169
getfontinfoexit:
2170
        ret
2171
 
2172
fontinfo    dw  font8x16, font8x8, font8x8+128*8, font8x16, font8x16, font8x16
2173
 
2174
;---------------- fn 12h, special functions
2175
special:
2176
        cmp     bl, 10h
2177
        jne     short special1
2178
        mov     cl, EgaMiscInfo2    ; cl = switch settings
2179
        and     cx, 15              ; ch <- 0 (feature bits)
2180
        mov     bx, 3               ; bh <- 0 (color mode), bl = video memory size
2181
        ret
2182
special1:
2183
        cmp     bl, 31h
2184
        jne     short special2
2185
        neg     al
2186
        xor     al, VgaFlags
2187
        and     al, 8       ; transfer palette loading bit to VgaFlags
2188
        xor     VgaFlags, al
2189
        mov     al, 12h     ; supported function
2190
        ret
2191
special2:
2192
        mov     al, 0       ; unsupported function
2193
        ret
2194
 
2195
 
2196
;---------------- fn 13h, write string
2197
writestr:
2198
        jcxz    short wstrexit
2199
        pusha
2200
        mov     si, bx
2201
        shr     si, 8
2202
        add     si, si
2203
        push    CursorPos[si]
2204
        mov     ah, 9       ; write tty char/attribute
2205
wstr1:
2206
        push    ax
2207
        test    al, 2
2208
        mov     al, es:[bp]
2209
        jz      short noattr
2210
        inc     bp
2211
        mov     bl, es:[bp]
2212
noattr:
2213
        inc     bp
2214
        mov     CursorPos[si], dx
2215
        call    tty
2216
        pop     ax
2217
        loop    short wstr1
2218
        pop     CursorPos[si]
2219
        test    al, 1
2220
        jz      short wstr2
2221
        mov     ah, 2       ; set cursor pos
2222
        int     10h
2223
wstr2:
2224
        popa
2225
wstrexit:
2226
        ret
2227
 
2228
;---------------- fn 1ah, get/set display combination code
2229
getdcc:
2230
        cmp     al, 1
2231
        ja      short getdccexit
2232
        mov     al, ah
2233
        je      short setdcc
2234
        mov     bx, 08h
2235
dccval  label word
2236
setdcc:
2237
        mov     cs:[dccval-2], bx
2238
getdccexit:
2239
        ret
2240
 
2241
;---------------- fn 1bh, query status
2242
querystatus:
2243
        pusha
2244
        mov     ax, offset staticfunctable
2245
        stosw
2246
        mov     ax, cs
2247
        stosw
2248
        mov     si, offset ActiveVideoMode
2249
        cmp     byte ptr [si], 13h
2250
        mov     cx, 33          ; info copied from BDA
2251
        rep     movsb
2252
        mov     ax, 8
2253
        stosw                   ; display info (one VGA analog color monitor)
2254
        mov     bx, 208h        ; 400 scan lines, 8 pages
2255
        mov     al, 10h         ; 16 colors
2256
        jb      short querystatus1     ; mode03h
2257
        mov     bh, 0           ; scan lines code (0=200, 1=350, 2=400, 3=480), 8 pages
2258
        mov     ax, 100h        ; 256 colors
2259
        je      short querystatus1     ; mode13h
2260
        mov     bx, 301h        ; 480 scan lines, 1 page
2261
querystatus1:
2262
        stosw
2263
        xchg    ax, bx
2264
        stosw
2265
        xor     ax, ax
2266
        stosw                   ; font block info (45)
2267
        mov     al, VgaFlags
2268
        and     al, 00101111b
2269
        stosw
2270
        stosw
2271
        mov     al, EgaMiscInfo
2272
        shr     al, 4
2273
        and     al, 7           ; video memory size
2274
        stosw
2275
        mov     al, 2
2276
        stosb                   ; color display attached
2277
        mov     cl, 6
2278
        xor     ax, ax
2279
        rep     stosw           ; 12 reserved bytes
2280
        popa
2281
        mov     al, ah          ; supported function
2282
        ret
2283
 
2284
staticfunctable db  00001100b   ; video mode 2h, 3h supported
2285
                db  00000000b
2286
                db  00001000b   ; video mode 13h supported
2287
                db  00000000b
2288
                db  00100000b   ; video mode 25h supported
2289
                db  0, 0
2290
                db  00000100b   ; 400 scanline supported
2291
                db  1           ; font blocks available in text mode
2292
                db  1           ; max active font blocks available in text mode
2293
 
2294
;Bit(s)  Description
2295
;0      all modes on all displays function supported
2296
;1      gray summing function supported
2297
;2      character font loading function supported
2298
;3      default palette loading enable/disable supported
2299
;4      cursor emulation function supported
2300
;5      EGA palette present
2301
;6      color palette present
2302
;7      color-register paging function supported
2303
;8      light pen supported (see AH=04h)
2304
;9      save/restore state function 1Ch supported
2305
;10     intensity/blinking function supported (see AX=1003h)
2306
;11     Display Combination Code supported (see #00039)
2307
;12-15  unused (0)
2308
                db  11101111b   ; miscellaneous function support flags
2309
                db  00001100b   ; miscellaneous function support flags
2310
 
2311
                db  0, 0        ; reserved
2312
                db  0           ; save pointer function flags
2313
                db  0           ; reserved
2314
 
2315
 
2316
vidtbl  dw  setmode, cursor, curpos, getcurpos, lightpen, apage, scrollup, scrolldn, readchar, writecharattr
2317
        dw  writechar, nullproc, nullproc, nullproc, writecharTTY, readmode
2318
        dw  pal, chargen, special, writestr, nullproc, nullproc, nullproc, nullproc, nullproc, nullproc, getdcc, querystatus, nullproc
2319
int10 endp
2320
 
2321
; --------------------- INT 11h - Equipment ----------------
2322
EquipmentWord       equ     
2323
 
2324
int11   proc near
2325
        push    ds
2326
        push    40h
2327
        pop     ds
2328
        mov     ax, EquipmentWord
2329
        pop     ds
2330
        iret
2331
int11   endp
2332
 
2333
; --------------------- INT 12h - Memory size ----------------
2334
MemorySize       equ     
2335
 
2336
int12   proc near
2337
        push    ds
2338
        push    40h
2339
        pop     ds
2340
        mov     ax, MemorySize
2341
        pop     ds
2342
        iret
2343
int12   endp
2344
 
2345
; --------------------- INT 13h - Disk services ----------------
2346
HDLastError       equ     
2347
HDOpStarted       equ         ; bit 3: in INT13h (all other bits must be 0)
2348
HDSize            equ     
2349
 
2350
int13   proc near
2351
        push    ds
2352
        push    bp
2353
        push    40h
2354
        pop     ds
2355
        xor     byte ptr HDOpStarted, 8
2356
        jz      short inINT13
2357
        sti
2358
        cld
2359
        cmp     ah, 1ah
2360
        jbe     short Disk1
2361
        sub     ah, 41h-1bh     ; extensions
2362
        cmp     ah, 22h
2363
        jbe     short Disk1
2364
        mov     ah, 1           ; bad command error
2365
        jmp     short exit
2366
inINT13:
2367
        mov     ah, 0aah        ; drive not ready
2368
        jmp     short exit2
2369
Disk1:
2370
        mov     bp, ax
2371
        shr     bp, 7
2372
        and     bp, 1feh
2373
        push    ds
2374
        call    cs:disktbl[bp]
2375
        pop     ds
2376
exit:
2377
        mov     HDLastError, ah
2378
exit2:
2379
        xor     byte ptr HDOpStarted, 8
2380
        neg     ah              ; CF <- (AH != 0)
2381
exit1:
2382
        mov     bp, sp
2383
        rcr     byte ptr [bp+8], 1
2384
        rol     byte ptr [bp+8], 1  ; insert error CF on stack
2385
        neg     ah
2386
        pop     bp
2387
        pop     ds
2388
        iret
2389
 
2390
disktbl dw      DiskReset, DiskGetStatus, DiskRead, DiskWrite, DiskVerify, DiskFormat, DiskFormat, DiskFormat, DiskGetParams, DiskInit, DiskRead, DiskWrite, DiskSeek, DiskRst, DiskReadSectBuffer, DiskWriteSectBuffer
2391
        dw      DiskReady, DiskRecalibrate, DiskDiag, DiskDiag, DiskDiag, DiskGetType, DiskChanged, DiskSetDASDType, DiskSetMediaType, DiskPark, DiskFormat,  DiskExtInstCheck, DiskExtRead, DiskExtWrite, DiskExtVerify, DiskExtLock
2392
        dw      DiskExtEject, DiskExtSeek, DiskExtGetParams
2393
 
2394
DiskGetType:
2395
        cmp     dl, 80h
2396
        jne     short DiskReset ; ah=0, drive not present
2397
        mov     cx, HDSize
2398
        mov     dx, cx
2399
        test    cx, cx
2400
        jz      short DiskReset ; ah=0, drive not present
2401
        mov     ah, -3      ; HD present
2402
        shr     cx, 6
2403
        shl     dx, 10      ; CX:DX = HDSize * 1024
2404
DiskGetTypeexit:
2405
        pop     ds          ; discard ret address
2406
        pop     ds          ; discard DS
2407
        xor     byte ptr HDOpStarted, 8     ; CF <- 0
2408
        jmp     short   exit1
2409
 
2410
DiskExtInstCheck:
2411
        xchg    bl, bh
2412
        mov     ah, -1
2413
        mov     cx, 1       ; extended disk access functions (AH=42h-44h,47h,48h) supported
2414
        cmp     dl, 80h
2415
        jne     short notready
2416
        jmp     short DiskGetTypeexit
2417
 
2418
DiskReset:
2419
DiskChanged:
2420
DiskPark:
2421
        mov     ah, 0       ; success
2422
        ret
2423
 
2424
DiskGetStatus:
2425
        mov     ah, HDLastError
2426
        ret
2427
 
2428
DiskVerify:
2429
        mov     bp, sdverify
2430
        jmp     short   DiskRead1
2431
DiskWrite:
2432
        mov     bp, sdwrite
2433
        jmp     short   DiskRead1
2434
DiskRead:
2435
        mov     bp, sdread
2436
DiskRead1:
2437
        test    al, al
2438
        jz      short DiskReset
2439
        cmp     dl, 80h
2440
        jne     short notready
2441
        mov     ah, 4
2442
        test    cl, 3fh
2443
        jz      short DiskReadend   ; bad sector 0
2444
        pusha
2445
        mov     ah, 0
2446
        push    ax
2447
        call    HCStoLBA
2448
        pop     cx
2449
        push    cx
2450
        call    bp              ; DX:AX sector, ES:BX buffer, CX=sectors, returns AX=read sectors
2451
        pop     cx
2452
        sub     cx, ax
2453
        neg     cx              ; CF=1 if cx != 0
2454
        rcl     ah, 3           ; AH = 4*CF (sector not found / read error)
2455
        mov     ds, ax
2456
        popa
2457
        mov     ax, ds
2458
DiskReadend:
2459
        ret
2460
 
2461
HCStoLBA:       ; CX = {cyl[7:0], cyl[9:8], sect[5:0]}, DH = head. Returns DX:AX LBA
2462
        mov     al, ch
2463
        mov     ah, cl
2464
        shr     ah, 6
2465
        shr     dx, 8
2466
        imul    dx, 63
2467
        and     cx, 3fh
2468
        add     cx, dx
2469
        dec     cx
2470
        mov     dx, 255*63
2471
        mul     dx
2472
        add     ax, cx
2473
        adc     dx, 0
2474
        ret
2475
;    unsigned int s = cs & 0x3f;
2476
;    unsigned int c = ((cs & 0xc0) << 2) | (cs >> 8);
2477
;    return (c*255l + h)*63l + s - 1l;
2478
 
2479
DiskFormat:
2480
DiskInit:
2481
DiskSeek:
2482
DiskRst:
2483
DiskReady:
2484
DiskRecalibrate:
2485
DiskDiag:
2486
DiskExtSeek:
2487
        cmp     word ptr HDSize, 0
2488
        je      short notready
2489
        cmp     dl, 80h
2490
        je      short DiskReset
2491
notready:
2492
        mov     ah, 0aah        ; disk not ready
2493
        ret
2494
 
2495
DiskGetParams:
2496
        cmp     dl, 80h
2497
        mov     ah, 7
2498
        jne     short DiskReadend   ; ret
2499
        mov     bl, 0   ; ???
2500
        mov     ax, HDSize
2501
        mov     dx, ax
2502
        shl     ax, 10
2503
        shr     dx, 6
2504
        sub     ax, 30
2505
        sbb     dx, 0
2506
        mov     cx, 63*255
2507
        div     cx
2508
        dec     ax
2509
        cmp     ax, 3feh
2510
        jbe     dgpok
2511
        mov     ax, 3feh
2512
dgpok:
2513
        xchg    al, ah
2514
        shl     al, 6
2515
        or      al, 3fh
2516
        mov     cx, ax
2517
        mov     dx, 0fe01h
2518
        xor     ax, ax
2519
        ret
2520
 
2521
DiskExtVerify:
2522
        mov     bp, sdverify
2523
        jmp     short DiskExtRead1
2524
DiskExtWrite:
2525
        mov     bp, sdwrite
2526
        jmp     short DiskExtRead1
2527
DiskExtRead:
2528
        mov     bp, sdread
2529
DiskExtRead1:
2530
        cmp     dl, 80h
2531
        jne     short notready
2532
        push    es
2533
        push    ax
2534
        pusha
2535
        mov     bx, sp
2536
        mov     ds, ss:[bx+26]
2537
        mov     cx, [si+2]
2538
        les     bx, [si+4]
2539
        mov     ax, [si+8]
2540
        mov     dx, [si+10]
2541
        push    ds
2542
        push    si
2543
        call    bp
2544
        pop     si
2545
        pop     ds
2546
        sub     ax, [si+2]
2547
        add     [si+2], ax
2548
        popa
2549
        pop     ax
2550
        sbb     ah, ah
2551
        and     ah, 4
2552
        pop     es
2553
        ret
2554
 
2555
DiskExtGetParams:
2556
        cmp     dl, 80h
2557
        jne     short notready
2558
        push    ax
2559
        mov     ax, HDSize
2560
        mov     bp, sp
2561
        mov     ds, [bp+8]
2562
        xor     bp, bp
2563
        mov     word ptr [si], 1ah      ; size
2564
        mov     word ptr [si+2], 0bh    ; flags
2565
        mov     word ptr [si+4], 1023   ; cylinders
2566
        mov     word ptr [si+6], bp
2567
        mov     word ptr [si+8], 255    ; heads
2568
        mov     word ptr [si+10], bp
2569
        mov     word ptr [si+12], 63     ; sectors/track
2570
        mov     word ptr [si+14], bp
2571
        mov     word ptr [si+16], ax
2572
        shl     word ptr [si+16], 10
2573
        shr     ax, 6
2574
        mov     word ptr [si+18], ax
2575
        mov     word ptr [si+20], bp
2576
        mov     word ptr [si+22], bp
2577
        mov     word ptr [si+24], 512   ; bytes/sector
2578
        pop     ax
2579
        mov     ah, 0
2580
        ret
2581
 
2582
DiskReadSectBuffer:
2583
DiskWriteSectBuffer:
2584
DiskSetDASDType:
2585
DiskSetMediaType:
2586
DiskExtLock:
2587
DiskExtEject:
2588
        mov     ah, 1       ; unsupported fn
2589
        ret
2590
 
2591
int13   endp
2592
 
2593
 
2594
; --------------------- INT 15h - Extended services ----------------
2595
UFPtr           equ     
2596
WaitCount       equ     
2597
UWaitFlag       equ     
2598
HandlerPtr      equ      ; 4 bytes
2599
DataBuffer      equ      ; 3 bytes
2600
DataCounter     equ      ; 1 byte
2601
PacketSize      equ      ; 1 byte, 0->3bytes, 1->4bytes
2602
FreeXMSKb       equ     (1024 - 16 - 6)*64
2603
 
2604
; ------------ MovExt
2605
IncSeg: ; DX = segment port address
2606
        jnz     short SetSegExit
2607
        in      ax, dx
2608
        and     ax, 3ffh
2609
        inc     ax
2610
        cmp     ax, 12h
2611
        jne     short IncSeg1
2612
        xor     ax, ax
2613
IncSeg1:
2614
        cmp     ax, 0ch
2615
        jne     short SetSeg2
2616
SetSeg: ; DX = segment port address, ax = logical segment (0..1023)
2617
        and     ax, 3ffh
2618
        cmp     ax, 0ch
2619
        jb      short SetSeg1
2620
        add     ax, 6
2621
SetSeg2:
2622
        cmp     ax, 400h
2623
        jb      short SetSeg1
2624
        sub     ax, 400h - 0ch
2625
SetSeg1:
2626
        out     dx, ax
2627
SetSegExit:
2628
        ret
2629
 
2630
MovSeg  equ     01h
2631
savess  dw      0
2632
savesp  dw      MovExt, 0 ; tmp stack
2633
; Log(idx) to Phy(val) segment map (1024segs): 0,1,2,3,4,5,6,7,8,9,a,b,12h,13h,...,3feh,3ffh,c,d,e,f,10h,11h, then wrap to 0,1,2,...
2634
MovExt:
2635
        push    es
2636
        push    ds
2637
        pusha
2638
        cli
2639
        mov     cs:savess, ss
2640
        push    cs
2641
        pop     ss
2642
        xchg    sp, cs:savesp
2643
        mov     dx, 80h + MovSeg + 1
2644
        jcxz    short MovExt_exit
2645
        push    es
2646
        pop     ds
2647
        cld
2648
        mov     al, [si+1ch]
2649
        mov     ah, [si+1fh]
2650
        mov     bl, [si+14h]
2651
        mov     bh, [si+17h]
2652
        mov     di, [si+1ah]
2653
        mov     si, [si+12h]
2654
        call    flush
2655
        call    SetSeg      ; 02000h = destination, DX=82h
2656
        dec     dx
2657
        xchg    ax, bx
2658
        call    SetSeg      ; 01000h = source, DX=81h
2659
        push    MovSeg shl 12
2660
        pop     ds
2661
        push    (MovSeg + 1) shl 12
2662
        pop     es
2663
        xor     bx, bx
2664
        add     cx, cx
2665
        adc     bx, bx      ; BX:CX = bytes to transfer
2666
; move from 01000h:si to 02000h:di, 2*cx bytes
2667
MovExtLoop:
2668
        inc     dx          ; 82h
2669
        mov     ax, si
2670
        cmp     ax, di
2671
        ja      short MovExt1
2672
        mov     ax, di
2673
MovExt1:
2674
        neg     ax
2675
        adc     bx, -1
2676
        sub     cx, ax
2677
        sbb     bx, 0
2678
        xchg    ax, cx      ; cx = bytes to move, bx:ax = bytes left for the next transfer
2679
        jns     short MovExt2   ; ax <= bx:cx
2680
        add     cx, ax
2681
        xor     ax, ax
2682
        inc     bx
2683
MovExt2:
2684
        movsb               ; if CX = 0 transfer 10000h bytes
2685
        dec     cx
2686
        jz      short MovExt_next
2687
        test    si, 1       ; read align
2688
        jz      short raligned
2689
        movsb
2690
        dec     cx
2691
raligned:
2692
        shr     cx, 1
2693
        rep     movsw
2694
        jnc     short MovExt_next
2695
        movsb
2696
MovExt_next:
2697
        call    flush
2698
        mov     cx, ax
2699
        or      ax, bx
2700
        jz      short MovExt_exit  ; finalized
2701
        test    di, di
2702
        call    incseg      ; does nothing if ZF == 0, dx = 8bh
2703
        dec     dx          ; 81h
2704
        test    si, si
2705
        call    incseg      ; dx = 81h
2706
        jmp     short MovExtLoop
2707
MovExt_exit:
2708
        mov     ax, MovSeg + 1
2709
        out     dx, ax      ; 82h
2710
        dec     ax
2711
        dec     dx
2712
        out     dx, ax      ; 81h
2713
        mov     ss, cs:savess
2714
        xchg    sp, cs:savesp
2715
        popa
2716
        pop     ds
2717
        pop     es
2718
        xor     ah, ah
2719
        jmp     short exit_ax
2720
MovExtProxy:
2721
        jmp     MovExt
2722
 
2723
int15:
2724
        cmp     ah, 4fh
2725
        je      short exit_iret
2726
        xchg    al, ah
2727
        cmp     al, 80h
2728
        jb      short exit15; CF=1  for <80h
2729
        cmp     al, 83h
2730
        jb      short done  ; no error for 80, 81, 82
2731
        je      short SetEventWait; 83
2732
        cmp     al, 86h
2733
        jb      short exit15; CF=1 for 84, 85
2734
        je      short Wait1 ; 86
2735
        cmp     al, 88h
2736
        jb      short MovExtProxy ; 87
2737
        je      short ExtSize     ; 88
2738
        cmp     al, 90h
2739
        jb      short  exit15; CF=1 for 89..8f
2740
        cmp     al, 92h
2741
        jb      short done  ; no error for 90, 91
2742
        cmp     al, 0c0h
2743
        jb      short exit15; CF=1 for 92..bf
2744
        je      short GetConfig   ; c0
2745
        cmp     al, 0c2h
2746
        jb      short exit15; CF=1 for c1
2747
        je      short Mouse ; c2
2748
done:
2749
        cmc                 ; CF=1 for >c2
2750
exit15:
2751
        mov     ax, 8600h
2752
exit_ax:
2753
        sti
2754
        retf    2           ; discard flags (need to keep CF)
2755
exit_iret:
2756
        iret
2757
 
2758
; ------------ SetEventWait
2759
SetEventWait:
2760
        push    ds
2761
        push    40h
2762
        pop     ds
2763
        xor     ah, 1
2764
        jz      short cancel
2765
        test    ah, byte ptr UWaitFlag ; ah=1
2766
        jnz     short busy  ; CF=0
2767
        mov     ax, 1000-1  ; 1ms
2768
        out     70h, ax     ; restart RTC timer
2769
        mov     UFPtr[0], bx
2770
        mov     UFPtr[2], es
2771
        add     ax, dx
2772
        adc     cx, 0
2773
        mov     WaitCount[0], ax
2774
        mov     WaitCount[2], cx
2775
        mov     ah, 1       ; wait in progress
2776
cancel:
2777
        mov     byte ptr UWaitFlag, ah
2778
        int     70h
2779
        stc                 ; no error
2780
busy:
2781
        cmc                 ; eror
2782
nowait:
2783
        pop     ds
2784
        jmp     short exit15
2785
 
2786
; ------------ Wait
2787
Wait1:
2788
        push    es
2789
        push    bx
2790
        mov     ax, 8300h
2791
        push    4ah
2792
        pop     es
2793
        xor     bx, bx      ; user wait flag address=0040:00a0
2794
        int     15h         ; returns with IF = 1
2795
        jc      short wbusy
2796
wloop:
2797
        hlt
2798
        test    byte ptr es:[bx], 80h
2799
        jz      short wloop
2800
wbusy:
2801
        pop     bx
2802
        pop     es
2803
        jmp     short exit15
2804
 
2805
 
2806
; ------------ ExtSize
2807
ExtSize:
2808
        mov     ax, FreeXMSKb
2809
        jmp     short exit_ax
2810
 
2811
; ------------ GetConfig
2812
GetConfig:
2813
        xor     ax, ax
2814
        push    cs
2815
        pop     es
2816
        mov     bx, offset SysParams
2817
        jmp     short exit_ax
2818
 
2819
; ------------ Mouse
2820
Mouse:
2821
        push    ds
2822
        push    dx
2823
        push    40h
2824
        pop     ds
2825
        test    byte ptr EquipmentWord, 4 ; ps2 mouse equipement word
2826
        jnz     short mouse_present
2827
if_err:
2828
        mov     ax, 03a7h   ; interface error (no mouse present)
2829
        out     64h, al     ; disable mouse
2830
errexit:
2831
        stc                 ; error
2832
exitok:
2833
        pushf               ; save CF
2834
        in      al, 21h
2835
        and     al, not 10h
2836
        out     21h, al     ; enable mouse interrupts
2837
        call    enableKbIfPresent
2838
        popf
2839
        pop     dx
2840
        pop     ds
2841
        jmp     exit_ax
2842
mouse_present:
2843
        mov     al, ah
2844
        mov     ah, 1       ; invalid function
2845
        cmp     al, 7
2846
        ja      short errexit
2847
        push    ax
2848
        in      al, 21h
2849
        or      al, 10h
2850
        out     21h, al     ; disable mouse interrupts
2851
        sti                 ; allow interrupts for a short time, to flush possible pending KB/mouse requests
2852
        mov     al, 0adh
2853
        out     64h, al     ; disable kb interface
2854
        pop     ax
2855
        cmp     al, 1
2856
        cli                 ; from now on we are working with ints disabled, as the following code is highly non re-entrant
2857
        jb      short en_dis
2858
        je      short reset
2859
        cmp     al, 3
2860
        jb      short sampling
2861
        je      short resolution
2862
        cmp     al, 5
2863
        jb      short gettype
2864
        je      short reset
2865
        cmp     al, 6
2866
        je      short extend
2867
 
2868
; ------------- set handler
2869
        mov     HandlerPtr[0], bx
2870
        mov     HandlerPtr[2], es
2871
        jmp     short exit_success1
2872
 
2873
; ------------- enable/disable
2874
en_dis:
2875
        mov     ax, 02f5h   ; ah = invalid input
2876
        sub     al, bh
2877
        cmp     bh, ah
2878
        jnc     short errexit
2879
        mov     ah, al
2880
        call    sendcmd     ; enable/disable data reporting (CF = 1)
2881
if_err1:
2882
        jc      short if_err
2883
exit_success:
2884
        mov     byte ptr DataCounter, 0
2885
exit_success1:
2886
        xor     ah, ah      ; success
2887
        jmp     short exitok
2888
 
2889
; ------------- reset
2890
reset:
2891
        mov     ah, 0f6h    ; set defaults
2892
        stc                 ; mouse command
2893
        call    sendcmd
2894
        jc      short if_err
2895
        mov     bx, 00aah
2896
        mov     byte ptr PacketSize, bh ; 3bytes packet
2897
        jmp     short exit_success
2898
 
2899
; ------------- sampling
2900
sampling:
2901
        cmp     bh, 6
2902
badparam:
2903
        mov     ah, 2       ; invalid input
2904
        ja      short errexit
2905
        shr     bx, 8
2906
        mov     ah, cs:sample_tbl[bx]
2907
        push    ax
2908
        mov     ah, 0f3h    ; st sample rate
2909
send2c:
2910
        stc
2911
        call    sendcmd
2912
        pop     ax
2913
        jc      short if_err1
2914
send1c:
2915
        stc
2916
        call    sendcmd
2917
        jmp     short if_err1
2918
 
2919
; ------------- resolution
2920
resolution:
2921
        cmp     bh, 3
2922
        ja      short badparam
2923
        push    bx
2924
        mov     ah, 0e8h    ; set resolution
2925
        jmp     short send2c
2926
 
2927
; ------------- gettype
2928
gettype:
2929
        mov     ah, 0f2h
2930
        stc
2931
        call    sendcmd
2932
        jc      short if_err1
2933
        call    getps2byte
2934
        jc      short if_err1
2935
        mov     bh, al
2936
        neg     al          ; CF=1 if al != 0
2937
        adc     al, bh
2938
        mov     byte ptr PacketSize, al ; 3 or 4 bytes packet
2939
        jmp     short exit_success
2940
 
2941
; ------------- extended commands
2942
extend:
2943
        test    bh, bh
2944
        jnz     short setscaling
2945
        mov     ah, 0e9h    ; status request
2946
        stc
2947
        call    sendcmd
2948
        jc      short if_err1
2949
        call    getps2byte
2950
        jc      short if_err1
2951
        mov     bl, al
2952
        call    getps2byte
2953
        jc      short if_err1
2954
        mov     cl, al
2955
        call    getps2byte
2956
        jc      short if_err1
2957
        pop     dx
2958
        push    ax          ; replace dx on stack
2959
        jmp     short exit_success
2960
setscaling:
2961
        cmp     bh, 2
2962
        ja      short badparam
2963
        mov     ah, 0e5h    ; set scaling 1:1 or 2:1
2964
        add     ah, bh
2965
        jmp     short send1c
2966
 
2967
sample_tbl  db  10, 20, 40, 60, 80, 100, 200
2968
SysParams   db  8, 0, 0fch, 0, 0
2969
;--------------------------------------------------------------------------
2970
; Feature byte 1
2971
; b7: 1=DMA channel 3 used by hard disk
2972
; b6: 1=2 interrupt controllers present
2973
; b5: 1=RTC present
2974
; b4: 1=BIOS calls int 15h/4Fh every key
2975
; b3: 1=wait for extern event supported (Int 15h/41h)
2976
; b2: 1=extended BIOS data area used
2977
; b1: 0=AT or ESDI bus, 1=MicroChannel
2978
; b0: 1=Dual bus (MicroChannel + ISA)
2979
;--------------------------------------------------------------------------
2980
            db      10h
2981
;--------------------------------------------------------------------------
2982
; Feature byte 2
2983
; b7: 1=32-bit DMA supported
2984
; b6: 1=int16h, function 9 supported
2985
; b5: 1=int15h/C6h (get POS data) supported
2986
; b4: 1=int15h/C7h (get mem map info) supported
2987
; b3: 1=int15h/C8h (en/dis CPU) supported
2988
; b2: 1=non-8042 kb controller
2989
; b1: 1=data streaming supported
2990
; b0: reserved
2991
;--------------------------------------------------------------------------
2992
            db      44h
2993
;--------------------------------------------------------------------------
2994
; Feature byte 3
2995
; b7: not used
2996
; b6: reserved
2997
; b5: reserved
2998
; b4: POST supports ROM-to-RAM enable/disable
2999
; b3: SCSI on system board
3000
; b2: info panel installed
3001
; b1: Initial Machine Load (IML) system - BIOS on disk
3002
; b0: SCSI supported in IML
3003
;--------------------------------------------------------------------------
3004
            db      0
3005
;--------------------------------------------------------------------------
3006
; Feature byte 4
3007
; b7: IBM private
3008
; b6: EEPROM present
3009
; b5-3: ABIOS presence (011 = not supported)
3010
; b2: private
3011
; b1: memory split above 16Mb supported
3012
; b0: POSTEXT directly supported by POST
3013
;--------------------------------------------------------------------------
3014
            db      0
3015
;--------------------------------------------------------------------------
3016
; Feature byte 5 (IBM)
3017
; b1: enhanced mouse
3018
; b0: flash EPROM
3019
;--------------------------------------------------------------------------
3020
            db      0
3021
 
3022
 
3023
; --------------------- INT 16h - keyboard interface ----------------
3024
;       AH      Description
3025
;       --      ------------------------------------------------
3026
;       00h     Get a key from the keyboard, return code in AX.
3027
;       01h     Test for available key, ZF=1 if none, ZF=0 and
3028
;               AX contains next key code if key available.
3029
;       02h     Get shift status. Returns shift key status in AL.
3030
;       03h     Set Autorepeat rate. BH=0,1,2,3 (delay time in quarter seconds), BL=0..1Fh for 30 char/sec to 2 char/sec repeat rate.
3031
;       05h     Store scan code (in CX) in the type ahead buffer.
3032
;       10h     Get a key (same as 00h in this implementation).
3033
;       11h     Test for key (same as 01h).
3034
;       12h     Get extended key status. Returns status in AX.
3035
 
3036
AltKpd          equ     
3037
HeadPtr         equ     
3038
TailPtr         equ     
3039
Buffer          equ     ;1eh
3040
EndBuf          equ     ;3eh
3041
 
3042
int16 proc near
3043
        push    ds
3044
        push    si
3045
        push    40h
3046
        pop     ds
3047
        xchg    al, ah          ;shorter opcodes for al than ah
3048
        dec     ax
3049
        test    al, 0EFh        ;Check for 01h and 11h
3050
        jz      short TestKey   ;TestKey does not need cld
3051
        inc     ax
3052
        cld
3053
        test    al, 0EFh        ;Check for 0h and 10h
3054
        jz      short GetKey
3055
        cmp     al, 3           ;Check for 02h and 03h
3056
        jb      short GetStatus
3057
        je      short SetAutoRpt
3058
        cmp     al, 5           ;Check for StoreKey function.
3059
        je      short StoreKey
3060
        cmp     al, 9           ;Get KB functionality
3061
        je      short kbfunc
3062
        cmp     al, 12h         ;Extended status call
3063
        je      short ExtStatus
3064
        cmp     al, 92h         ;stupid keyb.com
3065
        jne     short Exit
3066
kbfunc:
3067
        mov     al, 24h         ;AL=20h (fn 10h, 12h supported, set typematic supported)
3068
Exit:
3069
        pop     si
3070
        pop     ds
3071
        iret                    ; unknown function, Restores flags.
3072
 
3073
GetKey1:                        ; wait for interrupt
3074
        hlt
3075
GetKey: ; ----------- fn 00h, 10h
3076
        mov     ah, 11h
3077
        int     16h             ;See if key is available (IF becomes 1 after this int)
3078
        jz      short GetKey1   ;Wait for keystroke.
3079
        cli                     ;Critical region! Ints off.
3080
        mov     si, HeadPtr     ;Ptr to next character.
3081
        lodsw                   ;Get the character, Bump up HeadPtr
3082
        cmp     si, EndBuf
3083
        jb      short noWrap
3084
        mov     si, Buffer
3085
noWrap:
3086
        mov     HeadPtr, si
3087
        jmp     short Exit
3088
 
3089
TestKey: ; ---------- fn 01h
3090
        mov     si, HeadPtr
3091
        cmp     si, TailPtr     ;ZF=1, if empty buffer
3092
        lodsw                   ;BIOS returns avail keycode.
3093
        sti                     ;Ints back on.
3094
        pop     si
3095
        pop     ds
3096
        retf    2               ;Pop flags (ZF is important!)
3097
 
3098
StoreKey: ; ---------- fn 05h - Inserts the value in CX into the type ahead buffer.
3099
        mov     si, TailPtr     ;Address where we can put next key code.
3100
        mov     [si], cx        ;Store the key code away
3101
        inc     si
3102
        inc     si              ;Move on to next entry in buf
3103
        cmp     si, EndBuf
3104
        jb      short NoWrap1
3105
        mov     si, Buffer
3106
 NoWrap1:
3107
        mov     al, 1           ;no room
3108
        cmp     si, HeadPtr     ;Data overrun?
3109
        je      short Exit      ;if so, ignore key entry.
3110
        mov     TailPtr, si
3111
        dec     ax              ;al=0
3112
        jmp     short Exit
3113
 
3114
ExtStatus: ; ------- fn 12h - Retrieve the extended keyboard status and return it in AH, and the standard keyboard status in AL.
3115
        mov     al, KbdFlags2
3116
        and     al, 01110111b   ;Clear final sysreq field, and final right alt bit.
3117
        test    al, 100b        ;Test cur sysreq bit.
3118
        jz      short NoSysReq  ;Skip if it's zero.
3119
        sub     al, 10000100b   ;Set final sysreq bit, clear final right ctl bit.
3120
NoSysReq:
3121
        mov     ah, KbdFlags3
3122
        and     ah, 1100b       ;Grab rt alt/ctrl bits.
3123
        or      ah, al          ;Merge into AH.
3124
 
3125
GetStatus: ; --------- fn 02h
3126
        mov     al, KbdFlags1   ;Just return Std Status.
3127
Exit1:
3128
        jmp     short Exit
3129
 
3130
SetAutoRpt: ; ------ fn 03h
3131
        cmp     ah, 5
3132
        jne     short Exit
3133
        push    dx
3134
        shl     bh, 5
3135
        and     bl, 1fh
3136
        or      bl, bh
3137
        and     bl, 7fh
3138
        mov     ah, 0           ; wait LED update progress to finalize
3139
        call    WaitFlag        ; leaves with IF=0
3140
        jc      short timeout
3141
        or      byte ptr KbdFlags4, SetRepeat    ; set auto repeat in progress
3142
        mov     ah, 0f3h        ; set typematic rate and delay
3143
        push    bx
3144
        xor     bl, bl          ; send to kb
3145
        call    sendps2byte
3146
        pop     bx
3147
        jc      short timeout1  ; send timeout
3148
        mov     ah, SetRepeat or AckReceived ; test if ACK received
3149
        call    WaitFlag
3150
        jc      short timeout1
3151
        mov     ah, bl
3152
        xor     bl, bl          ; send to kb
3153
        call    sendps2byte     ; send data
3154
timeout1:
3155
        and     byte ptr KbdFlags4, not SetRepeat
3156
timeout:
3157
        pop     dx
3158
        jmp     short Exit1
3159
 
3160
 
3161
WaitFlag:   ; ah = desired KbdFlags4 & (AckReceived | LEDUpdate | SetRepeat)
3162
        mov     dx, 3dah
3163
        mov     bh, 8*25    ; wait for max 25 * VGA frame time
3164
wf_loop:
3165
        cli
3166
        mov     al, KbdFlags4
3167
        and     al, AckReceived or LEDUpdate or SetRepeat
3168
        cmp     al, ah
3169
        je      short wf_ok ; flag ok, CF=0
3170
        sti
3171
        in      al, dx      ; get vblank
3172
        xor     al, bh
3173
        and     al, 8h
3174
        sub     bh, al
3175
        jnc     short wf_loop     ; IBF - buffer full, no timeout
3176
wf_ok:
3177
        ret
3178
int16 endp
3179
 
3180
; --------------------- INT 18h - BIOS Basic ------------------
3181
int18 proc near
3182
        push    cs
3183
        pop     es
3184
        mov     si, offset booterrmsg
3185
        call    prts
3186
 
3187
;-------------- RS232 bootstrap
3188
        mov     al, 0b4h
3189
        out     43h, al
3190
        mov     ax, 0f000h
3191
        out     42h, al
3192
        out     42h, al      ; 18Hz PIT CH2
3193
          mov ds,ax
3194
          mov es,ax
3195
 
3196
        mov si,100h
3197
          call srecb
3198
        cli
3199
          mov bh,ah
3200
          call srecb
3201
          mov bl,ah
3202
sloop:
3203
          call srecb
3204
          mov [si],ah
3205
          inc si
3206
          dec bx
3207
          jnz short sloop
3208
          db 0eah
3209
        dw 100h,0f000h
3210
 
3211
booterrmsg db   'No boot device available, waiting on RS232 (115200bps, f000:100) ...', 13, 10, 0
3212
int18 endp
3213
 
3214
; --------------------- INT 19h - OS Bootstrap loader ------------------
3215
int19 proc near
3216
        mov     ax, 201h
3217
        mov     cx, 1
3218
        mov     dx, 80h
3219
        push    0
3220
        pop     es
3221
        mov     bx, 7c00h
3222
        int     13h
3223
        jc      int19err
3224
        db      0eah
3225
        dw      7c00h, 0     ; jmp far 0000h:7c00h
3226
int19err:
3227
        int     18h
3228
int19 endp
3229
 
3230
 
3231
; --------------------- INT 1ah - Get System Time ------------------
3232
int1a proc near
3233
        push    ds
3234
        push    40h
3235
        pop     ds
3236
        cmp     ah, 1
3237
        je      setclock
3238
        ja      clockexit
3239
        mov     dx, ds:[6ch]    ; read clock
3240
        mov     cx, ds:[6eh]
3241
        mov     al, ds:[70h]
3242
clockexit:
3243
        cmc     ; CF = 1 on error
3244
clockexit1:
3245
        pop     ds
3246
        sti
3247
        retf    2
3248
 
3249
setclock:
3250
        mov     ds:[6ch], dx
3251
        mov     ds:[6eh], cx
3252
        jmp     short clockexit1    ; CF = 0
3253
int1a endp
3254
 
3255
 
3256
; --------------------- INT 70h - RTC ------------------
3257
int70 proc near
3258
        push    ds
3259
        push    40h
3260
        pop     ds
3261
        test    byte ptr UWaitFlag, 1    ; is wait in progress?
3262
        jz      short exit
3263
        sub     word ptr WaitCount[0], 1000
3264
        sbb     word ptr WaitCount[2], 0
3265
        jnc     short exit
3266
        mov     byte ptr UWaitFlag, 0
3267
        push    bx
3268
        lds     bx, UFPtr
3269
        or      byte ptr [bx], 80h
3270
        pop     bx
3271
exit:
3272
        pop     ds
3273
        iret
3274
int70 endp
3275
 
3276
 
3277
; --------------------- INT 74h - mouse ------------------
3278
int74 proc near
3279
        cld
3280
        pusha
3281
        push    ds
3282
        push    40h
3283
        pop     ds
3284
        mov     ah, 0
3285
        in      al, 60h
3286
        mov     bx, ax
3287
        inc     byte ptr DataCounter
3288
        mov     al, DataCounter
3289
        mov     si, ax
3290
        sub     al, 3
3291
        ja      short docall
3292
        mov     DataBuffer[si-1], bl
3293
        cmp     al, PacketSize
3294
        jne     short nocall
3295
        mov     bl, 0
3296
docall:
3297
        mov     byte ptr DataCounter, bh    ; BH=0
3298
        mov     si, offset DataBuffer-2
3299
        lodsw
3300
        or      ax, [si-4]
3301
        jz      short nocall
3302
        sti
3303
        push    es
3304
        mov     ah, 0
3305
        lodsb
3306
        push    ax
3307
        lodsb
3308
        push    ax
3309
        lodsb
3310
        push    ax
3311
        push    bx
3312
        call    far ptr [si-7]
3313
        add     sp, 8
3314
        pop     es
3315
nocall:
3316
        pop     ds
3317
        popa
3318
        iret
3319
int74 endp
3320
 
3321
 
3322
; ----------------  serial receive byte 115200 bps --------------
3323
srecb:  mov     ah, 80h
3324
        mov     dx, 3dah
3325
        mov     cx, -5aeh ; (half start bit)
3326
srstb:  in      al, dx
3327
          shr     al, 2
3328
          jc      short srstb
3329
        in      al, 42h ; lo counter
3330
        add     ch, al
3331
        in      al, 42h ; hi counter, ignore
3332
l1:
3333
        call    dlybit
3334
          in      al, dx
3335
        shr     al, 2
3336
          rcr     ah, 1
3337
          jnc     short l1
3338
dlybit:
3339
        sub     cx, 0a5bh  ;  (full bit)
3340
dly1:
3341
        in      al, 42h
3342
        cmp     al, ch
3343
        in      al, 42h
3344
        jnz     short dly1
3345
        ret
3346
 
3347
; -------------------- KB/Mouse access ----------------
3348
sendps2byte proc near   ; ah=data, bl!=0 for mouse, 0 for kb. returns cf=1 if timeout (al = 8)
3349
; changes BH, AL
3350
        push    dx
3351
        mov     dx, 3dah
3352
        mov     bh, 8*5
3353
sps2b2:
3354
        in      al, 64h
3355
        test    al, 2
3356
        jz      short sps2b1; buffer empty
3357
        in      al, dx      ; get vblank
3358
        xor     al, bh
3359
        and     al, 8h
3360
        sub     bh, al
3361
        jnc     short sps2b2; IBF - buffer full, no timeout
3362
        jmp     short exit  ; timeout, CF=1
3363
sps2b1:
3364
        test    bl, bl      ; CF=0
3365
        jz      short sps2_kb
3366
        mov     al, 0d4h    ; next mouse
3367
        out     64h, al
3368
sps2_kb:
3369
        mov     al, ah
3370
        out     60h, al     ; send byte
3371
exit:
3372
        pop     dx
3373
        ret
3374
sendps2byte endp
3375
 
3376
getps2byte proc near    ; returns al=data, zf=0 for mouse, 1 for kb, cf=1 if timeout (al=8)
3377
; changes BH, DX, AL
3378
        mov     dx, 3dah
3379
        mov     bh, 8*5
3380
gps2b2:
3381
        in      al, 64h
3382
        test    al, 1
3383
        jnz     short gps2b1     ; OBF (buffer full), continue
3384
        in      al, dx     ; get vblank
3385
        xor     al, bh
3386
        and     al, 8
3387
        sub     bh, al
3388
        jnc     short gps2b2     ; buffer empty, no timeout
3389
        ret                ; timeout, CF=1
3390
gps2b1:
3391
        test    al, 20h    ; CF=0, ZF <- !MOBF
3392
        in      al, 60h    ; read byte (if IF=1, this data may be invalid)
3393
        ret
3394
getps2byte endp
3395
 
3396
sendcmd proc near     ; ah = command, CF=1 for mouse, CF=0 for kb. returns CF=1 on error
3397
        sbb     bl, bl      ; bl <- CF
3398
        call    sendps2byte
3399
        jc      short exit
3400
retry:
3401
        call    getps2byte
3402
        jc      short exit
3403
        cmp     al, 0fah    ; ack (returns CF=1 on error, when al=8)
3404
        jne     short retry
3405
exit:
3406
        ret
3407
sendcmd endp
3408
 
3409
enableKbIfPresent proc near ; input DS = 40h
3410
; modify AL, flags
3411
        test    byte ptr KbdFlags3, 10h
3412
        jz      short noenablekb
3413
        mov     al, 0aeh
3414
        out     64h, al     ; enable kb interface
3415
noenablekb:
3416
        ret
3417
enableKbIfPresent endp
3418
 
3419
; ----------------------- default interrupt handler ---------------
3420
defint  proc near
3421
        iret
3422
defint  endp
3423
 
3424
; ------------------------------- flush --------------------------
3425
flush:
3426
        pop     cs:flushret
3427
flush_nostack:
3428
        mov     cs:flushbh, bh
3429
        mov     bh, 7       ; flush all 7 cache lines (the 8th one is CS:IP)
3430
flush1:
3431
        test    bl, cs:[bx + 0e000h]
3432
        dec     bh
3433
        jnz     short flush1
3434
        mov     bh, cs:flushbh
3435
        jmp     word ptr cs:flushret
3436
flushret dw 0
3437
flushbh  db 0
3438
 
3439
; ------------------------------- misc --------------------------
3440
dispAX:
3441
        push    dx
3442
        xor     dx, dx
3443
        div     word ptr cs:ten
3444
        test    ax, ax
3445
        jz      dispAX1
3446
        call    dispAX
3447
dispAX1:
3448
        xchg    ax, dx
3449
        add     ax, 0e00h + '0'
3450
        int     10h
3451
        pop     dx
3452
        ret
3453
ten     dw      10
3454
 
3455
prts:   ; es:si = string
3456
        mov     ah, 0eh
3457
        lodsb   es:[si]
3458
        or      al, al
3459
        jz      short prtse
3460
        int     10h
3461
        jmp     short prts
3462
prtse:
3463
        ret
3464
 
3465
 
3466
 
3467
;---------------------  read/write byte ----------------------
3468
sdrb:   mov al,0ffh
3469
sdsb:               ; in AL=byte, DX = 03dah, out AX=result
3470
        out     dx, al
3471
        add     ax, ax
3472
        out     dx, al
3473
        add     ax, ax
3474
        out     dx, al
3475
        add     ax, ax
3476
        out     dx, al
3477
        add     ax, ax
3478
        out     dx, al
3479
        add     ax, ax
3480
        out     dx, al
3481
        add     ax, ax
3482
        out     dx, al
3483
        add     ax, ax
3484
        out     dx, al
3485
        in      ax, dx
3486
        ret
3487
 
3488
;---------------------  write block ----------------------
3489
sdwblk proc near              ; in SI=data ptr, DX=03dah, CX=size
3490
        shr     cx, 1
3491
sdwblk1:
3492
        lodsb
3493
        out     dx, al
3494
        add     ax, ax
3495
        out     dx, al
3496
        add     ax, ax
3497
        out     dx, al
3498
        add     ax, ax
3499
        out     dx, al
3500
        add     ax, ax
3501
        out     dx, al
3502
        add     ax, ax
3503
        out     dx, al
3504
        add     ax, ax
3505
        out     dx, al
3506
        add     ax, ax
3507
        out     dx, al
3508
        lodsb
3509
        out     dx, al
3510
        add     ax, ax
3511
        out     dx, al
3512
        add     ax, ax
3513
        out     dx, al
3514
        add     ax, ax
3515
        out     dx, al
3516
        add     ax, ax
3517
        out     dx, al
3518
        add     ax, ax
3519
        out     dx, al
3520
        add     ax, ax
3521
        out     dx, al
3522
        add     ax, ax
3523
        out     dx, al
3524
        loop    short sdwblk1
3525
        ret
3526
sdwblk endp
3527
 
3528
;---------------------  read block ----------------------
3529
sdrblk proc near              ; in DI=data ptr, DX=03dah, CX=size. Returns CF = 0
3530
        mov     al, 0ffh
3531
        out     dx, al
3532
        shr     cx, 1         ; CF = 0
3533
        out     dx, al
3534
        jmp     short sdrblk2
3535
sdrblk1:
3536
        out     dx, al
3537
        mov     [di], ah
3538
        out     dx, al
3539
        inc     di
3540
sdrblk2:
3541
        out     dx, al
3542
        nop
3543
        out     dx, al
3544
        nop
3545
        out     dx, al
3546
        nop
3547
        out     dx, al
3548
        nop
3549
        out     dx, al
3550
        nop
3551
        out     dx, al
3552
        in      ax, dx
3553
        out     dx, al
3554
        mov     [di], ah
3555
        out     dx, al
3556
        inc     di
3557
        out     dx, al
3558
        nop
3559
        out     dx, al
3560
        nop
3561
        out     dx, al
3562
        nop
3563
        out     dx, al
3564
        nop
3565
        out     dx, al
3566
        nop
3567
        out     dx, al
3568
        in      ax, dx
3569
        loop    short sdrblk1
3570
        mov     [di], ah
3571
        inc     di
3572
        ret
3573
sdrblk endp
3574
 
3575
;---------------------  verify block ----------------------
3576
sdvblk:              ; in DI=data ptr, DX=03dah, CX=size. Returns CF=1 on error
3577
        push    bx
3578
        xor     bl, bl
3579
sdvblk1:
3580
        call    sdrb
3581
        sub     ah, [di]
3582
        or      bl, ah
3583
        inc     di
3584
        loop    short sdvblk1
3585
        neg     bl  ; CF=1 if BL != 0
3586
        pop     bx
3587
        ret
3588
 
3589
;---------------------  write command ----------------------
3590
sdcmd8T:
3591
        call    sdrb
3592
sdcmd:              ; in SI=6 bytes cmd buffer, DX=03dah, out AH = 0ffh on error
3593
        mov     cx, 6
3594
        call    sdwblk
3595
sdresp:
3596
        xor     si, si
3597
sdresp1:
3598
        call    sdrb
3599
        inc     si
3600
        jz      short sdcmd1
3601
        cmp     ah, 0ffh
3602
        je      short sdresp1
3603
sdcmd1: ret
3604
 
3605
;---------------------  read ----------------------
3606
sdverify:
3607
        push    sdvblk
3608
        jmp     short sdread1
3609
sdread:   ; DX:AX sector, ES:BX buffer, CX=sectors. returns AX=read sectors
3610
        push    sdrblk   ; push proc address (read or verify) on stack
3611
sdread1:
3612
        push    ax
3613
        mov     al, dl
3614
        push    ax
3615
        mov     dl, 51h  ; CMD17
3616
        cmp     cx, 1
3617
        je      short sdr1s
3618
        inc     dx      ; CMD18 - multiple sectors
3619
sdr1s:
3620
        push    dx
3621
        mov     si, sp
3622
 
3623
        mov     dx, 3dah
3624
        mov     ah, 1
3625
        out     dx, ax       ; CS on
3626
        mov     di, bx
3627
        mov     bx, cx
3628
        mov     bp, cx       ; save sectors number
3629
        push    ss
3630
        pop     ds
3631
        call    sdcmd
3632
        add     sp, 6
3633
        or      ah, ah
3634
        jnz     short sdr11   ; error
3635
        push    es
3636
        pop     ds
3637
sdrms:
3638
        mov     ax, di
3639
        shr     ax, 4
3640
        mov     si, ds
3641
        add     ax, si
3642
        mov     ds, ax
3643
        and     di, 15
3644
        call    sdresp     ; wait for 0feh token
3645
        cmp     ah, 0feh
3646
        jne     short sdr11; read token error
3647
        mov     ch, 2      ; 512 byte sector
3648
        pop     si
3649
        call    si         ; sdrblk or sdvblk
3650
        push    si
3651
        pushf
3652
        call    sdrb       ; ignore CRC
3653
        call    sdrb       ; ignore CRC
3654
        popf
3655
        jc      short sdr3 ; verify error
3656
        dec     bx
3657
        jnz     short sdrms; multiple sectors
3658
sdr3:
3659
        cmp     bp, 1
3660
        je      short sdr11; single sector
3661
        mov     si, offset SD_CMD12 ; stop transfer
3662
        push    cs
3663
        pop     ds
3664
        call    sdcmd
3665
sdr2:
3666
        shr     ah, 1
3667
        jnc     short sdr11
3668
        call    sdrb
3669
        jmp     short sdr2
3670
sdr11:
3671
        pop     ax         ; remove proc address from stack
3672
sdr1:
3673
        xor     ax, ax
3674
        out     dx, ax
3675
        call    sdrb       ; 8T
3676
        mov     ax, bp
3677
        sub     ax, bx
3678
        ret
3679
 
3680
;---------------------  write ----------------------
3681
sdwrite:   ; DX:AX sector, ES:BX buffer, CX=sectors, returns AX=wrote sectors
3682
        push    ax
3683
        mov     al, dl
3684
        push    ax
3685
        mov     dl, 58h  ; CMD24
3686
        cmp     cx, 1
3687
        je      short sdw1s
3688
        inc     dx      ; CMD25 - multiple sectors
3689
sdw1s:
3690
        push    dx
3691
        mov     si, sp
3692
 
3693
        mov     dx, 3dah
3694
        mov     ah, 1
3695
        out     dx, ax       ; CS on
3696
        mov     bp, cx       ; save sectors number
3697
        push    ss
3698
        pop     ds
3699
        call    sdcmd
3700
        add     sp, 6
3701
        mov     si, bx
3702
        mov     bx, bp
3703
        or      ah, ah
3704
        jnz     short sdr1   ; error
3705
        push    es
3706
        pop     ds
3707
sdwms:
3708
        mov     ax, si
3709
        shr     ax, 4
3710
        mov     di, ds
3711
        add     ax, di
3712
        mov     ds, ax
3713
        and     si, 15
3714
        mov     al, 0feh      ; start token
3715
        cmp     bp, 1
3716
        je      short sdw1s1
3717
        mov     al, 0fch   ; multiple sectors
3718
sdw1s1:
3719
        call    sdsb
3720
        mov     ch, 2      ; 512 byte sector
3721
        call    sdwblk
3722
        call    sdrb       ; ignore CRC
3723
        call    sdrb       ; ignore CRC
3724
        call    sdrb       ; read response byte xxx00101
3725
        and     ah, 0eh
3726
        cmp     ah, 4
3727
        jne     short sdr1 ; write error
3728
sdwwait:
3729
        call    sdrb
3730
        shr     ah, 1
3731
        jnc     short sdwwait     ; wait write completion
3732
        dec     bx
3733
        jnz     short sdwms       ; multiple sectors
3734
 
3735
        cmp     bp, 1
3736
        je      short sdr1
3737
        mov     al, 0fdh     ; multiple end transfer
3738
        call    sdsb
3739
sdwwait1:
3740
        call    sdrb
3741
        shr     ah, 1
3742
        jnc     short sdwwait1     ; wait write completion
3743
        jmp     sdr1
3744
 
3745
;---------------------  init SD ----------------------
3746
sdinit  proc near       ; returns AX = num kilosectors
3747
        push    ds
3748
        push    cx
3749
        push    dx
3750
        push    si
3751
        push    di
3752
        mov     dx, 3dah
3753
        mov     cx, 10
3754
sdinit1:                   ; send 80T
3755
        call    sdrb
3756
        loop    short sdinit1
3757
 
3758
        mov     ah, 1
3759
        out     dx, ax       ; select SD
3760
 
3761
        mov     si, offset SD_CMD0
3762
        push    cs
3763
        pop     ds
3764
        call    sdcmd
3765
        dec     ah
3766
        jnz     short sdexit ; error
3767
 
3768
        mov     si, offset SD_CMD8
3769
        call    sdcmd8T
3770
        dec     ah
3771
        jnz     short sdexit ; error
3772
        mov     cl, 4
3773
        sub     sp, cx
3774
        mov     di, sp
3775
        push    ss
3776
        pop     ds
3777
        call    sdrblk
3778
        pop     ax
3779
        pop     ax
3780
        cmp     ah, 0aah
3781
        jne     short sdexit ; CMD8 error
3782
repinit:
3783
        mov     si, offset SD_CMD55
3784
        push    cs
3785
        pop     ds
3786
        call    sdcmd8T
3787
        call    sdrb
3788
        mov     si, offset SD_CMD41
3789
        call    sdcmd
3790
        dec     ah
3791
        jz      short repinit
3792
 
3793
        mov     si, offset SD_CMD58
3794
        call    sdcmd8T
3795
        mov     cl, 4
3796
        sub     sp, cx
3797
        mov     di, sp
3798
        push    ss
3799
        pop     ds
3800
        call    sdrblk
3801
        pop     ax
3802
        test    al, 40h     ; test OCR bit 30 (CCS)
3803
        pop     ax
3804
        jz      short sdexit; no SDHC
3805
 
3806
        mov     si, offset SD_CMD9 ; get size info
3807
        push    cs
3808
        pop     ds
3809
        call    sdcmd8T
3810
        or      ah, ah
3811
        jnz     short sdexit
3812
        call    sdresp     ; wait for 0feh token
3813
        cmp     ah, 0feh
3814
        jne     short sdexit
3815
        mov     cl, 18       ; 16bytes + 2bytes CRC
3816
        sub     sp, cx
3817
        mov     di, sp
3818
        push    ss
3819
        pop     ds
3820
        call    sdrblk
3821
        mov     cx, [di-10]
3822
        rol     cx, 8
3823
        inc     cx
3824
        mov     sp, di
3825
sdexit:
3826
        xor     ax, ax       ; raise CS
3827
        out     dx, ax
3828
        call    sdrb
3829
        pop     di
3830
        pop     si
3831
        pop     dx
3832
        mov     ax, cx
3833
        pop     cx
3834
        pop     ds
3835
        ret
3836
sdinit endp
3837
 
3838
SD_CMD0     db  40h, 0, 0, 0, 0, 95h
3839
SD_CMD8     db  48h, 0, 0, 1, 0aah, 087h
3840
SD_CMD9     db  49h, 0, 0, 0, 0, 0ffh
3841
SD_CMD12    db  4ch, 0, 0, 0, 0, 0ffh
3842
SD_CMD41    db  69h, 40h, 0, 0, 0, 0ffh
3843
SD_CMD55    db  77h, 0, 0, 0, 0, 0ffh
3844
SD_CMD58    db  7ah, 0, 0, 0, 0, 0ffh
3845
 
3846
 
3847
default_pal:
3848
        db  00h,00h,00h, 00h,00h,2ah, 00h,2ah,00h, 00h,2ah,2ah, 2ah,00h,00h, 2ah,00h,2ah, 2ah,15h,00h, 2ah,2ah,2ah
3849
        db  15h,15h,15h, 15h,15h,3fh, 15h,3fh,15h, 15h,3fh,3fh, 3fh,15h,15h, 3fh,15h,3fh, 3fh,3fh,15h, 3fh,3fh,3fh
3850
        db  00h,00h,00h, 05h,05h,05h, 08h,08h,08h, 0bh,0bh,0bh, 0eh,0eh,0eh, 11h,11h,11h, 14h,14h,14h, 18h,18h,18h
3851
        db  1ch,1ch,1ch, 20h,20h,20h, 24h,24h,24h, 28h,28h,28h, 2dh,2dh,2dh, 32h,32h,32h, 38h,38h,38h, 3fh,3fh,3fh
3852
        db  00h,00h,3fh, 10h,00h,3fh, 1fh,00h,3fh, 2fh,00h,3fh, 3fh,00h,3fh, 3fh,00h,2fh, 3fh,00h,1fh, 3fh,00h,10h
3853
        db  3fh,00h,00h, 3fh,10h,00h, 3fh,1fh,00h, 3fh,2fh,00h, 3fh,3fh,00h, 2fh,3fh,00h, 1fh,3fh,00h, 10h,3fh,00h
3854
        db  00h,3fh,00h, 00h,3fh,10h, 00h,3fh,1fh, 00h,3fh,2fh, 00h,3fh,3fh, 00h,2fh,3fh, 00h,1fh,3fh, 00h,10h,3fh
3855
        db  1fh,1fh,3fh, 27h,1fh,3fh, 2fh,1fh,3fh, 37h,1fh,3fh, 3fh,1fh,3fh, 3fh,1fh,37h, 3fh,1fh,2fh, 3fh,1fh,27h
3856
        db  3fh,1fh,1fh, 3fh,27h,1fh, 3fh,2fh,1fh, 3fh,37h,1fh, 3fh,3fh,1fh, 37h,3fh,1fh, 2fh,3fh,1fh, 27h,3fh,1fh
3857
        db  1fh,3fh,1fh, 1fh,3fh,27h, 1fh,3fh,2fh, 1fh,3fh,37h, 1fh,3fh,3fh, 1fh,37h,3fh, 1fh,2fh,3fh, 1fh,27h,3fh
3858
        db  2dh,2dh,3fh, 31h,2dh,3fh, 36h,2dh,3fh, 3ah,2dh,3fh, 3fh,2dh,3fh, 3fh,2dh,3ah, 3fh,2dh,36h, 3fh,2dh,31h
3859
        db  3fh,2dh,2dh, 3fh,31h,2dh, 3fh,36h,2dh, 3fh,3ah,2dh, 3fh,3fh,2dh, 3ah,3fh,2dh, 36h,3fh,2dh, 31h,3fh,2dh
3860
        db  2dh,3fh,2dh, 2dh,3fh,31h, 2dh,3fh,36h, 2dh,3fh,3ah, 2dh,3fh,3fh, 2dh,3ah,3fh, 2dh,36h,3fh, 2dh,31h,3fh
3861
        db  00h,00h,1ch, 07h,00h,1ch, 0eh,00h,1ch, 15h,00h,1ch, 1ch,00h,1ch, 1ch,00h,15h, 1ch,00h,0eh, 1ch,00h,07h
3862
        db  1ch,00h,00h, 1ch,07h,00h, 1ch,0eh,00h, 1ch,15h,00h, 1ch,1ch,00h, 15h,1ch,00h, 0eh,1ch,00h, 07h,1ch,00h
3863
        db  00h,1ch,00h, 00h,1ch,07h, 00h,1ch,0eh, 00h,1ch,15h, 00h,1ch,1ch, 00h,15h,1ch, 00h,0eh,1ch, 00h,07h,1ch
3864
        db  0eh,0eh,1ch, 11h,0eh,1ch, 15h,0eh,1ch, 18h,0eh,1ch, 1ch,0eh,1ch, 1ch,0eh,18h, 1ch,0eh,15h, 1ch,0eh,11h
3865
        db  1ch,0eh,0eh, 1ch,11h,0eh, 1ch,15h,0eh, 1ch,18h,0eh, 1ch,1ch,0eh, 18h,1ch,0eh, 15h,1ch,0eh, 11h,1ch,0eh
3866
        db  0eh,1ch,0eh, 0eh,1ch,11h, 0eh,1ch,15h, 0eh,1ch,18h, 0eh,1ch,1ch, 0eh,18h,1ch, 0eh,15h,1ch, 0eh,11h,1ch
3867
        db  14h,14h,1ch, 16h,14h,1ch, 18h,14h,1ch, 1ah,14h,1ch, 1ch,14h,1ch, 1ch,14h,1ah, 1ch,14h,18h, 1ch,14h,16h
3868
        db  1ch,14h,14h, 1ch,16h,14h, 1ch,18h,14h, 1ch,1ah,14h, 1ch,1ch,14h, 1ah,1ch,14h, 18h,1ch,14h, 16h,1ch,14h
3869
        db  14h,1ch,14h, 14h,1ch,16h, 14h,1ch,18h, 14h,1ch,1ah, 14h,1ch,1ch, 14h,1ah,1ch, 14h,18h,1ch, 14h,16h,1ch
3870
        db  00h,00h,10h, 04h,00h,10h, 08h,00h,10h, 0ch,00h,10h, 10h,00h,10h, 10h,00h,0ch, 10h,00h,08h, 10h,00h,04h
3871
        db  10h,00h,00h, 10h,04h,00h, 10h,08h,00h, 10h,0ch,00h, 10h,10h,00h, 0ch,10h,00h, 08h,10h,00h, 04h,10h,00h
3872
        db  00h,10h,00h, 00h,10h,04h, 00h,10h,08h, 00h,10h,0ch, 00h,10h,10h, 00h,0ch,10h, 00h,08h,10h, 00h,04h,10h
3873
        db  08h,08h,10h, 0ah,08h,10h, 0ch,08h,10h, 0eh,08h,10h, 10h,08h,10h, 10h,08h,0eh, 10h,08h,0ch, 10h,08h,0ah
3874
        db  10h,08h,08h, 10h,0ah,08h, 10h,0ch,08h, 10h,0eh,08h, 10h,10h,08h, 0eh,10h,08h, 0ch,10h,08h, 0ah,10h,08h
3875
        db  08h,10h,08h, 08h,10h,0ah, 08h,10h,0ch, 08h,10h,0eh, 08h,10h,10h, 08h,0eh,10h, 08h,0ch,10h, 08h,0ah,10h
3876
        db  0bh,0bh,10h, 0ch,0bh,10h, 0dh,0bh,10h, 0fh,0bh,10h, 10h,0bh,10h, 10h,0bh,0fh, 10h,0bh,0dh, 10h,0bh,0ch
3877
        db  10h,0bh,0bh, 10h,0ch,0bh, 10h,0dh,0bh, 10h,0fh,0bh, 10h,10h,0bh, 0fh,10h,0bh, 0dh,10h,0bh, 0ch,10h,0bh
3878
        db  0bh,10h,0bh, 0bh,10h,0ch, 0bh,10h,0dh, 0bh,10h,0fh, 0bh,10h,10h, 0bh,0fh,10h, 0bh,0dh,10h, 0bh,0ch,10h
3879
        db  00h,00h,00h, 00h,00h,00h, 00h,00h,00h, 00h,00h,00h, 00h,00h,00h, 00h,00h,00h, 00h,00h,00h, 00h,00h,00h
3880
 
3881
IFDEF SCANCODE1 ; use SCANCODE1
3882
KeyIndex:
3883
        db      0, 82, 49, 50, 52, 51, 54, 55    ;0-7
3884
        db 56, 57, 60, 59, 65, 68, 72, 47    ;8-f
3885
        db      1,  5,  9, 13, 12, 18, 21, 23    ;10-17
3886
        db 24, 26, 67, 70, 69,  0,  4,  3    ;18-1f
3887
        db      8, 11, 17, 16, 20, 22, 25, 64    ;20-27
3888
        db 66, 48,  0, 71,  2,  7,  6, 10    ;28-2f
3889
        db 15, 14, 19, 58, 61, 62,  0, 87    ;30-37
3890
        db      0, 53,  0, 40, 41, 39, 46, 38    ;38-3f
3891
        db 45, 90, 44, 79, 43,  0, 89, 29    ;40-47
3892
        db 34, 36, 86, 28, 37, 33, 84, 27    ;48-4f
3893
        db 32, 35, 30, 31,  0,  0,      0, 83    ;50-57
3894
        db 42
3895
E0KeyList:
3896
        db      35h, 1ch, 4fh, 4bh, 47h, 52h, 53h, 50h, 4dh, 48h, 51h, 49h
3897
 
3898
ELSE    ; use SCANCODE2
3899
 
3900
KeyIndex:
3901
        db      0, 79,  0, 38, 39, 40, 41, 42
3902
        db      0, 43, 44, 45, 46, 47, 48,  0
3903
        db      0,  0,  0,  0,  0,  1, 49,  0
3904
        db      0,  0,  2,      3,  4,  5, 50,  0
3905
        db      0,  6,  7,      8,  9, 51, 52,  0
3906
        db      0, 53, 10, 11, 12, 13, 54,  0
3907
        db      0, 14, 15, 16, 17, 18, 55,  0
3908
        db      0,  0, 19, 20, 21, 56, 57,  0
3909
        db      0, 58, 22, 23, 24, 59, 60,  0
3910
        db      0, 61, 62, 25, 64, 26, 65,  0
3911
        db      0,  0, 66,      0, 67, 68,      0,  0
3912
        db      0,  0, 69, 70,  0, 71,  0,  0
3913
        db      0,  0,  0,      0,  0,  0, 72,  0
3914
        db      0, 27,  0, 28, 29,  0,  0,  0
3915
        db 30, 31, 32, 37, 33, 34, 82,  0
3916
        db 83, 84, 35, 86, 87, 36, 89,  0
3917
        db      0,  0,  0,      90
3918
E0KeyList:
3919
        db      4ah, 5ah, 69h, 6bh, 6ch, 70h, 71h, 72h, 74h, 75h, 7ah, 7dh
3920
 
3921
ENDIF
3922
 
3923
E0KeyIndex:
3924
        db      63,  69,  73,  74,  75,  76,  77,  78,  80,  81,  85,  88
3925
 
3926
KeyCode:
3927
; Keys affected by CapsLock
3928
;               norm   shft   ctrl   alt
3929
        dw      0000h, 0000h, 0000h, 0000h ;17 - <0>
3930
        dw      1071h, 1051h, 1011h, 1000h ;15 - Q, (E0)PrevTrack <1>
3931
        dw      2c7ah, 2c5ah, 2c1ah, 2c00h ;1a - Z <2>
3932
        dw      1f73h, 1f53h, 1f13h, 1f00h ;1b - S <3>
3933
        dw      1e61h, 1e41h, 1e01h, 1e00h ;1c - A <4>
3934
        dw      1177h, 1157h, 1117h, 1100h ;1d - W <5>
3935
        dw      2e63h, 2e43h, 2e03h, 2e00h ;21 - C, (E0)Volume Down <6>
3936
        dw      2d78h, 2d58h, 2d18h, 2d00h ;22 - X <7>
3937
        dw      2064h, 2044h, 2004h, 2000h ;23 - D, (E0)Mute <8>
3938
        dw      1265h, 1245h, 1205h, 1200h ;24 - E <9>
3939
        dw      2f76h, 2f56h, 2f16h, 2f00h ;2a - V <10>
3940
        dw      2166h, 2146h, 2106h, 2100h ;2b - F, (E0)Calculator <11>
3941
        dw      1474h, 1454h, 1414h, 1400h ;2c - T <12>
3942
        dw      1372h, 1352h, 1312h, 1300h ;2d - R <13>
3943
        dw      316eh, 314eh, 310eh, 3100h ;31 - N <14>
3944
        dw      3062h, 3042h, 3002h, 3000h ;32 - B, (E0)Volume Up <15>
3945
        dw      2368h, 2348h, 2308h, 2300h ;33 - H <16>
3946
        dw      2267h, 2247h, 2207h, 2200h ;34 - G, (E0)Play/Pause <17>
3947
        dw      1579h, 1559h, 1519h, 1500h ;35 - Y <18>
3948
        dw      326dh, 324dh, 320dh, 3200h ;3a - M, (E0)WWW Home <19>
3949
        dw      246ah, 244ah, 240ah, 2400h ;3b - J, (E0)Stop <20>
3950
        dw      1675h, 1655h, 1615h, 1600h ;3c - U <21>
3951
        dw      256bh, 254bh, 250bh, 2500h ;42 - K <22>
3952
        dw      1769h, 1749h, 1709h, 1700h ;43 - I <23>
3953
        dw      186fh, 184fh, 180fh, 1800h ;44 - O <24>
3954
        dw      266ch, 264ch, 260ch, 2600h ;4b - L <25>
3955
        dw      1970h, 1950h, 1910h, 1900h ;4d - P, (E0)Next Track <26>
3956
; keys affected by NumLock
3957
        dw      4f00h, 4f31h, 7500h, 0002h ;69 - KP1 <27>
3958
        dw      4b00h, 4b34h, 7300h, 0005h ;6b - KP4 <28>
3959
        dw      4700h, 4737h, 7700h, 0008h ;6c - KP7 <29>
3960
        dw      5200h, 5230h, 9200h, 0001h ;70 - KP0 <30>
3961
        dw      5300h, 532eh, 9300h, 0000h ;71 - KP. <31>
3962
        dw      5000h, 5032h, 9100h, 0003h ;72 - KP2 <32>
3963
        dw      4d00h, 4d36h, 7400h, 0007h ;74 - KP6 <33>
3964
        dw      4800h, 4838h, 8d00h, 0009h ;75 - KP8 <34>
3965
        dw      5100h, 5133h, 7600h, 0004h ;7a - KP3 <35>
3966
        dw      4900h, 4939h, 8400h, 000ah ;7d - KP9 <36>
3967
        dw      4c00h, 4c35h, 8f00h, 0006h ;73 - KP5 --- on VMWare, it does not send 4c00 <37>
3968
; keys unaffected by CapsLock or N
3969
        dw      3f00h, 5800h, 6200h, 6c00h ;03 - F5 <38>
3970
        dw      3d00h, 5600h, 6000h, 6a00h ;04 - F3 <39>
3971
        dw      3b00h, 5400h, 5e00h, 6800h ;05 - F1 <40>
3972
        dw      3c00h, 5500h, 5f00h, 6900h ;06 - F2 <41>
3973
        dw      8600h, 8800h, 8a00h, 8c00h ;07 - F12 <42>
3974
        dw      4400h, 5d00h, 6700h, 7100h ;09 - F10 <43>
3975
        dw      4200h, 5b00h, 6500h, 6f00h ;0a - F8 <44>
3976
        dw      4000h, 5900h, 6300h, 6d00h ;0b - F6 <45>
3977
        dw      3e00h, 5700h, 6100h, 6b00h ;0c - F4 <46>
3978
        dw      0f09h, 0f00h, 9400h, 0000h ;0d - TAB <47>
3979
        dw      2960h, 297eh, 0000h, 2900h ;0e - ` ~ <48>
3980
        dw      0231h, 0221h, 0000h, 7800h ;16 - 1 ! <49>
3981
        dw      0332h, 0340h, 0300h, 7900h ;1e - 2 @ <50>
3982
        dw      0534h, 0524h, 0000h, 7b00h ;25 - 4 $ <51>
3983
        dw      0433h, 0423h, 0000h, 7a00h ;26 - 3 # <52>
3984
        dw      3920h, 3920h, 3920h, 3920h ;29 - SPC <53>
3985
        dw      0635h, 0625h, 0000h, 7c00h ;2e - 5 % <54>
3986
        dw      0736h, 075eh, 071eh, 7d00h ;36 - 6 ^ <55>
3987
        dw      0837h, 0826h, 0000h, 7e00h ;3d - 7 & <56>
3988
        dw      0938h, 092ah, 0000h, 7f00h ;3e - 8 * <57>
3989
        dw      332ch, 333ch, 0000h, 3300h ;41 - , < <58>
3990
        dw      0b30h, 0b29h, 0000h, 8100h ;45 - 0 ) <59>
3991
        dw      0a39h, 0a28h, 0000h, 8000h ;46 - 9 ( <60>
3992
        dw      342eh, 343eh, 0000h, 3400h ;49 - . > <61>
3993
        dw      352fh, 353fh, 0000h, 3500h ;4a - / ? <62>
3994
        dw      0e02fh, 0e02fh, 9500h, 0a400h ;4a - (e0)KP/ <63>
3995
        dw      273bh, 273ah, 0000h, 2700h ;4c - ; : <64>
3996
        dw      0c2dh, 0c5fh, 0c1fh, 8200h ;4e - - _ <65>
3997
        dw      2827h, 2822h, 0000h, 2800h ;52 - ’ “ <66>
3998
        dw      1a5bh, 1a7bh, 1a1bh, 1a00h ;54 - [ { <67>
3999
        dw      0d3dh, 0d2bh, 0000h, 8300h ;55 - = + <68>
4000
        dw      1c0dh, 1c0dh, 1c0ah, 1c00h ;5a - Enter, (E0)KPEnter <69>
4001
        dw      1b5dh, 1b7dh, 1b1dh, 1b00h ;5b - ] } <70>
4002
        dw      2b5ch, 2b7ch, 2b1ch, 2b00h ;5d - \ | <71>
4003
        dw      0e08h, 0e08h, 0e7fh, 0e00h ;66 - BKSP <72>
4004
        dw      4f00h, 4f00h, 7500h, 9f00h ;69 - (E0)END <73>
4005
        dw      4b00h, 4b00h, 7300h, 9b00h ;6b - (E0)LEFT <74>
4006
        dw      4700h, 4700h, 7700h, 9700h ;6c - (E0)HOME <75>
4007
        dw      5200h, 5200h, 9200h, 0a200h ;70 - (E0)INS <76>
4008
        dw      5300h, 5300h, 9300h, 0a300h ;71 - (E0)DEL <77>
4009
        dw      5000h, 5000h, 9100h, 0a000h ;72 - (E0)DOWN <78>
4010
        dw      4300h, 5c00h, 6600h, 7000h ;01 - F9 <79>
4011
        dw      4d00h, 4d00h, 7400h, 9d00h ;74 - (E0)RIGHT <80>
4012
        dw      4800h, 4800h, 8d00h, 9800h ;75 - (E0)UP <81>
4013
        dw      011bh, 011bh, 011bh, 0100h ;76 - ESC <82>
4014
        dw      8500h, 8700h, 8900h, 8b00h ;78 - F11 <83>
4015
        dw      4e2bh, 4e2bh, 9000h, 4e00h ;79 - KP+ <84>
4016
        dw      5100h, 5100h, 7600h, 0a100h ;7a - (E0)PGDN <85>
4017
        dw      4a2dh, 4a2dh, 8e00h, 4a00h ;7b - KP- <86>
4018
        dw      372ah, 372ah, 9600h, 3700h ;7c - KP* --- on VMWare, it does not send 3710h with CTL <87>
4019
        dw      4900h, 4900h, 8400h, 9900h ;7d - (E0)PGUP <88>
4020
        dw      4600h, 4600h, 4600h, 4600h ;7e - SCRL <89>
4021
        dw      4100h, 5a00h, 6400h, 6e00h ;83 - F7 <90>
4022
 
4023
; ------------------------- POWER ON RESET -----------------------
4024
        org     0fff0h
4025
 
4026
        db      0eah
4027
        dw      coldboot, 0f000h
4028
        db      '02/05/13'
4029
        db      0ffh, 0ffh, 0
4030
end bios

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.