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 7

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 7 ndumitrach
;        test    bx, not 101h                ; BX validation
1229
;        jnz     short VESAGetModeInfo1      ; error
1230 3 ndumitrach
        push    cs
1231 7 ndumitrach
        push    offset VESASupported
1232
;        call    VESAMemControlCB
1233
;        jmp     short VESASupported
1234 3 ndumitrach
VESAMemControlCB:
1235 7 ndumitrach
        pushf
1236
        cli
1237 3 ndumitrach
        push    ax
1238
        push    dx
1239
        mov     ax, bx
1240
        and     ax, 1
1241
        add     al, 8ah
1242
        xchg    ax, dx
1243
        and     ax, 7
1244
        add     al, 0ah
1245
        test    bh, bh
1246
        jnz     getpageinfo
1247
        call    flush
1248
        out     dx, ax
1249
        pop     dx
1250
        pop     ax
1251 7 ndumitrach
        popf
1252 3 ndumitrach
        retf
1253
getpageinfo:
1254
        in      ax, dx
1255
        sub     al, 0ah
1256
        and     ax, 7
1257
        xchg    ax, dx
1258
        pop     ax
1259
        pop     ax
1260 7 ndumitrach
        popf
1261 3 ndumitrach
        retf
1262
 
1263
VESAInfo    db  'VESA'
1264
            dw  100h, VESAOEM, 0f000h, 2, 0, VESAModes, 0f000h, 8
1265
VESAOEM     db  'Nicolae Dumitrache', 0
1266
VESAModes   dw  101h, 0ffffh
1267
VESAModeInfo:
1268
;Bit(s)  Description - mode attributes
1269
;0      mode supported by present hardware configuration
1270
;1      optional information available (must be =1 for VBE v1.2+)
1271
;2      BIOS output supported
1272
;3      set if color, clear if monochrome
1273
;4      set if graphics mode, clear if text mode
1274
;---VBE v2.0+ ---
1275
;5      mode is not VGA-compatible
1276
;6      bank-switched mode not supported
1277
;7      linear framebuffer mode supported
1278
;8      double-scan mode available (e.g. 320x200 and 320x240)
1279
;---VBE v3.0 ---
1280
;9      interlaced mode available
1281
;10     hardware supports triple buffering
1282
;11     hardware supports stereoscopic display
1283
;12     dual display start address support
1284
;13-15  reserved
1285
        dw  0000000010011001b
1286
;Bit(s)  Description - window attributes
1287
;0      exists
1288
;1      readable
1289
;2      writable
1290
;3-7    reserved
1291
        db  00000111b, 00000111b
1292
        dw  64, 64, 0a000h, 0b000h, VESAMemControlCB, 0f000h, 640
1293
 
1294
 
1295
; --------------- fn 00h, set video mode
1296
setmode:
1297
        pusha
1298
        push    es
1299
        add     al, al      ; CF = cls bit
1300
        rcl     byte ptr EgaMiscInfo, 1
1301
        ror     byte ptr EgaMiscInfo, 1
1302
        cmp     al, 3*2
1303
        ja      short setmode1
1304
        mov     al, 0b6h        ; reset sound generator
1305
        out     43h, al
1306
        mov     al, 0
1307
        out     42h, al
1308
        out     42h, al
1309
        mov     ax, 0806h   ; text mode (80x25, 16 colors), flash enabled
1310
        mov     word ptr ScreenWidth, 80
1311
        mov     word ptr RegenLength, 1000h
1312
        mov     byte ptr ScreenRows, 25-1
1313
        mov     word ptr ScanLinesChar, 16
1314
        mov     bx, 0b800h  ; segment
1315
        mov     cx, 4000h   ; video len/2
1316
        mov     si, 0720h   ; clear value
1317
        jmp     short setmode2
1318
setmode1:
1319
        cmp     al, 13h*2
1320
        jne     short setmode3
1321
        mov     ah, 41h     ; graphic mode, 320x200, 256 colors
1322
        mov     word ptr ScreenWidth, 40
1323
        mov     word ptr RegenLength, 2000h
1324
        jmp     short setmode21
1325
setmode3:
1326
        cmp     al, 25h*2
1327
        jne     short setmodeexit
1328
        mov     ah, 1       ; graphic mode, 640x400, 256 colors
1329
        mov     word ptr ScreenWidth, 80
1330
        mov     word ptr RegenLength, 2000h
1331
setmode21:
1332
        mov     bx, 0a000h  ; segment
1333
        mov     cx, 8000h   ; video len/2 - clears only the first segment (TODO clear full screen)
1334
        xor     si, si      ; clear value
1335
setmode2:
1336
        shr     al, 1
1337
        mov     ActiveVideoMode, al
1338
        push    ax
1339
        push    cx
1340
        push    ds
1341
        pop     es
1342
        xor     ax, ax
1343
        mov     di, offset CursorPos
1344
        mov     cx, 8
1345
        rep     stosw           ; reset cursor position for all pages
1346
        mov     ax, 0500h
1347
        int     10h             ; set page0
1348
        pop     cx
1349
        pop     ax
1350
        test    byte ptr EgaMiscInfo, 80h
1351
        jnz     short setmode4    ; no clear video memory
1352
        mov     es, bx
1353
        xchg    ax, si
1354
        xor     di, di
1355
        rep     stosw
1356
        xchg    ax, si
1357
        call    palpageset
1358
        mov     byte ptr PalPaging, cl  ; reset paging
1359
setmode4:
1360
        mov     dx, 3c0h
1361
        mov     al, 10h
1362
        out     dx, al
1363
        mov     al, ah
1364
        out     dx, al          ; set video mode
1365
        mov     ax, 1123h
1366
        int     10h             ; set ROM 8x8 font for graphics mode
1367
        mov     ah, 1
1368
        xor     cx, cx
1369
        int     10h             ; show cursor
1370
        test    byte ptr VgaFlags, 8     ; test default palette loading
1371
        jnz     short setmodeexit     ; no default palette
1372
        mov     ax, 1012h
1373
        xor     bx, bx
1374
        mov     cx, 100h
1375
        mov     dx, offset default_pal
1376
        push    cs
1377
        pop     es
1378
        int     10h             ; set default palette
1379
setmodeexit:
1380
        pop     es
1381
        popa
1382
nullproc:
1383
        ret
1384
 
1385
; --------------- fn 01h, set cursor shape and visibility (shape is ignored, always lines 14&15 of text mode char)
1386
cursor:     ; CH bit 6 or 5 -> cursor off
1387
        push    ax
1388
        push    dx
1389
        mov     dx, 3d4h
1390
        mov     al, 0ah
1391
        out     dx, al
1392
        mov     al, ch
1393
        shr     al, 1
1394
        or      al, ch
1395
        inc     dx
1396
        out     dx, al
1397
        pop     dx
1398
        pop     ax
1399
        ret
1400
 
1401
;---------------- fn 02h, set cursor pos
1402
curpos:
1403
        push    ax
1404
        push    bx
1405
        mov     al, bh
1406
        shr     bx, 7
1407
        and     bx, 0eh
1408
        mov     CursorPos[bx], dx
1409
        cmp     byte ptr ActiveVideoMode, 3
1410
        jne     short curpos1
1411
        cmp     al, ActivePage
1412
        jne     short curpos1
1413
        push    dx
1414
        xor     ax, ax
1415
        xchg    al, dh
1416
        imul    ax, 80
1417
        add     ax, dx
1418
        mov     dx, 3d4h
1419
        push    ax
1420
        mov     al, 0fh
1421
        out     dx, al
1422
        inc     dx
1423
        pop     ax
1424
        out     dx, al
1425
        dec     dx
1426
        mov     al, 0eh
1427
        out     dx, al
1428
        inc     dx
1429
        mov     al, ah
1430
        out     dx, al
1431
        pop     dx
1432
curpos1:
1433
        pop     bx
1434
        pop     ax
1435
        ret
1436
 
1437
;---------------- fn 03h, get cursor pos
1438
getcurpos:
1439
        push    bx
1440
        shr     bx, 7
1441
        and     bx, 0eh
1442
        mov     dx, CursorPos[bx]
1443
        mov     cx, CursorShape
1444
        pop     bx
1445
        ret
1446
 
1447
;---------------- fn 04h, light pen
1448
lightpen:
1449
        mov     ah, 0   ; not triggered
1450
        ret
1451
 
1452
;---------------- fn 05h, set active video page
1453
apage:
1454
        pusha
1455
        call    flush
1456
        and     al, 7
1457
        mov     bh, al
1458
        mov     ActivePage, al
1459
        mov     al, ActiveVideoMode
1460
        cmp     al, 3
1461
        jne     short apage1
1462
        mov     ax, 0ah
1463
        out     8ah, ax
1464
        inc     ax
1465
        out     8bh, ax
1466
        mov     ah, 3
1467
        int     10h        ; get cursor pos
1468
        mov     ah, 2
1469
        int     10h        ; set cursor pos
1470
        mov     ax, 200h   ; page size / 8
1471
        jmp     short apage2
1472
apage1:                    ; mode 13h and 25h
1473
        mov     ax, 0ah
1474
        add     al, bh
1475
        out     8ah, ax
1476
        inc     ax
1477
        cmp     al, 12h
1478
        jne     short apage4
1479
        mov     al, 0ah
1480
apage4: out     8bh, ax
1481
        mov     ax, 2000h  ; page size / 8
1482
apage2:
1483
        shr     bx, 8      ; page number
1484
        mul     bx
1485
        push    ax
1486
        shl     ax, 3
1487
        mov     PageOffset, ax
1488
        mov     dx, 3d4h
1489
        mov     al, 0dh
1490
        out     dx, al
1491
        inc     dx
1492
        pop     ax
1493
        out     dx, al
1494
        dec     dx
1495
        mov     al, 0ch
1496
        out     dx, al
1497
        inc     dx
1498
        mov     al, ah
1499
        out     dx, al
1500
        popa
1501
        ret
1502
 
1503
;---------------- fn 06h, scroll up / clr
1504
scrollup:
1505
        pusha
1506
        push    es
1507
        xchg    cx, dx
1508
        sub     cx, dx
1509
        inc     cx
1510
        cmp     byte ptr ActiveVideoMode, 13h
1511
        jae     short scrollup1
1512
        call    scr_params
1513
scrollup6:
1514
        push    0b800h          ; segment
1515
        pop     es
1516
        add     dl, dl
1517
        add     di, di
1518
        add     di, PageOffset  ; di = top left corner address
1519
        xchg    ax, cx          ; ah = 0
1520
        test    bl, bl
1521
        jz      short scrollup3       ; clear
1522
        sub     ah, bl
1523
        jb      short scrollup3       ; clear
1524
        add     si, di
1525
scrollup4:
1526
        mov     cl, al
1527
        rep     movsw es:[si], es:[di]
1528
        add     si, dx
1529
        add     di, dx
1530
        dec     ah
1531
        jns     short scrollup4       ; ch = lines - 1
1532
scrollup3:
1533
        add     ah, bl          ; clear rectangle: DI=address, ah=lines, al=columns, bh=attribute
1534
        xchg    ax, bx
1535
        mov     al, ' '
1536
scrollup5:
1537
        mov     cl, bl
1538
        rep     stosw
1539
        add     di, dx
1540
        dec     bh
1541
        jns     short scrollup5       ; ch = lines - 1
1542
scrollexit:
1543
        pop     es
1544
        popa
1545
        ret
1546
scrollup1:
1547
        ja     short scrollup2
1548
; TODO mode13h scroll up
1549
        jmp     short scrollexit
1550
scrollup2:
1551
; TODO mode25h scroll up
1552
        jmp     short scrollexit
1553
 
1554
;---------------- fn 07h, scroll dn / clr
1555
scrolldn:
1556
        std
1557
        pusha
1558
        push    es
1559
        neg     cx
1560
        add     cx, dx
1561
        inc     cx
1562
        cmp     byte ptr ActiveVideoMode, 13h
1563
        jae     short scrolldn1
1564
        call    scr_params
1565
        neg     dx
1566
        neg     si
1567
        jmp     short scrollup6
1568
 
1569
scrolldn1:
1570
        ja     short scrolldn2
1571
; TODO  mode13h scroll down
1572
        jmp     short scrollexit
1573
scrolldn2:
1574
; TODO  mode25h scroll down
1575
        jmp     short scrollexit
1576
 
1577
scr_params:
1578
        mov     bl, al          ; lines
1579
        xor     ax, ax
1580
        xchg    al, dh
1581
        imul    di, ax, 80
1582
        add     di, dx
1583
        mov     dl, 80          ; dh = 0
1584
        sub     dl, cl
1585
        mov     al, bl
1586
        imul    si, ax, 160
1587
        ret
1588
;---------------- fn 08h, read char/attr
1589
readchar:
1590
        push    bx
1591
        mov     al, ActiveVideoMode
1592
        cmp     al, 3
1593
        xor     ax, ax
1594
        jne     short readchar1
1595
        call    mode3chaddr
1596
        mov     ax, [bx]
1597
readcharexit:
1598
        pop     bx
1599
        ret
1600
readchar1:
1601
        cmp     al, 13h
1602
        jne     short readchar2
1603
; TODO mode13h
1604
        jmp     short readcharexit
1605
readchar2:
1606
; TODO mode25h
1607
        jmp     short readcharexit
1608
 
1609
mode3chaddr:    ; returns current char address in mode3 in ds:bx. Input: bh=page, ds=40h
1610
        push    ax
1611
        and     bx, 700h
1612
        lea     ax, [bx+0b800h]
1613
        shr     bx, 7
1614
        mov     bx, CursorPos[bx]
1615
        mov     ds, ax
1616
        xor     ax, ax
1617
        xchg    al, bh
1618
        imul    ax, 80
1619
        add     bx, ax
1620
        add     bx, bx
1621
        pop     ax
1622
        ret
1623
 
1624
;---------------- fn 09h, write char/attr
1625
writecharattr:
1626
        push    ax
1627
        push    es
1628
        push    bx
1629
        push    cx
1630
        cmp     byte ptr ActiveVideoMode, 3
1631
        jne     short writecharattr1
1632
        mov     ah, bl
1633
        call    mode3chaddr
1634
        push    ds
1635
        pop     es
1636
        xchg    di, bx
1637
        rep     stosw
1638
        xchg    di, bx
1639
writecharattrexit:
1640
        pop     cx
1641
        pop     bx
1642
        pop     es
1643
        pop     ax
1644
        ret
1645
writecharattr1:
1646
        cmp     byte ptr ActiveVideoMode, 13h
1647
        jne     short writecharattr2
1648
; TODO mode13h
1649
        jmp     short writecharattrexit
1650
writecharattr2:
1651
; TODO mode25h
1652
        jmp     short writecharattrexit
1653
 
1654
;---------------- fn 0ah, write char
1655
writechar:
1656
        jcxz    short writecharskip
1657
        push    bx
1658
        push    cx
1659
        cmp     byte ptr ActiveVideoMode, 3
1660
        jne     short writechar1
1661
        call    mode3chaddr
1662
writechar3:
1663
        mov     [bx], al
1664
        add     bx, 2
1665
        loop    short writechar3
1666
writecharexit:
1667
        pop     cx
1668
        pop     bx
1669
writecharskip:
1670
        ret
1671
writechar1:
1672
        cmp     byte ptr ActiveVideoMode, 13h
1673
        jne     short writechar2
1674
; TODO mode13h
1675
        jmp     short writecharexit
1676
writechar2:
1677
; TODO mode25h
1678
        jmp     short writecharexit
1679
 
1680
;---------------- fn 0eh, write char as TTY
1681
writecharTTY:
1682
        push    ax
1683
        push    bx
1684
        push    dx
1685
        mov     bl, ActivePage
1686
        mov     bh, 0
1687
        add     bx, bx
1688
        mov     dx, CursorPos[bx]
1689
        shl     bx, 7
1690
        mov     ah, 0ah
1691
        call    tty
1692
        mov     ah, 2       ; set cursor pos
1693
        int     10h
1694
        pop     dx
1695
        pop     bx
1696
        pop     ax
1697
        ret
1698
 
1699
tty:    ; dx=xy, bh=page, al=char, bl=attr, ah=0ah(no attr) or 09h(with attr)
1700
        test    word ptr KbdFlags2, Pause
1701
        jnz     short tty
1702
        push    cx
1703
        cmp     al, 7
1704
        je      short bell
1705
        cmp     al, 8
1706
        je      short bs
1707
        cmp     al, 0ah
1708
        je      short cr
1709
        cmp     al, 0dh
1710
        je      short lf
1711
        mov     cx, 1
1712
        int     10h         ; write char at cursor
1713
        inc     dx
1714
        cmp     dl, ScreenWidth
1715
        jae     short crlf
1716
tty1:
1717
        pop     cx
1718
        ret
1719
bell:
1720
; TODO bell code
1721
        jmp     short tty1
1722
bs:
1723
        sub     dl, 1
1724
        adc     dl, 0
1725
        jmp     short tty1
1726
lf:
1727
        mov     dl, 0
1728
        jmp     short tty1
1729
crlf:
1730
        mov     dl, 0
1731
cr:
1732
        inc     dh
1733
        cmp     dh, ScreenRows
1734
        jbe     short tty1
1735
        dec     dh
1736
;        mov     ah, 8
1737
;        int     10h         ; read attribute at cursor pos
1738
        push    bx          ; save active page in bh
1739
        push    dx
1740
;        xchg    ax, bx
1741
        mov     bh, 7       ; default attribute
1742
        mov     ax, 601h
1743
        mov     dh, ScreenRows
1744
        mov     dl, ScreenWidth
1745
        dec     dx
1746
        xor     cx, cx
1747
        int     10h         ; scroll up
1748
        pop     dx
1749
        pop     bx          ; restore active page in bh
1750
        jmp     short tty1
1751
 
1752
;---------------- fn 0fh, read video mode
1753
readmode:
1754
        mov     al, EgaMiscInfo
1755
        and     al, 80h
1756
        or      al, ActiveVideoMode
1757
        mov     ah, ScreenWidth
1758
        mov     bh, ActivePage
1759
        ret
1760
 
1761
 
1762
;---------------- fn 10h, palette
1763
paltable    dw  setonereg, palexit, setallreg, setblink, palexit, palexit, palexit, readonereg, readoverscan, readallreg, palexit, palexit, palexit, palexit, palexit, palexit
1764
            dw  setoneDAC, palexit, setblockDAC, paging, palexit, readoneDAC, palexit, readblockDAC, setPELmask, getPELmask, getpaging, grayscale
1765
 
1766
pal:
1767
        cmp     al, 1bh
1768
        ja      short palexit
1769
        mov     si, ax
1770
        add     si, si
1771
        add     byte ptr PalPagingCounter, ah   ; prevents  re-entrance on recursive  calls
1772
        call    palpage
1773
        call    cs:paltable[si-2000h]
1774
        call    palpage
1775
        sub     byte ptr PalPagingCounter, ah
1776
palexit:
1777
        ret
1778
 
1779
palpage:                    ; executes only if PalPagingCounter == ah
1780
        cmp     byte ptr PalPagingCounter, ah
1781
        jne     short palpageexit
1782
palpageset:
1783
        test    byte ptr PalPaging, 0fh
1784
        jz      short palpageexit
1785
        pusha
1786
        mov     bl, byte ptr PalPaging
1787
        add     bl, bl
1788
        jc      short page16
1789
        shl     bl, 2
1790
page16:
1791
        shl     bx, 11  ; bh=target page, bl=0 page
1792
palpage1:
1793
        mov     al, 15h
1794
        int     10h     ; read 0 page DAC reg
1795
        push    cx
1796
        push    dx
1797
        xchg    bl, bh
1798
        int     10h     ; read target page DAC register
1799
        xchg    bl, bh
1800
        mov     al, 10h
1801
        int     10h     ; write 0 page DAC register
1802
        pop     dx
1803
        pop     cx
1804
        xchg    bl, bh
1805
        int     10h     ; write target page DAC register
1806
        xchg    bl, bh
1807
        add     bx, 101h; next DAC reg
1808
        test    bl, 0fh
1809
        jnz     short palpage1
1810
        popa
1811
palpageexit:
1812
        ret
1813
 
1814
setonereg:
1815
        cmp     bl, 10h
1816
        jae     setonereg1
1817
        pusha
1818
        call    colfrombits
1819
        mov     cl, al
1820
        call    colfrombits
1821
        mov     ch, al
1822
        call    colfrombits
1823
        mov     dh, al
1824
        mov     al, 10h
1825
        int     10h
1826
        popa
1827
setonereg1:
1828
        ret
1829
 
1830
setallreg:
1831
        pusha
1832
        mov     al, 0
1833
        mov     si, dx
1834
        mov     bl, 15
1835
setallreg1:
1836
        mov     bh, es:[si+15]
1837
        int     10h
1838
        dec     si
1839
        dec     bl
1840
        jns     short setallreg1
1841
        popa
1842
        ret
1843
 
1844
setblink:
1845
        pusha
1846
        cmp     byte ptr ActiveVideoMode, 3
1847
        jne     short setblink1
1848
        mov     dx, 3c0h
1849
        mov     al, 10h
1850
        out     dx, al
1851
        mov     al, bl
1852
        and     al, 1
1853
        shl     al, 3
1854
        out     dx, al          ; set video mode (0 or 8)
1855
        shl     al, 2
1856
        xor     al, VgaFlags
1857
        and     al, 20h
1858
        xor     VgaFlags, al
1859
setblink1:
1860
        popa
1861
        ret
1862
 
1863
readonereg:
1864
        cmp     bl, 10h
1865
        jae     readonereg1
1866
        push    ax
1867
        push    cx
1868
        push    dx
1869
        mov     al, 15h
1870
        int     10h
1871
        mov     al, dh          ; al = R
1872
        and     al, 00110000b
1873
        shr     al, 2
1874
        add     al, 01111000b
1875
        and     al, 10000100b
1876
        mov     bh, al
1877
        xchg    ax, cx          ; ax = GB
1878
        and     ax, 0011000000110000b
1879
        shr     ax, 3
1880
        shr     al, 1
1881
        add     ax, 0011110000011110b
1882
        and     ax, 0100001000100001b
1883
        or      bh, ah
1884
        or      bh, al
1885
        rol     bh, 3
1886
        pop     dx
1887
        pop     cx
1888
        pop     ax
1889
readonereg1:
1890
        ret
1891
 
1892
readallreg:
1893
        pusha
1894
        mov     di, dx
1895
        mov     bl, 0
1896
readllreg1:
1897
        mov     al, 7
1898
        int     10h
1899
        mov     al, bh
1900
        stosb
1901
        inc     bx
1902
        cmp     bl, 16
1903
        jne     short readllreg1
1904
        mov     al, 0   ; overscan color
1905
        stosb
1906
        popa
1907
        ret
1908
 
1909
readoverscan:
1910
        mov     bh, 0
1911
        ret
1912
 
1913
setoneDAC:
1914
        push    ax
1915
        push    dx
1916
        xchg    ax, dx
1917
        mov     al, bl
1918
        mov     dx, 3c8h
1919
        out     dx, al
1920
        inc     dx
1921
        mov     al, ah
1922
        out     dx, al
1923
        mov     al, ch
1924
        out     dx, al
1925
        mov     al, cl
1926
        out     dx, al
1927
        pop     dx
1928
        pop     ax
1929
        ret
1930
 
1931
setblockDAC:
1932
        pusha
1933
        mov     si, dx
1934
        mov     dx, 3c8h
1935
        xchg    ax, bx
1936
        out     dx, al
1937
        inc     dx
1938
        imul    cx, 3
1939
        rep     outsb dx, es:[si]
1940
        popa
1941
        ret
1942
 
1943
paging:
1944
        push    bx
1945
        test    bl, bl
1946
        mov     bl, PalPaging
1947
        jnz     short paging1
1948
        add     bl, bl
1949
        ror     bx, 1
1950
        jmp     short paging2
1951
paging1:
1952
        and     bx, 0f80h       ; bl=old page, bh=new page
1953
        or      bl, bh
1954
paging2:
1955
        mov     PalPaging, bl
1956
        pop     bx
1957
        ret
1958
 
1959
readoneDAC:
1960
        push    ax
1961
        push    dx
1962
        mov     al, bl
1963
        mov     dx, 3c7h
1964
        out     dx, al
1965
        inc     dx
1966
        inc     dx
1967
        in      al, dx
1968
        mov     ah, al
1969
        in      al, dx
1970
        mov     ch, al
1971
        in      al, dx
1972
        mov     cl, al
1973
        pop     dx
1974
        mov     dh, ah
1975
        pop     ax
1976
        ret
1977
 
1978
readblockDAC:
1979
        pusha
1980
        mov     di, dx
1981
        mov     dx, 3c7h
1982
        xchg    ax, bx
1983
        out     dx, al
1984
        inc     dx
1985
        inc     dx
1986
        imul    cx, 3
1987
        rep     insb
1988
        popa
1989
        ret
1990
 
1991
setPELmask:
1992
        push    dx
1993
        xchg    ax, bx
1994
        mov     dx, 3c6h
1995
        out     dx, al
1996
        xchg    ax, bx
1997
        pop     dx
1998
        ret
1999
 
2000
getPELmask:
2001
        push    dx
2002
        xchg    ax, bx
2003
        mov     dx, 3c6h
2004
        in      al, dx
2005
        xchg    ax, bx
2006
        pop     dx
2007
        ret
2008
 
2009
getpaging:
2010
        mov     bh, PalPaging
2011
        mov     bl, 0
2012
        rol     bx, 1
2013
        shr     bh, 1
2014
        ret
2015
 
2016
grayscale:
2017
        jcxz    short grayscale2
2018
        pusha
2019
        mov     bh, cl
2020
grayscale1:
2021
        mov     al, 15h
2022
        int     10h
2023
        shr     dx, 8
2024
        imul    si, dx, 77
2025
        mov     dl, ch
2026
        imul    dx, 151
2027
        mov     ch, 0
2028
        imul    cx, 28
2029
        add     dx, si
2030
        add     dx, cx
2031
        mov     ch, dh
2032
        mov     cl, dh
2033
        mov     al, 10h
2034
        int     10h
2035
        inc     bl
2036
        dec     bh
2037
        jne     short grayscale1
2038
        popa
2039
grayscale2:
2040
        ret
2041
 
2042
colfrombits:    ; input: bh, output: al
2043
        shr     bh, 1
2044
        sbb     al, al
2045
        and     al, 2ah
2046
        test    bh, 4
2047
        jz      short col1
2048
        or      al, 15h
2049
col1:
2050
        ret
2051
 
2052
 
2053
;---------------- fn 11h, character generator
2054
loadUDF:
2055
        cmp     bx, 1000h
2056
        jne     loadUDFexit     ; only 16bytes chars and font block 0 supported
2057
        pusha
2058
        xchg    ax, dx
2059
        mov     dx, 03cbh
2060
        out     dx, ax
2061
        mov     si, bp
2062
        shl     cx, 4
2063
        rep     outsb dx, es:[si]
2064
        popa
2065
loadUDFexit:
2066
        ret
2067
 
2068
chargen:
2069
        test    al, not 10h     ; test for 00h and 10h
2070
        jz      short loadUDF
2071
        test    al, not 11h     ; test for 01h and 11h
2072
        jz      short loadROMfont
2073
        test    al, not 12h     ; test for 02h and 12h
2074
        jz      short loadROMfont
2075
        test    al, not 14h     ; test for 04h and 14h
2076
        jz      short loadROMfont
2077
        cmp     al, 20h
2078
        jb      loadUDFexit
2079
        je      short set1f
2080
        cmp     al, 21h
2081
        je      short setgrUDF
2082
        cmp     al, 24h
2083
        jbe     short setROMgrFont
2084
        cmp     al, 30h
2085
        je      short getfontinfo
2086
        ret
2087
 
2088
loadROMFont:
2089
        push    es
2090
        pusha
2091
        mov     bx, 1000h       ; 8x16 chars, block 0
2092
        mov     cx, 100h        ; all chars
2093
        xor     dx, dx
2094
        mov     bp, offset font8x16
2095
        push    cs
2096
        pop     es
2097
        mov     al, 0
2098
;        int     10h             ; loadUDF
2099
        popa
2100
        pop     es
2101
        ret
2102
 
2103
set1f:
2104
        xor     si, si
2105
        mov     ds, si
2106
        mov     [si+1fh*4], bp
2107
        mov     [si+1fh*4+2], es
2108
        ret
2109
 
2110
setgrUDF:
2111
        pusha
2112
        jcxz    short loadUDFexit
2113
        push    ds
2114
        xor     si, si
2115
        mov     ds, si
2116
        mov     [si+43h*4], bp
2117
        mov     [si+43h*4+2], es
2118
        pop     ds
2119
        mov     ax, 200
2120
        cmp     byte ptr ActiveVideoMode, 13h
2121
        jb      short setgrUDFexit
2122
        je      short setgrUDF1
2123
        mov     ax, 480         ; mode 25h, 480 lines
2124
setgrUDF1:
2125
        mov     ScanLinesChar, cx
2126
        cwd
2127
        div     cx
2128
        dec     ax
2129
        mov     ScreenRows, al
2130
setgrUDFexit:
2131
        popa
2132
        ret
2133
 
2134
setROMgrFont:
2135
        pusha
2136
        push    es
2137
        mov     cx, 8
2138
        push    cs
2139
        pop     es
2140
        mov     bp, offset font8x8
2141
        cmp     al, 23h
2142
        je      short setROMgrFont1
2143
        mov     bp, offset font8x16
2144
setROMgrFont1:
2145
        mov     al, 21h
2146
        int     10h     ; set graphic UDF
2147
        dec     ax
2148
        mov     bp, offset font8x8 + 128*8
2149
        int     10h     ; set INT 1fh
2150
        pop     es
2151
        popa
2152
        ret
2153
 
2154
getfontinfo:
2155
        mov     cx, ScanLinesChar
2156
        mov     dl, ScreenRows
2157
        cmp     bh, 1
2158
        ja      short getfontinfo1
2159
        push    0
2160
        pop     ds
2161
        les     bp, ds:[1fh*4]
2162
        jb      short getfontinfoexit
2163
        les     bp, ds:[43h*4]
2164
        ret
2165
getfontinfo1:
2166
        cmp     bh, 7
2167
        ja      short getfontinfoexit
2168
        mov     si, bx
2169
        shr     si, 8
2170
        add     si, si
2171
        mov     bp, cs:fontinfo[si-4]
2172
        push    cs
2173
        pop     es
2174
getfontinfoexit:
2175
        ret
2176
 
2177
fontinfo    dw  font8x16, font8x8, font8x8+128*8, font8x16, font8x16, font8x16
2178
 
2179
;---------------- fn 12h, special functions
2180
special:
2181
        cmp     bl, 10h
2182
        jne     short special1
2183
        mov     cl, EgaMiscInfo2    ; cl = switch settings
2184
        and     cx, 15              ; ch <- 0 (feature bits)
2185
        mov     bx, 3               ; bh <- 0 (color mode), bl = video memory size
2186
        ret
2187
special1:
2188
        cmp     bl, 31h
2189
        jne     short special2
2190
        neg     al
2191
        xor     al, VgaFlags
2192
        and     al, 8       ; transfer palette loading bit to VgaFlags
2193
        xor     VgaFlags, al
2194
        mov     al, 12h     ; supported function
2195
        ret
2196
special2:
2197
        mov     al, 0       ; unsupported function
2198
        ret
2199
 
2200
 
2201
;---------------- fn 13h, write string
2202
writestr:
2203
        jcxz    short wstrexit
2204
        pusha
2205
        mov     si, bx
2206
        shr     si, 8
2207
        add     si, si
2208
        push    CursorPos[si]
2209
        mov     ah, 9       ; write tty char/attribute
2210
wstr1:
2211
        push    ax
2212
        test    al, 2
2213
        mov     al, es:[bp]
2214
        jz      short noattr
2215
        inc     bp
2216
        mov     bl, es:[bp]
2217
noattr:
2218
        inc     bp
2219
        mov     CursorPos[si], dx
2220
        call    tty
2221
        pop     ax
2222
        loop    short wstr1
2223
        pop     CursorPos[si]
2224
        test    al, 1
2225
        jz      short wstr2
2226
        mov     ah, 2       ; set cursor pos
2227
        int     10h
2228
wstr2:
2229
        popa
2230
wstrexit:
2231
        ret
2232
 
2233
;---------------- fn 1ah, get/set display combination code
2234
getdcc:
2235
        cmp     al, 1
2236
        ja      short getdccexit
2237
        mov     al, ah
2238
        je      short setdcc
2239
        mov     bx, 08h
2240
dccval  label word
2241
setdcc:
2242
        mov     cs:[dccval-2], bx
2243
getdccexit:
2244
        ret
2245
 
2246
;---------------- fn 1bh, query status
2247
querystatus:
2248
        pusha
2249
        mov     ax, offset staticfunctable
2250
        stosw
2251
        mov     ax, cs
2252
        stosw
2253
        mov     si, offset ActiveVideoMode
2254
        cmp     byte ptr [si], 13h
2255
        mov     cx, 33          ; info copied from BDA
2256
        rep     movsb
2257
        mov     ax, 8
2258
        stosw                   ; display info (one VGA analog color monitor)
2259
        mov     bx, 208h        ; 400 scan lines, 8 pages
2260
        mov     al, 10h         ; 16 colors
2261
        jb      short querystatus1     ; mode03h
2262
        mov     bh, 0           ; scan lines code (0=200, 1=350, 2=400, 3=480), 8 pages
2263
        mov     ax, 100h        ; 256 colors
2264
        je      short querystatus1     ; mode13h
2265
        mov     bx, 301h        ; 480 scan lines, 1 page
2266
querystatus1:
2267
        stosw
2268
        xchg    ax, bx
2269
        stosw
2270
        xor     ax, ax
2271
        stosw                   ; font block info (45)
2272
        mov     al, VgaFlags
2273
        and     al, 00101111b
2274
        stosw
2275
        stosw
2276
        mov     al, EgaMiscInfo
2277
        shr     al, 4
2278
        and     al, 7           ; video memory size
2279
        stosw
2280
        mov     al, 2
2281
        stosb                   ; color display attached
2282
        mov     cl, 6
2283
        xor     ax, ax
2284
        rep     stosw           ; 12 reserved bytes
2285
        popa
2286
        mov     al, ah          ; supported function
2287
        ret
2288
 
2289
staticfunctable db  00001100b   ; video mode 2h, 3h supported
2290
                db  00000000b
2291
                db  00001000b   ; video mode 13h supported
2292
                db  00000000b
2293
                db  00100000b   ; video mode 25h supported
2294
                db  0, 0
2295
                db  00000100b   ; 400 scanline supported
2296
                db  1           ; font blocks available in text mode
2297
                db  1           ; max active font blocks available in text mode
2298
 
2299
;Bit(s)  Description
2300
;0      all modes on all displays function supported
2301
;1      gray summing function supported
2302
;2      character font loading function supported
2303
;3      default palette loading enable/disable supported
2304
;4      cursor emulation function supported
2305
;5      EGA palette present
2306
;6      color palette present
2307
;7      color-register paging function supported
2308
;8      light pen supported (see AH=04h)
2309
;9      save/restore state function 1Ch supported
2310
;10     intensity/blinking function supported (see AX=1003h)
2311
;11     Display Combination Code supported (see #00039)
2312
;12-15  unused (0)
2313
                db  11101111b   ; miscellaneous function support flags
2314
                db  00001100b   ; miscellaneous function support flags
2315
 
2316
                db  0, 0        ; reserved
2317
                db  0           ; save pointer function flags
2318
                db  0           ; reserved
2319
 
2320
 
2321
vidtbl  dw  setmode, cursor, curpos, getcurpos, lightpen, apage, scrollup, scrolldn, readchar, writecharattr
2322
        dw  writechar, nullproc, nullproc, nullproc, writecharTTY, readmode
2323
        dw  pal, chargen, special, writestr, nullproc, nullproc, nullproc, nullproc, nullproc, nullproc, getdcc, querystatus, nullproc
2324
int10 endp
2325
 
2326
; --------------------- INT 11h - Equipment ----------------
2327
EquipmentWord       equ     
2328
 
2329
int11   proc near
2330
        push    ds
2331
        push    40h
2332
        pop     ds
2333
        mov     ax, EquipmentWord
2334
        pop     ds
2335
        iret
2336
int11   endp
2337
 
2338
; --------------------- INT 12h - Memory size ----------------
2339
MemorySize       equ     
2340
 
2341
int12   proc near
2342
        push    ds
2343
        push    40h
2344
        pop     ds
2345
        mov     ax, MemorySize
2346
        pop     ds
2347
        iret
2348
int12   endp
2349
 
2350
; --------------------- INT 13h - Disk services ----------------
2351
HDLastError       equ     
2352
HDOpStarted       equ         ; bit 3: in INT13h (all other bits must be 0)
2353
HDSize            equ     
2354
 
2355
int13   proc near
2356
        push    ds
2357
        push    bp
2358
        push    40h
2359
        pop     ds
2360
        xor     byte ptr HDOpStarted, 8
2361
        jz      short inINT13
2362
        sti
2363
        cld
2364
        cmp     ah, 1ah
2365
        jbe     short Disk1
2366
        sub     ah, 41h-1bh     ; extensions
2367
        cmp     ah, 22h
2368
        jbe     short Disk1
2369
        mov     ah, 1           ; bad command error
2370
        jmp     short exit
2371
inINT13:
2372
        mov     ah, 0aah        ; drive not ready
2373
        jmp     short exit2
2374
Disk1:
2375
        mov     bp, ax
2376
        shr     bp, 7
2377
        and     bp, 1feh
2378
        push    ds
2379
        call    cs:disktbl[bp]
2380
        pop     ds
2381
exit:
2382
        mov     HDLastError, ah
2383
exit2:
2384
        xor     byte ptr HDOpStarted, 8
2385
        neg     ah              ; CF <- (AH != 0)
2386
exit1:
2387
        mov     bp, sp
2388
        rcr     byte ptr [bp+8], 1
2389
        rol     byte ptr [bp+8], 1  ; insert error CF on stack
2390
        neg     ah
2391
        pop     bp
2392
        pop     ds
2393
        iret
2394
 
2395
disktbl dw      DiskReset, DiskGetStatus, DiskRead, DiskWrite, DiskVerify, DiskFormat, DiskFormat, DiskFormat, DiskGetParams, DiskInit, DiskRead, DiskWrite, DiskSeek, DiskRst, DiskReadSectBuffer, DiskWriteSectBuffer
2396
        dw      DiskReady, DiskRecalibrate, DiskDiag, DiskDiag, DiskDiag, DiskGetType, DiskChanged, DiskSetDASDType, DiskSetMediaType, DiskPark, DiskFormat,  DiskExtInstCheck, DiskExtRead, DiskExtWrite, DiskExtVerify, DiskExtLock
2397
        dw      DiskExtEject, DiskExtSeek, DiskExtGetParams
2398
 
2399
DiskGetType:
2400
        cmp     dl, 80h
2401
        jne     short DiskReset ; ah=0, drive not present
2402
        mov     cx, HDSize
2403
        mov     dx, cx
2404
        test    cx, cx
2405
        jz      short DiskReset ; ah=0, drive not present
2406
        mov     ah, -3      ; HD present
2407
        shr     cx, 6
2408
        shl     dx, 10      ; CX:DX = HDSize * 1024
2409
DiskGetTypeexit:
2410
        pop     ds          ; discard ret address
2411
        pop     ds          ; discard DS
2412 7 ndumitrach
        xor     byte ptr HDOpStarted, 8     ; CF <- 0
2413 3 ndumitrach
        jmp     short   exit1
2414
 
2415
DiskExtInstCheck:
2416
        xchg    bl, bh
2417
        mov     ah, -1
2418
        mov     cx, 1       ; extended disk access functions (AH=42h-44h,47h,48h) supported
2419
        cmp     dl, 80h
2420
        jne     short notready
2421
        jmp     short DiskGetTypeexit
2422
 
2423
DiskReset:
2424
DiskChanged:
2425
DiskPark:
2426
        mov     ah, 0       ; success
2427
        ret
2428
 
2429
DiskGetStatus:
2430
        mov     ah, HDLastError
2431
        ret
2432
 
2433
DiskVerify:
2434
        mov     bp, sdverify
2435
        jmp     short   DiskRead1
2436
DiskWrite:
2437
        mov     bp, sdwrite
2438
        jmp     short   DiskRead1
2439
DiskRead:
2440
        mov     bp, sdread
2441
DiskRead1:
2442
        test    al, al
2443
        jz      short DiskReset
2444
        cmp     dl, 80h
2445
        jne     short notready
2446
        mov     ah, 4
2447
        test    cl, 3fh
2448
        jz      short DiskReadend   ; bad sector 0
2449
        pusha
2450
        mov     ah, 0
2451
        push    ax
2452
        call    HCStoLBA
2453
        pop     cx
2454
        push    cx
2455
        call    bp              ; DX:AX sector, ES:BX buffer, CX=sectors, returns AX=read sectors
2456
        pop     cx
2457
        sub     cx, ax
2458
        neg     cx              ; CF=1 if cx != 0
2459
        rcl     ah, 3           ; AH = 4*CF (sector not found / read error)
2460
        mov     ds, ax
2461
        popa
2462
        mov     ax, ds
2463
DiskReadend:
2464
        ret
2465
 
2466
HCStoLBA:       ; CX = {cyl[7:0], cyl[9:8], sect[5:0]}, DH = head. Returns DX:AX LBA
2467
        mov     al, ch
2468
        mov     ah, cl
2469
        shr     ah, 6
2470
        shr     dx, 8
2471
        imul    dx, 63
2472
        and     cx, 3fh
2473
        add     cx, dx
2474
        dec     cx
2475
        mov     dx, 255*63
2476
        mul     dx
2477
        add     ax, cx
2478
        adc     dx, 0
2479
        ret
2480
;    unsigned int s = cs & 0x3f;
2481
;    unsigned int c = ((cs & 0xc0) << 2) | (cs >> 8);
2482
;    return (c*255l + h)*63l + s - 1l;
2483
 
2484
DiskFormat:
2485
DiskInit:
2486
DiskSeek:
2487
DiskRst:
2488
DiskReady:
2489
DiskRecalibrate:
2490
DiskDiag:
2491
DiskExtSeek:
2492
        cmp     word ptr HDSize, 0
2493
        je      short notready
2494
        cmp     dl, 80h
2495
        je      short DiskReset
2496
notready:
2497
        mov     ah, 0aah        ; disk not ready
2498
        ret
2499
 
2500
DiskGetParams:
2501
        cmp     dl, 80h
2502
        mov     ah, 7
2503
        jne     short DiskReadend   ; ret
2504
        mov     bl, 0   ; ???
2505
        mov     ax, HDSize
2506
        mov     dx, ax
2507
        shl     ax, 10
2508
        shr     dx, 6
2509
        sub     ax, 30
2510
        sbb     dx, 0
2511
        mov     cx, 63*255
2512
        div     cx
2513
        dec     ax
2514
        cmp     ax, 3feh
2515
        jbe     dgpok
2516
        mov     ax, 3feh
2517
dgpok:
2518
        xchg    al, ah
2519
        shl     al, 6
2520
        or      al, 3fh
2521
        mov     cx, ax
2522
        mov     dx, 0fe01h
2523
        xor     ax, ax
2524
        ret
2525
 
2526
DiskExtVerify:
2527
        mov     bp, sdverify
2528
        jmp     short DiskExtRead1
2529
DiskExtWrite:
2530
        mov     bp, sdwrite
2531
        jmp     short DiskExtRead1
2532
DiskExtRead:
2533
        mov     bp, sdread
2534
DiskExtRead1:
2535
        cmp     dl, 80h
2536
        jne     short notready
2537
        push    es
2538
        push    ax
2539
        pusha
2540
        mov     bx, sp
2541
        mov     ds, ss:[bx+26]
2542
        mov     cx, [si+2]
2543
        les     bx, [si+4]
2544
        mov     ax, [si+8]
2545
        mov     dx, [si+10]
2546
        push    ds
2547
        push    si
2548
        call    bp
2549
        pop     si
2550
        pop     ds
2551
        sub     ax, [si+2]
2552
        add     [si+2], ax
2553
        popa
2554
        pop     ax
2555
        sbb     ah, ah
2556
        and     ah, 4
2557
        pop     es
2558
        ret
2559
 
2560
DiskExtGetParams:
2561
        cmp     dl, 80h
2562
        jne     short notready
2563
        push    ax
2564
        mov     ax, HDSize
2565
        mov     bp, sp
2566
        mov     ds, [bp+8]
2567
        xor     bp, bp
2568
        mov     word ptr [si], 1ah      ; size
2569
        mov     word ptr [si+2], 0bh    ; flags
2570
        mov     word ptr [si+4], 1023   ; cylinders
2571
        mov     word ptr [si+6], bp
2572
        mov     word ptr [si+8], 255    ; heads
2573
        mov     word ptr [si+10], bp
2574
        mov     word ptr [si+12], 63     ; sectors/track
2575
        mov     word ptr [si+14], bp
2576
        mov     word ptr [si+16], ax
2577
        shl     word ptr [si+16], 10
2578
        shr     ax, 6
2579
        mov     word ptr [si+18], ax
2580
        mov     word ptr [si+20], bp
2581
        mov     word ptr [si+22], bp
2582
        mov     word ptr [si+24], 512   ; bytes/sector
2583
        pop     ax
2584
        mov     ah, 0
2585
        ret
2586
 
2587
DiskReadSectBuffer:
2588
DiskWriteSectBuffer:
2589
DiskSetDASDType:
2590
DiskSetMediaType:
2591
DiskExtLock:
2592
DiskExtEject:
2593
        mov     ah, 1       ; unsupported fn
2594
        ret
2595
 
2596
int13   endp
2597
 
2598
 
2599
; --------------------- INT 15h - Extended services ----------------
2600
UFPtr           equ     
2601
WaitCount       equ     
2602
UWaitFlag       equ     
2603
HandlerPtr      equ      ; 4 bytes
2604
DataBuffer      equ      ; 3 bytes
2605
DataCounter     equ      ; 1 byte
2606
PacketSize      equ      ; 1 byte, 0->3bytes, 1->4bytes
2607
FreeXMSKb       equ     (1024 - 16 - 6)*64
2608
 
2609
; ------------ MovExt
2610
IncSeg: ; DX = segment port address
2611
        jnz     short SetSegExit
2612
        in      ax, dx
2613
        and     ax, 3ffh
2614
        inc     ax
2615
        cmp     ax, 12h
2616
        jne     short IncSeg1
2617
        xor     ax, ax
2618
IncSeg1:
2619
        cmp     ax, 0ch
2620
        jne     short SetSeg2
2621
SetSeg: ; DX = segment port address, ax = logical segment (0..1023)
2622
        and     ax, 3ffh
2623
        cmp     ax, 0ch
2624
        jb      short SetSeg1
2625
        add     ax, 6
2626
SetSeg2:
2627
        cmp     ax, 400h
2628
        jb      short SetSeg1
2629
        sub     ax, 400h - 0ch
2630
SetSeg1:
2631
        out     dx, ax
2632
SetSegExit:
2633
        ret
2634
 
2635
MovSeg  equ     01h
2636
savess  dw      0
2637
savesp  dw      MovExt, 0 ; tmp stack
2638
; 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,...
2639
MovExt:
2640
        push    es
2641
        push    ds
2642
        pusha
2643
        cli
2644
        mov     cs:savess, ss
2645
        push    cs
2646
        pop     ss
2647
        xchg    sp, cs:savesp
2648
        mov     dx, 80h + MovSeg + 1
2649
        jcxz    short MovExt_exit
2650
        push    es
2651
        pop     ds
2652
        cld
2653
        mov     al, [si+1ch]
2654
        mov     ah, [si+1fh]
2655
        mov     bl, [si+14h]
2656
        mov     bh, [si+17h]
2657
        mov     di, [si+1ah]
2658
        mov     si, [si+12h]
2659
        call    flush
2660
        call    SetSeg      ; 02000h = destination, DX=82h
2661
        dec     dx
2662
        xchg    ax, bx
2663
        call    SetSeg      ; 01000h = source, DX=81h
2664
        push    MovSeg shl 12
2665
        pop     ds
2666
        push    (MovSeg + 1) shl 12
2667
        pop     es
2668
        xor     bx, bx
2669
        add     cx, cx
2670
        adc     bx, bx      ; BX:CX = bytes to transfer
2671
; move from 01000h:si to 02000h:di, 2*cx bytes
2672
MovExtLoop:
2673
        inc     dx          ; 82h
2674
        mov     ax, si
2675
        cmp     ax, di
2676
        ja      short MovExt1
2677
        mov     ax, di
2678
MovExt1:
2679
        neg     ax
2680
        adc     bx, -1
2681
        sub     cx, ax
2682
        sbb     bx, 0
2683
        xchg    ax, cx      ; cx = bytes to move, bx:ax = bytes left for the next transfer
2684
        jns     short MovExt2   ; ax <= bx:cx
2685
        add     cx, ax
2686
        xor     ax, ax
2687
        inc     bx
2688
MovExt2:
2689
        movsb               ; if CX = 0 transfer 10000h bytes
2690
        dec     cx
2691
        jz      short MovExt_next
2692
        test    si, 1       ; read align
2693
        jz      short raligned
2694
        movsb
2695
        dec     cx
2696
raligned:
2697
        shr     cx, 1
2698
        rep     movsw
2699
        jnc     short MovExt_next
2700
        movsb
2701
MovExt_next:
2702
        call    flush
2703
        mov     cx, ax
2704
        or      ax, bx
2705
        jz      short MovExt_exit  ; finalized
2706
        test    di, di
2707
        call    incseg      ; does nothing if ZF == 0, dx = 8bh
2708
        dec     dx          ; 81h
2709
        test    si, si
2710
        call    incseg      ; dx = 81h
2711
        jmp     short MovExtLoop
2712
MovExt_exit:
2713
        mov     ax, MovSeg + 1
2714
        out     dx, ax      ; 82h
2715
        dec     ax
2716
        dec     dx
2717
        out     dx, ax      ; 81h
2718
        mov     ss, cs:savess
2719
        xchg    sp, cs:savesp
2720
        popa
2721
        pop     ds
2722
        pop     es
2723
        xor     ah, ah
2724
        jmp     short exit_ax
2725
MovExtProxy:
2726
        jmp     MovExt
2727
 
2728
int15:
2729
        cmp     ah, 4fh
2730
        je      short exit_iret
2731
        xchg    al, ah
2732
        cmp     al, 80h
2733
        jb      short exit15; CF=1  for <80h
2734
        cmp     al, 83h
2735
        jb      short done  ; no error for 80, 81, 82
2736
        je      short SetEventWait; 83
2737
        cmp     al, 86h
2738
        jb      short exit15; CF=1 for 84, 85
2739
        je      short Wait1 ; 86
2740
        cmp     al, 88h
2741
        jb      short MovExtProxy ; 87
2742
        je      short ExtSize     ; 88
2743
        cmp     al, 90h
2744
        jb      short  exit15; CF=1 for 89..8f
2745
        cmp     al, 92h
2746
        jb      short done  ; no error for 90, 91
2747
        cmp     al, 0c0h
2748
        jb      short exit15; CF=1 for 92..bf
2749
        je      short GetConfig   ; c0
2750
        cmp     al, 0c2h
2751
        jb      short exit15; CF=1 for c1
2752
        je      short Mouse ; c2
2753
done:
2754
        cmc                 ; CF=1 for >c2
2755
exit15:
2756
        mov     ax, 8600h
2757
exit_ax:
2758
        sti
2759
        retf    2           ; discard flags (need to keep CF)
2760
exit_iret:
2761
        iret
2762
 
2763
; ------------ SetEventWait
2764
SetEventWait:
2765
        push    ds
2766
        push    40h
2767
        pop     ds
2768
        xor     ah, 1
2769
        jz      short cancel
2770
        test    ah, byte ptr UWaitFlag ; ah=1
2771
        jnz     short busy  ; CF=0
2772
        mov     ax, 1000-1  ; 1ms
2773
        out     70h, ax     ; restart RTC timer
2774
        mov     UFPtr[0], bx
2775
        mov     UFPtr[2], es
2776
        add     ax, dx
2777
        adc     cx, 0
2778
        mov     WaitCount[0], ax
2779
        mov     WaitCount[2], cx
2780
        mov     ah, 1       ; wait in progress
2781
cancel:
2782
        mov     byte ptr UWaitFlag, ah
2783
        int     70h
2784
        stc                 ; no error
2785
busy:
2786
        cmc                 ; eror
2787
nowait:
2788
        pop     ds
2789
        jmp     short exit15
2790
 
2791
; ------------ Wait
2792
Wait1:
2793
        push    es
2794
        push    bx
2795
        mov     ax, 8300h
2796
        push    4ah
2797
        pop     es
2798
        xor     bx, bx      ; user wait flag address=0040:00a0
2799
        int     15h         ; returns with IF = 1
2800
        jc      short wbusy
2801
wloop:
2802
        hlt
2803
        test    byte ptr es:[bx], 80h
2804
        jz      short wloop
2805
wbusy:
2806
        pop     bx
2807
        pop     es
2808
        jmp     short exit15
2809
 
2810
 
2811
; ------------ ExtSize
2812
ExtSize:
2813
        mov     ax, FreeXMSKb
2814
        jmp     short exit_ax
2815
 
2816
; ------------ GetConfig
2817
GetConfig:
2818
        xor     ax, ax
2819
        push    cs
2820
        pop     es
2821
        mov     bx, offset SysParams
2822
        jmp     short exit_ax
2823
 
2824
; ------------ Mouse
2825
Mouse:
2826
        push    ds
2827
        push    dx
2828
        push    40h
2829
        pop     ds
2830
        test    byte ptr EquipmentWord, 4 ; ps2 mouse equipement word
2831
        jnz     short mouse_present
2832
if_err:
2833
        mov     ax, 03a7h   ; interface error (no mouse present)
2834
        out     64h, al     ; disable mouse
2835
errexit:
2836
        stc                 ; error
2837
exitok:
2838
        pushf               ; save CF
2839
        in      al, 21h
2840
        and     al, not 10h
2841
        out     21h, al     ; enable mouse interrupts
2842
        call    enableKbIfPresent
2843
        popf
2844
        pop     dx
2845
        pop     ds
2846
        jmp     exit_ax
2847
mouse_present:
2848
        mov     al, ah
2849
        mov     ah, 1       ; invalid function
2850
        cmp     al, 7
2851
        ja      short errexit
2852
        push    ax
2853
        in      al, 21h
2854
        or      al, 10h
2855
        out     21h, al     ; disable mouse interrupts
2856
        sti                 ; allow interrupts for a short time, to flush possible pending KB/mouse requests
2857
        mov     al, 0adh
2858
        out     64h, al     ; disable kb interface
2859
        pop     ax
2860
        cmp     al, 1
2861
        cli                 ; from now on we are working with ints disabled, as the following code is highly non re-entrant
2862
        jb      short en_dis
2863
        je      short reset
2864
        cmp     al, 3
2865
        jb      short sampling
2866
        je      short resolution
2867
        cmp     al, 5
2868
        jb      short gettype
2869
        je      short reset
2870
        cmp     al, 6
2871
        je      short extend
2872
 
2873
; ------------- set handler
2874
        mov     HandlerPtr[0], bx
2875
        mov     HandlerPtr[2], es
2876
        jmp     short exit_success1
2877
 
2878
; ------------- enable/disable
2879
en_dis:
2880
        mov     ax, 02f5h   ; ah = invalid input
2881
        sub     al, bh
2882
        cmp     bh, ah
2883
        jnc     short errexit
2884
        mov     ah, al
2885
        call    sendcmd     ; enable/disable data reporting (CF = 1)
2886
if_err1:
2887
        jc      short if_err
2888
exit_success:
2889
        mov     byte ptr DataCounter, 0
2890
exit_success1:
2891
        xor     ah, ah      ; success
2892
        jmp     short exitok
2893
 
2894
; ------------- reset
2895
reset:
2896
        mov     ah, 0f6h    ; set defaults
2897
        stc                 ; mouse command
2898
        call    sendcmd
2899
        jc      short if_err
2900
        mov     bx, 00aah
2901
        mov     byte ptr PacketSize, bh ; 3bytes packet
2902
        jmp     short exit_success
2903
 
2904
; ------------- sampling
2905
sampling:
2906
        cmp     bh, 6
2907
badparam:
2908
        mov     ah, 2       ; invalid input
2909
        ja      short errexit
2910
        shr     bx, 8
2911
        mov     ah, cs:sample_tbl[bx]
2912
        push    ax
2913
        mov     ah, 0f3h    ; st sample rate
2914
send2c:
2915
        stc
2916
        call    sendcmd
2917
        pop     ax
2918
        jc      short if_err1
2919
send1c:
2920
        stc
2921
        call    sendcmd
2922
        jmp     short if_err1
2923
 
2924
; ------------- resolution
2925
resolution:
2926
        cmp     bh, 3
2927
        ja      short badparam
2928
        push    bx
2929
        mov     ah, 0e8h    ; set resolution
2930
        jmp     short send2c
2931
 
2932
; ------------- gettype
2933
gettype:
2934
        mov     ah, 0f2h
2935
        stc
2936
        call    sendcmd
2937
        jc      short if_err1
2938
        call    getps2byte
2939
        jc      short if_err1
2940
        mov     bh, al
2941
        neg     al          ; CF=1 if al != 0
2942
        adc     al, bh
2943
        mov     byte ptr PacketSize, al ; 3 or 4 bytes packet
2944
        jmp     short exit_success
2945
 
2946
; ------------- extended commands
2947
extend:
2948
        test    bh, bh
2949
        jnz     short setscaling
2950
        mov     ah, 0e9h    ; status request
2951
        stc
2952
        call    sendcmd
2953
        jc      short if_err1
2954
        call    getps2byte
2955
        jc      short if_err1
2956
        mov     bl, al
2957
        call    getps2byte
2958
        jc      short if_err1
2959
        mov     cl, al
2960
        call    getps2byte
2961
        jc      short if_err1
2962
        pop     dx
2963
        push    ax          ; replace dx on stack
2964
        jmp     short exit_success
2965
setscaling:
2966
        cmp     bh, 2
2967
        ja      short badparam
2968
        mov     ah, 0e5h    ; set scaling 1:1 or 2:1
2969
        add     ah, bh
2970
        jmp     short send1c
2971
 
2972
sample_tbl  db  10, 20, 40, 60, 80, 100, 200
2973
SysParams   db  8, 0, 0fch, 0, 0
2974
;--------------------------------------------------------------------------
2975
; Feature byte 1
2976
; b7: 1=DMA channel 3 used by hard disk
2977
; b6: 1=2 interrupt controllers present
2978
; b5: 1=RTC present
2979
; b4: 1=BIOS calls int 15h/4Fh every key
2980
; b3: 1=wait for extern event supported (Int 15h/41h)
2981
; b2: 1=extended BIOS data area used
2982
; b1: 0=AT or ESDI bus, 1=MicroChannel
2983
; b0: 1=Dual bus (MicroChannel + ISA)
2984
;--------------------------------------------------------------------------
2985
            db      10h
2986
;--------------------------------------------------------------------------
2987
; Feature byte 2
2988
; b7: 1=32-bit DMA supported
2989
; b6: 1=int16h, function 9 supported
2990
; b5: 1=int15h/C6h (get POS data) supported
2991
; b4: 1=int15h/C7h (get mem map info) supported
2992
; b3: 1=int15h/C8h (en/dis CPU) supported
2993
; b2: 1=non-8042 kb controller
2994
; b1: 1=data streaming supported
2995
; b0: reserved
2996
;--------------------------------------------------------------------------
2997
            db      44h
2998
;--------------------------------------------------------------------------
2999
; Feature byte 3
3000
; b7: not used
3001
; b6: reserved
3002
; b5: reserved
3003
; b4: POST supports ROM-to-RAM enable/disable
3004
; b3: SCSI on system board
3005
; b2: info panel installed
3006
; b1: Initial Machine Load (IML) system - BIOS on disk
3007
; b0: SCSI supported in IML
3008
;--------------------------------------------------------------------------
3009
            db      0
3010
;--------------------------------------------------------------------------
3011
; Feature byte 4
3012
; b7: IBM private
3013
; b6: EEPROM present
3014
; b5-3: ABIOS presence (011 = not supported)
3015
; b2: private
3016
; b1: memory split above 16Mb supported
3017
; b0: POSTEXT directly supported by POST
3018
;--------------------------------------------------------------------------
3019
            db      0
3020
;--------------------------------------------------------------------------
3021
; Feature byte 5 (IBM)
3022
; b1: enhanced mouse
3023
; b0: flash EPROM
3024
;--------------------------------------------------------------------------
3025
            db      0
3026
 
3027
 
3028
; --------------------- INT 16h - keyboard interface ----------------
3029
;       AH      Description
3030
;       --      ------------------------------------------------
3031
;       00h     Get a key from the keyboard, return code in AX.
3032
;       01h     Test for available key, ZF=1 if none, ZF=0 and
3033
;               AX contains next key code if key available.
3034
;       02h     Get shift status. Returns shift key status in AL.
3035
;       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.
3036
;       05h     Store scan code (in CX) in the type ahead buffer.
3037
;       10h     Get a key (same as 00h in this implementation).
3038
;       11h     Test for key (same as 01h).
3039
;       12h     Get extended key status. Returns status in AX.
3040
 
3041
AltKpd          equ     
3042
HeadPtr         equ     
3043
TailPtr         equ     
3044
Buffer          equ     ;1eh
3045
EndBuf          equ     ;3eh
3046
 
3047
int16 proc near
3048
        push    ds
3049
        push    si
3050
        push    40h
3051
        pop     ds
3052
        xchg    al, ah          ;shorter opcodes for al than ah
3053
        dec     ax
3054
        test    al, 0EFh        ;Check for 01h and 11h
3055
        jz      short TestKey   ;TestKey does not need cld
3056
        inc     ax
3057
        cld
3058
        test    al, 0EFh        ;Check for 0h and 10h
3059
        jz      short GetKey
3060
        cmp     al, 3           ;Check for 02h and 03h
3061
        jb      short GetStatus
3062
        je      short SetAutoRpt
3063
        cmp     al, 5           ;Check for StoreKey function.
3064
        je      short StoreKey
3065
        cmp     al, 9           ;Get KB functionality
3066
        je      short kbfunc
3067
        cmp     al, 12h         ;Extended status call
3068
        je      short ExtStatus
3069
        cmp     al, 92h         ;stupid keyb.com
3070
        jne     short Exit
3071
kbfunc:
3072
        mov     al, 24h         ;AL=20h (fn 10h, 12h supported, set typematic supported)
3073
Exit:
3074
        pop     si
3075
        pop     ds
3076
        iret                    ; unknown function, Restores flags.
3077
 
3078
GetKey1:                        ; wait for interrupt
3079
        hlt
3080
GetKey: ; ----------- fn 00h, 10h
3081
        mov     ah, 11h
3082
        int     16h             ;See if key is available (IF becomes 1 after this int)
3083
        jz      short GetKey1   ;Wait for keystroke.
3084
        cli                     ;Critical region! Ints off.
3085
        mov     si, HeadPtr     ;Ptr to next character.
3086
        lodsw                   ;Get the character, Bump up HeadPtr
3087
        cmp     si, EndBuf
3088
        jb      short noWrap
3089
        mov     si, Buffer
3090
noWrap:
3091
        mov     HeadPtr, si
3092
        jmp     short Exit
3093
 
3094
TestKey: ; ---------- fn 01h
3095
        mov     si, HeadPtr
3096
        cmp     si, TailPtr     ;ZF=1, if empty buffer
3097
        lodsw                   ;BIOS returns avail keycode.
3098
        sti                     ;Ints back on.
3099
        pop     si
3100
        pop     ds
3101
        retf    2               ;Pop flags (ZF is important!)
3102
 
3103
StoreKey: ; ---------- fn 05h - Inserts the value in CX into the type ahead buffer.
3104
        mov     si, TailPtr     ;Address where we can put next key code.
3105
        mov     [si], cx        ;Store the key code away
3106
        inc     si
3107
        inc     si              ;Move on to next entry in buf
3108
        cmp     si, EndBuf
3109
        jb      short NoWrap1
3110
        mov     si, Buffer
3111
 NoWrap1:
3112
        mov     al, 1           ;no room
3113
        cmp     si, HeadPtr     ;Data overrun?
3114
        je      short Exit      ;if so, ignore key entry.
3115
        mov     TailPtr, si
3116
        dec     ax              ;al=0
3117
        jmp     short Exit
3118
 
3119
ExtStatus: ; ------- fn 12h - Retrieve the extended keyboard status and return it in AH, and the standard keyboard status in AL.
3120
        mov     al, KbdFlags2
3121
        and     al, 01110111b   ;Clear final sysreq field, and final right alt bit.
3122
        test    al, 100b        ;Test cur sysreq bit.
3123
        jz      short NoSysReq  ;Skip if it's zero.
3124
        sub     al, 10000100b   ;Set final sysreq bit, clear final right ctl bit.
3125
NoSysReq:
3126
        mov     ah, KbdFlags3
3127
        and     ah, 1100b       ;Grab rt alt/ctrl bits.
3128
        or      ah, al          ;Merge into AH.
3129
 
3130
GetStatus: ; --------- fn 02h
3131
        mov     al, KbdFlags1   ;Just return Std Status.
3132
Exit1:
3133
        jmp     short Exit
3134
 
3135
SetAutoRpt: ; ------ fn 03h
3136
        cmp     ah, 5
3137
        jne     short Exit
3138
        push    dx
3139
        shl     bh, 5
3140
        and     bl, 1fh
3141
        or      bl, bh
3142
        and     bl, 7fh
3143
        mov     ah, 0           ; wait LED update progress to finalize
3144
        call    WaitFlag        ; leaves with IF=0
3145
        jc      short timeout
3146
        or      byte ptr KbdFlags4, SetRepeat    ; set auto repeat in progress
3147
        mov     ah, 0f3h        ; set typematic rate and delay
3148
        push    bx
3149
        xor     bl, bl          ; send to kb
3150
        call    sendps2byte
3151
        pop     bx
3152
        jc      short timeout1  ; send timeout
3153
        mov     ah, SetRepeat or AckReceived ; test if ACK received
3154
        call    WaitFlag
3155
        jc      short timeout1
3156
        mov     ah, bl
3157
        xor     bl, bl          ; send to kb
3158
        call    sendps2byte     ; send data
3159
timeout1:
3160
        and     byte ptr KbdFlags4, not SetRepeat
3161
timeout:
3162
        pop     dx
3163
        jmp     short Exit1
3164
 
3165
 
3166
WaitFlag:   ; ah = desired KbdFlags4 & (AckReceived | LEDUpdate | SetRepeat)
3167
        mov     dx, 3dah
3168
        mov     bh, 8*25    ; wait for max 25 * VGA frame time
3169
wf_loop:
3170
        cli
3171
        mov     al, KbdFlags4
3172
        and     al, AckReceived or LEDUpdate or SetRepeat
3173
        cmp     al, ah
3174
        je      short wf_ok ; flag ok, CF=0
3175
        sti
3176
        in      al, dx      ; get vblank
3177
        xor     al, bh
3178
        and     al, 8h
3179
        sub     bh, al
3180
        jnc     short wf_loop     ; IBF - buffer full, no timeout
3181
wf_ok:
3182
        ret
3183
int16 endp
3184
 
3185
; --------------------- INT 18h - BIOS Basic ------------------
3186
int18 proc near
3187
        push    cs
3188
        pop     es
3189
        mov     si, offset booterrmsg
3190
        call    prts
3191
 
3192
;-------------- RS232 bootstrap
3193
        mov     al, 0b4h
3194
        out     43h, al
3195
        mov     ax, 0f000h
3196
        out     42h, al
3197
        out     42h, al      ; 18Hz PIT CH2
3198
          mov ds,ax
3199
          mov es,ax
3200
 
3201
        mov si,100h
3202
          call srecb
3203
        cli
3204
          mov bh,ah
3205
          call srecb
3206
          mov bl,ah
3207
sloop:
3208
          call srecb
3209
          mov [si],ah
3210
          inc si
3211
          dec bx
3212
          jnz short sloop
3213
          db 0eah
3214
        dw 100h,0f000h
3215
 
3216
booterrmsg db   'No boot device available, waiting on RS232 (115200bps, f000:100) ...', 13, 10, 0
3217
int18 endp
3218
 
3219
; --------------------- INT 19h - OS Bootstrap loader ------------------
3220
int19 proc near
3221
        mov     ax, 201h
3222
        mov     cx, 1
3223
        mov     dx, 80h
3224
        push    0
3225
        pop     es
3226
        mov     bx, 7c00h
3227
        int     13h
3228
        jc      int19err
3229
        db      0eah
3230
        dw      7c00h, 0     ; jmp far 0000h:7c00h
3231
int19err:
3232
        int     18h
3233
int19 endp
3234
 
3235
 
3236
; --------------------- INT 1ah - Get System Time ------------------
3237
int1a proc near
3238
        push    ds
3239
        push    40h
3240
        pop     ds
3241
        cmp     ah, 1
3242 4 ndumitrach
        ja      clockexit
3243 3 ndumitrach
        je      setclock
3244
        mov     dx, ds:[6ch]    ; read clock
3245
        mov     cx, ds:[6eh]
3246
        mov     al, ds:[70h]
3247 4 ndumitrach
clockexit1:
3248
        mov     byte ptr ds:[70h], 0
3249 3 ndumitrach
clockexit:
3250
        cmc     ; CF = 1 on error
3251
        pop     ds
3252
        sti
3253
        retf    2
3254
 
3255
setclock:
3256
        mov     ds:[6ch], dx
3257
        mov     ds:[6eh], cx
3258 4 ndumitrach
        stc
3259
        jmp     short clockexit1
3260 3 ndumitrach
int1a endp
3261
 
3262
 
3263
; --------------------- INT 70h - RTC ------------------
3264
int70 proc near
3265
        push    ds
3266
        push    40h
3267
        pop     ds
3268
        test    byte ptr UWaitFlag, 1    ; is wait in progress?
3269
        jz      short exit
3270
        sub     word ptr WaitCount[0], 1000
3271
        sbb     word ptr WaitCount[2], 0
3272
        jnc     short exit
3273
        mov     byte ptr UWaitFlag, 0
3274
        push    bx
3275
        lds     bx, UFPtr
3276
        or      byte ptr [bx], 80h
3277
        pop     bx
3278
exit:
3279
        pop     ds
3280
        iret
3281
int70 endp
3282
 
3283
 
3284
; --------------------- INT 74h - mouse ------------------
3285
int74 proc near
3286
        cld
3287
        pusha
3288
        push    ds
3289
        push    40h
3290
        pop     ds
3291
        mov     ah, 0
3292
        in      al, 60h
3293
        mov     bx, ax
3294
        inc     byte ptr DataCounter
3295
        mov     al, DataCounter
3296
        mov     si, ax
3297
        sub     al, 3
3298
        ja      short docall
3299
        mov     DataBuffer[si-1], bl
3300
        cmp     al, PacketSize
3301
        jne     short nocall
3302
        mov     bl, 0
3303
docall:
3304
        mov     byte ptr DataCounter, bh    ; BH=0
3305
        mov     si, offset DataBuffer-2
3306
        lodsw
3307
        or      ax, [si-4]
3308
        jz      short nocall
3309
        sti
3310
        push    es
3311
        mov     ah, 0
3312
        lodsb
3313
        push    ax
3314
        lodsb
3315
        push    ax
3316
        lodsb
3317
        push    ax
3318
        push    bx
3319
        call    far ptr [si-7]
3320
        add     sp, 8
3321
        pop     es
3322
nocall:
3323
        pop     ds
3324
        popa
3325
        iret
3326
int74 endp
3327
 
3328
 
3329
; ----------------  serial receive byte 115200 bps --------------
3330
srecb:  mov     ah, 80h
3331
        mov     dx, 3dah
3332
        mov     cx, -5aeh ; (half start bit)
3333
srstb:  in      al, dx
3334
          shr     al, 2
3335
          jc      short srstb
3336
        in      al, 42h ; lo counter
3337
        add     ch, al
3338
        in      al, 42h ; hi counter, ignore
3339
l1:
3340
        call    dlybit
3341
          in      al, dx
3342
        shr     al, 2
3343
          rcr     ah, 1
3344
          jnc     short l1
3345
dlybit:
3346
        sub     cx, 0a5bh  ;  (full bit)
3347
dly1:
3348
        in      al, 42h
3349
        cmp     al, ch
3350
        in      al, 42h
3351
        jnz     short dly1
3352
        ret
3353
 
3354
; -------------------- KB/Mouse access ----------------
3355
sendps2byte proc near   ; ah=data, bl!=0 for mouse, 0 for kb. returns cf=1 if timeout (al = 8)
3356
; changes BH, AL
3357
        push    dx
3358
        mov     dx, 3dah
3359
        mov     bh, 8*5
3360
sps2b2:
3361
        in      al, 64h
3362
        test    al, 2
3363
        jz      short sps2b1; buffer empty
3364
        in      al, dx      ; get vblank
3365
        xor     al, bh
3366
        and     al, 8h
3367
        sub     bh, al
3368
        jnc     short sps2b2; IBF - buffer full, no timeout
3369
        jmp     short exit  ; timeout, CF=1
3370
sps2b1:
3371
        test    bl, bl      ; CF=0
3372
        jz      short sps2_kb
3373
        mov     al, 0d4h    ; next mouse
3374
        out     64h, al
3375
sps2_kb:
3376
        mov     al, ah
3377
        out     60h, al     ; send byte
3378
exit:
3379
        pop     dx
3380
        ret
3381
sendps2byte endp
3382
 
3383
getps2byte proc near    ; returns al=data, zf=0 for mouse, 1 for kb, cf=1 if timeout (al=8)
3384
; changes BH, DX, AL
3385
        mov     dx, 3dah
3386
        mov     bh, 8*5
3387
gps2b2:
3388
        in      al, 64h
3389
        test    al, 1
3390
        jnz     short gps2b1     ; OBF (buffer full), continue
3391
        in      al, dx     ; get vblank
3392
        xor     al, bh
3393
        and     al, 8
3394
        sub     bh, al
3395
        jnc     short gps2b2     ; buffer empty, no timeout
3396
        ret                ; timeout, CF=1
3397
gps2b1:
3398
        test    al, 20h    ; CF=0, ZF <- !MOBF
3399
        in      al, 60h    ; read byte (if IF=1, this data may be invalid)
3400
        ret
3401
getps2byte endp
3402
 
3403
sendcmd proc near     ; ah = command, CF=1 for mouse, CF=0 for kb. returns CF=1 on error
3404
        sbb     bl, bl      ; bl <- CF
3405
        call    sendps2byte
3406
        jc      short exit
3407
retry:
3408
        call    getps2byte
3409
        jc      short exit
3410
        cmp     al, 0fah    ; ack (returns CF=1 on error, when al=8)
3411
        jne     short retry
3412
exit:
3413
        ret
3414
sendcmd endp
3415
 
3416
enableKbIfPresent proc near ; input DS = 40h
3417
; modify AL, flags
3418
        test    byte ptr KbdFlags3, 10h
3419
        jz      short noenablekb
3420
        mov     al, 0aeh
3421
        out     64h, al     ; enable kb interface
3422
noenablekb:
3423
        ret
3424
enableKbIfPresent endp
3425
 
3426
; ----------------------- default interrupt handler ---------------
3427
defint  proc near
3428
        iret
3429
defint  endp
3430
 
3431
; ------------------------------- flush --------------------------
3432
flush:
3433
        pop     cs:flushret
3434
flush_nostack:
3435
        mov     cs:flushbh, bh
3436
        mov     bh, 7       ; flush all 7 cache lines (the 8th one is CS:IP)
3437
flush1:
3438
        test    bl, cs:[bx + 0e000h]
3439
        dec     bh
3440
        jnz     short flush1
3441
        mov     bh, cs:flushbh
3442
        jmp     word ptr cs:flushret
3443
flushret dw 0
3444
flushbh  db 0
3445
 
3446
; ------------------------------- misc --------------------------
3447
dispAX:
3448
        push    dx
3449
        xor     dx, dx
3450
        div     word ptr cs:ten
3451
        test    ax, ax
3452
        jz      dispAX1
3453
        call    dispAX
3454
dispAX1:
3455
        xchg    ax, dx
3456
        add     ax, 0e00h + '0'
3457
        int     10h
3458
        pop     dx
3459
        ret
3460
ten     dw      10
3461
 
3462
prts:   ; es:si = string
3463
        mov     ah, 0eh
3464
        lodsb   es:[si]
3465
        or      al, al
3466
        jz      short prtse
3467
        int     10h
3468
        jmp     short prts
3469
prtse:
3470
        ret
3471
 
3472
 
3473
 
3474
;---------------------  read/write byte ----------------------
3475
sdrb:   mov al,0ffh
3476
sdsb:               ; in AL=byte, DX = 03dah, out AX=result
3477
        out     dx, al
3478
        add     ax, ax
3479
        out     dx, al
3480
        add     ax, ax
3481
        out     dx, al
3482
        add     ax, ax
3483
        out     dx, al
3484
        add     ax, ax
3485
        out     dx, al
3486
        add     ax, ax
3487
        out     dx, al
3488
        add     ax, ax
3489
        out     dx, al
3490
        add     ax, ax
3491
        out     dx, al
3492
        in      ax, dx
3493
        ret
3494
 
3495
;---------------------  write block ----------------------
3496
sdwblk proc near              ; in SI=data ptr, DX=03dah, CX=size
3497
        shr     cx, 1
3498
sdwblk1:
3499
        lodsb
3500
        out     dx, al
3501
        add     ax, ax
3502
        out     dx, al
3503
        add     ax, ax
3504
        out     dx, al
3505
        add     ax, ax
3506
        out     dx, al
3507
        add     ax, ax
3508
        out     dx, al
3509
        add     ax, ax
3510
        out     dx, al
3511
        add     ax, ax
3512
        out     dx, al
3513
        add     ax, ax
3514
        out     dx, al
3515
        lodsb
3516
        out     dx, al
3517
        add     ax, ax
3518
        out     dx, al
3519
        add     ax, ax
3520
        out     dx, al
3521
        add     ax, ax
3522
        out     dx, al
3523
        add     ax, ax
3524
        out     dx, al
3525
        add     ax, ax
3526
        out     dx, al
3527
        add     ax, ax
3528
        out     dx, al
3529
        add     ax, ax
3530
        out     dx, al
3531
        loop    short sdwblk1
3532
        ret
3533
sdwblk endp
3534
 
3535
;---------------------  read block ----------------------
3536
sdrblk proc near              ; in DI=data ptr, DX=03dah, CX=size. Returns CF = 0
3537
        mov     al, 0ffh
3538
        out     dx, al
3539
        shr     cx, 1         ; CF = 0
3540
        out     dx, al
3541
        jmp     short sdrblk2
3542
sdrblk1:
3543
        out     dx, al
3544
        mov     [di], ah
3545
        out     dx, al
3546
        inc     di
3547
sdrblk2:
3548
        out     dx, al
3549
        nop
3550
        out     dx, al
3551
        nop
3552
        out     dx, al
3553
        nop
3554
        out     dx, al
3555
        nop
3556
        out     dx, al
3557
        nop
3558
        out     dx, al
3559
        in      ax, dx
3560
        out     dx, al
3561
        mov     [di], ah
3562
        out     dx, al
3563
        inc     di
3564
        out     dx, al
3565
        nop
3566
        out     dx, al
3567
        nop
3568
        out     dx, al
3569
        nop
3570
        out     dx, al
3571
        nop
3572
        out     dx, al
3573
        nop
3574
        out     dx, al
3575
        in      ax, dx
3576
        loop    short sdrblk1
3577
        mov     [di], ah
3578
        inc     di
3579
        ret
3580
sdrblk endp
3581
 
3582
;---------------------  verify block ----------------------
3583
sdvblk:              ; in DI=data ptr, DX=03dah, CX=size. Returns CF=1 on error
3584
        push    bx
3585
        xor     bl, bl
3586
sdvblk1:
3587
        call    sdrb
3588
        sub     ah, [di]
3589
        or      bl, ah
3590
        inc     di
3591
        loop    short sdvblk1
3592
        neg     bl  ; CF=1 if BL != 0
3593
        pop     bx
3594
        ret
3595
 
3596
;---------------------  write command ----------------------
3597
sdcmd8T:
3598
        call    sdrb
3599
sdcmd:              ; in SI=6 bytes cmd buffer, DX=03dah, out AH = 0ffh on error
3600
        mov     cx, 6
3601
        call    sdwblk
3602
sdresp:
3603
        xor     si, si
3604
sdresp1:
3605
        call    sdrb
3606
        inc     si
3607
        jz      short sdcmd1
3608
        cmp     ah, 0ffh
3609
        je      short sdresp1
3610
sdcmd1: ret
3611
 
3612
;---------------------  read ----------------------
3613
sdverify:
3614
        push    sdvblk
3615
        jmp     short sdread1
3616
sdread:   ; DX:AX sector, ES:BX buffer, CX=sectors. returns AX=read sectors
3617
        push    sdrblk   ; push proc address (read or verify) on stack
3618
sdread1:
3619
        push    ax
3620
        mov     al, dl
3621
        push    ax
3622
        mov     dl, 51h  ; CMD17
3623
        cmp     cx, 1
3624
        je      short sdr1s
3625
        inc     dx      ; CMD18 - multiple sectors
3626
sdr1s:
3627
        push    dx
3628
        mov     si, sp
3629
 
3630
        mov     dx, 3dah
3631
        mov     ah, 1
3632
        out     dx, ax       ; CS on
3633
        mov     di, bx
3634
        mov     bx, cx
3635
        mov     bp, cx       ; save sectors number
3636
        push    ss
3637
        pop     ds
3638
        call    sdcmd
3639
        add     sp, 6
3640
        or      ah, ah
3641
        jnz     short sdr11   ; error
3642
        push    es
3643
        pop     ds
3644
sdrms:
3645
        mov     ax, di
3646
        shr     ax, 4
3647
        mov     si, ds
3648
        add     ax, si
3649
        mov     ds, ax
3650
        and     di, 15
3651
        call    sdresp     ; wait for 0feh token
3652
        cmp     ah, 0feh
3653
        jne     short sdr11; read token error
3654
        mov     ch, 2      ; 512 byte sector
3655
        pop     si
3656
        call    si         ; sdrblk or sdvblk
3657
        push    si
3658
        pushf
3659
        call    sdrb       ; ignore CRC
3660
        call    sdrb       ; ignore CRC
3661
        popf
3662
        jc      short sdr3 ; verify error
3663
        dec     bx
3664
        jnz     short sdrms; multiple sectors
3665
sdr3:
3666
        cmp     bp, 1
3667
        je      short sdr11; single sector
3668
        mov     si, offset SD_CMD12 ; stop transfer
3669
        push    cs
3670
        pop     ds
3671
        call    sdcmd
3672
sdr2:
3673
        shr     ah, 1
3674
        jnc     short sdr11
3675
        call    sdrb
3676
        jmp     short sdr2
3677
sdr11:
3678
        pop     ax         ; remove proc address from stack
3679
sdr1:
3680
        xor     ax, ax
3681
        out     dx, ax
3682
        call    sdrb       ; 8T
3683
        mov     ax, bp
3684
        sub     ax, bx
3685
        ret
3686
 
3687
;---------------------  write ----------------------
3688
sdwrite:   ; DX:AX sector, ES:BX buffer, CX=sectors, returns AX=wrote sectors
3689
        push    ax
3690
        mov     al, dl
3691
        push    ax
3692
        mov     dl, 58h  ; CMD24
3693
        cmp     cx, 1
3694
        je      short sdw1s
3695
        inc     dx      ; CMD25 - multiple sectors
3696
sdw1s:
3697
        push    dx
3698
        mov     si, sp
3699
 
3700
        mov     dx, 3dah
3701
        mov     ah, 1
3702
        out     dx, ax       ; CS on
3703
        mov     bp, cx       ; save sectors number
3704
        push    ss
3705
        pop     ds
3706
        call    sdcmd
3707
        add     sp, 6
3708
        mov     si, bx
3709
        mov     bx, bp
3710
        or      ah, ah
3711
        jnz     short sdr1   ; error
3712
        push    es
3713
        pop     ds
3714
sdwms:
3715
        mov     ax, si
3716
        shr     ax, 4
3717
        mov     di, ds
3718
        add     ax, di
3719
        mov     ds, ax
3720
        and     si, 15
3721
        mov     al, 0feh      ; start token
3722
        cmp     bp, 1
3723
        je      short sdw1s1
3724
        mov     al, 0fch   ; multiple sectors
3725
sdw1s1:
3726
        call    sdsb
3727
        mov     ch, 2      ; 512 byte sector
3728
        call    sdwblk
3729
        call    sdrb       ; ignore CRC
3730
        call    sdrb       ; ignore CRC
3731
        call    sdrb       ; read response byte xxx00101
3732
        and     ah, 0eh
3733
        cmp     ah, 4
3734
        jne     short sdr1 ; write error
3735
sdwwait:
3736
        call    sdrb
3737
        shr     ah, 1
3738
        jnc     short sdwwait     ; wait write completion
3739
        dec     bx
3740
        jnz     short sdwms       ; multiple sectors
3741
 
3742
        cmp     bp, 1
3743
        je      short sdr1
3744
        mov     al, 0fdh     ; multiple end transfer
3745
        call    sdsb
3746
sdwwait1:
3747
        call    sdrb
3748
        shr     ah, 1
3749
        jnc     short sdwwait1     ; wait write completion
3750
        jmp     sdr1
3751
 
3752
;---------------------  init SD ----------------------
3753
sdinit  proc near       ; returns AX = num kilosectors
3754
        push    ds
3755
        push    cx
3756
        push    dx
3757
        push    si
3758
        push    di
3759
        mov     dx, 3dah
3760
        mov     cx, 10
3761
sdinit1:                   ; send 80T
3762
        call    sdrb
3763
        loop    short sdinit1
3764
 
3765
        mov     ah, 1
3766
        out     dx, ax       ; select SD
3767
 
3768
        mov     si, offset SD_CMD0
3769
        push    cs
3770
        pop     ds
3771
        call    sdcmd
3772
        dec     ah
3773
        jnz     short sdexit ; error
3774
 
3775
        mov     si, offset SD_CMD8
3776
        call    sdcmd8T
3777
        dec     ah
3778
        jnz     short sdexit ; error
3779
        mov     cl, 4
3780
        sub     sp, cx
3781
        mov     di, sp
3782
        push    ss
3783
        pop     ds
3784
        call    sdrblk
3785
        pop     ax
3786
        pop     ax
3787
        cmp     ah, 0aah
3788
        jne     short sdexit ; CMD8 error
3789
repinit:
3790
        mov     si, offset SD_CMD55
3791
        push    cs
3792
        pop     ds
3793
        call    sdcmd8T
3794
        call    sdrb
3795
        mov     si, offset SD_CMD41
3796
        call    sdcmd
3797
        dec     ah
3798
        jz      short repinit
3799
 
3800
        mov     si, offset SD_CMD58
3801
        call    sdcmd8T
3802
        mov     cl, 4
3803
        sub     sp, cx
3804
        mov     di, sp
3805
        push    ss
3806
        pop     ds
3807
        call    sdrblk
3808
        pop     ax
3809
        test    al, 40h     ; test OCR bit 30 (CCS)
3810
        pop     ax
3811
        jz      short sdexit; no SDHC
3812
 
3813
        mov     si, offset SD_CMD9 ; get size info
3814
        push    cs
3815
        pop     ds
3816
        call    sdcmd8T
3817
        or      ah, ah
3818
        jnz     short sdexit
3819
        call    sdresp     ; wait for 0feh token
3820
        cmp     ah, 0feh
3821
        jne     short sdexit
3822
        mov     cl, 18       ; 16bytes + 2bytes CRC
3823
        sub     sp, cx
3824
        mov     di, sp
3825
        push    ss
3826
        pop     ds
3827
        call    sdrblk
3828
        mov     cx, [di-10]
3829
        rol     cx, 8
3830
        inc     cx
3831
        mov     sp, di
3832
sdexit:
3833
        xor     ax, ax       ; raise CS
3834
        out     dx, ax
3835
        call    sdrb
3836
        pop     di
3837
        pop     si
3838
        pop     dx
3839
        mov     ax, cx
3840
        pop     cx
3841
        pop     ds
3842
        ret
3843
sdinit endp
3844
 
3845
SD_CMD0     db  40h, 0, 0, 0, 0, 95h
3846
SD_CMD8     db  48h, 0, 0, 1, 0aah, 087h
3847
SD_CMD9     db  49h, 0, 0, 0, 0, 0ffh
3848
SD_CMD12    db  4ch, 0, 0, 0, 0, 0ffh
3849
SD_CMD41    db  69h, 40h, 0, 0, 0, 0ffh
3850
SD_CMD55    db  77h, 0, 0, 0, 0, 0ffh
3851
SD_CMD58    db  7ah, 0, 0, 0, 0, 0ffh
3852
 
3853
 
3854
default_pal:
3855
        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
3856
        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
3857
        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
3858
        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
3859
        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
3860
        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
3861
        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
3862
        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
3863
        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
3864
        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
3865
        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
3866
        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
3867
        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
3868
        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
3869
        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
3870
        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
3871
        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
3872
        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
3873
        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
3874
        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
3875
        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
3876
        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
3877
        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
3878
        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
3879
        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
3880
        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
3881
        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
3882
        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
3883
        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
3884
        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
3885
        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
3886
        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
3887
 
3888
IFDEF SCANCODE1 ; use SCANCODE1
3889
KeyIndex:
3890
        db      0, 82, 49, 50, 52, 51, 54, 55    ;0-7
3891
        db 56, 57, 60, 59, 65, 68, 72, 47    ;8-f
3892
        db      1,  5,  9, 13, 12, 18, 21, 23    ;10-17
3893
        db 24, 26, 67, 70, 69,  0,  4,  3    ;18-1f
3894
        db      8, 11, 17, 16, 20, 22, 25, 64    ;20-27
3895
        db 66, 48,  0, 71,  2,  7,  6, 10    ;28-2f
3896
        db 15, 14, 19, 58, 61, 62,  0, 87    ;30-37
3897
        db      0, 53,  0, 40, 41, 39, 46, 38    ;38-3f
3898
        db 45, 90, 44, 79, 43,  0, 89, 29    ;40-47
3899
        db 34, 36, 86, 28, 37, 33, 84, 27    ;48-4f
3900
        db 32, 35, 30, 31,  0,  0,      0, 83    ;50-57
3901
        db 42
3902
E0KeyList:
3903
        db      35h, 1ch, 4fh, 4bh, 47h, 52h, 53h, 50h, 4dh, 48h, 51h, 49h
3904
 
3905
ELSE    ; use SCANCODE2
3906
 
3907
KeyIndex:
3908
        db      0, 79,  0, 38, 39, 40, 41, 42
3909
        db      0, 43, 44, 45, 46, 47, 48,  0
3910
        db      0,  0,  0,  0,  0,  1, 49,  0
3911
        db      0,  0,  2,      3,  4,  5, 50,  0
3912
        db      0,  6,  7,      8,  9, 51, 52,  0
3913
        db      0, 53, 10, 11, 12, 13, 54,  0
3914
        db      0, 14, 15, 16, 17, 18, 55,  0
3915
        db      0,  0, 19, 20, 21, 56, 57,  0
3916
        db      0, 58, 22, 23, 24, 59, 60,  0
3917
        db      0, 61, 62, 25, 64, 26, 65,  0
3918
        db      0,  0, 66,      0, 67, 68,      0,  0
3919
        db      0,  0, 69, 70,  0, 71,  0,  0
3920
        db      0,  0,  0,      0,  0,  0, 72,  0
3921
        db      0, 27,  0, 28, 29,  0,  0,  0
3922
        db 30, 31, 32, 37, 33, 34, 82,  0
3923
        db 83, 84, 35, 86, 87, 36, 89,  0
3924
        db      0,  0,  0,      90
3925
E0KeyList:
3926
        db      4ah, 5ah, 69h, 6bh, 6ch, 70h, 71h, 72h, 74h, 75h, 7ah, 7dh
3927
 
3928
ENDIF
3929
 
3930
E0KeyIndex:
3931
        db      63,  69,  73,  74,  75,  76,  77,  78,  80,  81,  85,  88
3932
 
3933
KeyCode:
3934
; Keys affected by CapsLock
3935
;               norm   shft   ctrl   alt
3936
        dw      0000h, 0000h, 0000h, 0000h ;17 - <0>
3937
        dw      1071h, 1051h, 1011h, 1000h ;15 - Q, (E0)PrevTrack <1>
3938
        dw      2c7ah, 2c5ah, 2c1ah, 2c00h ;1a - Z <2>
3939
        dw      1f73h, 1f53h, 1f13h, 1f00h ;1b - S <3>
3940
        dw      1e61h, 1e41h, 1e01h, 1e00h ;1c - A <4>
3941
        dw      1177h, 1157h, 1117h, 1100h ;1d - W <5>
3942
        dw      2e63h, 2e43h, 2e03h, 2e00h ;21 - C, (E0)Volume Down <6>
3943
        dw      2d78h, 2d58h, 2d18h, 2d00h ;22 - X <7>
3944
        dw      2064h, 2044h, 2004h, 2000h ;23 - D, (E0)Mute <8>
3945
        dw      1265h, 1245h, 1205h, 1200h ;24 - E <9>
3946
        dw      2f76h, 2f56h, 2f16h, 2f00h ;2a - V <10>
3947
        dw      2166h, 2146h, 2106h, 2100h ;2b - F, (E0)Calculator <11>
3948
        dw      1474h, 1454h, 1414h, 1400h ;2c - T <12>
3949
        dw      1372h, 1352h, 1312h, 1300h ;2d - R <13>
3950
        dw      316eh, 314eh, 310eh, 3100h ;31 - N <14>
3951
        dw      3062h, 3042h, 3002h, 3000h ;32 - B, (E0)Volume Up <15>
3952
        dw      2368h, 2348h, 2308h, 2300h ;33 - H <16>
3953
        dw      2267h, 2247h, 2207h, 2200h ;34 - G, (E0)Play/Pause <17>
3954
        dw      1579h, 1559h, 1519h, 1500h ;35 - Y <18>
3955
        dw      326dh, 324dh, 320dh, 3200h ;3a - M, (E0)WWW Home <19>
3956
        dw      246ah, 244ah, 240ah, 2400h ;3b - J, (E0)Stop <20>
3957
        dw      1675h, 1655h, 1615h, 1600h ;3c - U <21>
3958
        dw      256bh, 254bh, 250bh, 2500h ;42 - K <22>
3959
        dw      1769h, 1749h, 1709h, 1700h ;43 - I <23>
3960
        dw      186fh, 184fh, 180fh, 1800h ;44 - O <24>
3961
        dw      266ch, 264ch, 260ch, 2600h ;4b - L <25>
3962
        dw      1970h, 1950h, 1910h, 1900h ;4d - P, (E0)Next Track <26>
3963
; keys affected by NumLock
3964
        dw      4f00h, 4f31h, 7500h, 0002h ;69 - KP1 <27>
3965
        dw      4b00h, 4b34h, 7300h, 0005h ;6b - KP4 <28>
3966
        dw      4700h, 4737h, 7700h, 0008h ;6c - KP7 <29>
3967
        dw      5200h, 5230h, 9200h, 0001h ;70 - KP0 <30>
3968
        dw      5300h, 532eh, 9300h, 0000h ;71 - KP. <31>
3969
        dw      5000h, 5032h, 9100h, 0003h ;72 - KP2 <32>
3970
        dw      4d00h, 4d36h, 7400h, 0007h ;74 - KP6 <33>
3971
        dw      4800h, 4838h, 8d00h, 0009h ;75 - KP8 <34>
3972
        dw      5100h, 5133h, 7600h, 0004h ;7a - KP3 <35>
3973
        dw      4900h, 4939h, 8400h, 000ah ;7d - KP9 <36>
3974
        dw      4c00h, 4c35h, 8f00h, 0006h ;73 - KP5 --- on VMWare, it does not send 4c00 <37>
3975
; keys unaffected by CapsLock or N
3976
        dw      3f00h, 5800h, 6200h, 6c00h ;03 - F5 <38>
3977
        dw      3d00h, 5600h, 6000h, 6a00h ;04 - F3 <39>
3978
        dw      3b00h, 5400h, 5e00h, 6800h ;05 - F1 <40>
3979
        dw      3c00h, 5500h, 5f00h, 6900h ;06 - F2 <41>
3980
        dw      8600h, 8800h, 8a00h, 8c00h ;07 - F12 <42>
3981
        dw      4400h, 5d00h, 6700h, 7100h ;09 - F10 <43>
3982
        dw      4200h, 5b00h, 6500h, 6f00h ;0a - F8 <44>
3983
        dw      4000h, 5900h, 6300h, 6d00h ;0b - F6 <45>
3984
        dw      3e00h, 5700h, 6100h, 6b00h ;0c - F4 <46>
3985
        dw      0f09h, 0f00h, 9400h, 0000h ;0d - TAB <47>
3986
        dw      2960h, 297eh, 0000h, 2900h ;0e - ` ~ <48>
3987
        dw      0231h, 0221h, 0000h, 7800h ;16 - 1 ! <49>
3988
        dw      0332h, 0340h, 0300h, 7900h ;1e - 2 @ <50>
3989
        dw      0534h, 0524h, 0000h, 7b00h ;25 - 4 $ <51>
3990
        dw      0433h, 0423h, 0000h, 7a00h ;26 - 3 # <52>
3991
        dw      3920h, 3920h, 3920h, 3920h ;29 - SPC <53>
3992
        dw      0635h, 0625h, 0000h, 7c00h ;2e - 5 % <54>
3993
        dw      0736h, 075eh, 071eh, 7d00h ;36 - 6 ^ <55>
3994
        dw      0837h, 0826h, 0000h, 7e00h ;3d - 7 & <56>
3995
        dw      0938h, 092ah, 0000h, 7f00h ;3e - 8 * <57>
3996
        dw      332ch, 333ch, 0000h, 3300h ;41 - , < <58>
3997
        dw      0b30h, 0b29h, 0000h, 8100h ;45 - 0 ) <59>
3998
        dw      0a39h, 0a28h, 0000h, 8000h ;46 - 9 ( <60>
3999
        dw      342eh, 343eh, 0000h, 3400h ;49 - . > <61>
4000
        dw      352fh, 353fh, 0000h, 3500h ;4a - / ? <62>
4001
        dw      0e02fh, 0e02fh, 9500h, 0a400h ;4a - (e0)KP/ <63>
4002
        dw      273bh, 273ah, 0000h, 2700h ;4c - ; : <64>
4003
        dw      0c2dh, 0c5fh, 0c1fh, 8200h ;4e - - _ <65>
4004
        dw      2827h, 2822h, 0000h, 2800h ;52 - ’ “ <66>
4005
        dw      1a5bh, 1a7bh, 1a1bh, 1a00h ;54 - [ { <67>
4006
        dw      0d3dh, 0d2bh, 0000h, 8300h ;55 - = + <68>
4007
        dw      1c0dh, 1c0dh, 1c0ah, 1c00h ;5a - Enter, (E0)KPEnter <69>
4008
        dw      1b5dh, 1b7dh, 1b1dh, 1b00h ;5b - ] } <70>
4009
        dw      2b5ch, 2b7ch, 2b1ch, 2b00h ;5d - \ | <71>
4010
        dw      0e08h, 0e08h, 0e7fh, 0e00h ;66 - BKSP <72>
4011
        dw      4f00h, 4f00h, 7500h, 9f00h ;69 - (E0)END <73>
4012
        dw      4b00h, 4b00h, 7300h, 9b00h ;6b - (E0)LEFT <74>
4013
        dw      4700h, 4700h, 7700h, 9700h ;6c - (E0)HOME <75>
4014
        dw      5200h, 5200h, 9200h, 0a200h ;70 - (E0)INS <76>
4015
        dw      5300h, 5300h, 9300h, 0a300h ;71 - (E0)DEL <77>
4016
        dw      5000h, 5000h, 9100h, 0a000h ;72 - (E0)DOWN <78>
4017
        dw      4300h, 5c00h, 6600h, 7000h ;01 - F9 <79>
4018
        dw      4d00h, 4d00h, 7400h, 9d00h ;74 - (E0)RIGHT <80>
4019
        dw      4800h, 4800h, 8d00h, 9800h ;75 - (E0)UP <81>
4020
        dw      011bh, 011bh, 011bh, 0100h ;76 - ESC <82>
4021
        dw      8500h, 8700h, 8900h, 8b00h ;78 - F11 <83>
4022
        dw      4e2bh, 4e2bh, 9000h, 4e00h ;79 - KP+ <84>
4023
        dw      5100h, 5100h, 7600h, 0a100h ;7a - (E0)PGDN <85>
4024
        dw      4a2dh, 4a2dh, 8e00h, 4a00h ;7b - KP- <86>
4025
        dw      372ah, 372ah, 9600h, 3700h ;7c - KP* --- on VMWare, it does not send 3710h with CTL <87>
4026
        dw      4900h, 4900h, 8400h, 9900h ;7d - (E0)PGUP <88>
4027
        dw      4600h, 4600h, 4600h, 4600h ;7e - SCRL <89>
4028
        dw      4100h, 5a00h, 6400h, 6e00h ;83 - F7 <90>
4029
 
4030
; ------------------------- POWER ON RESET -----------------------
4031
        org     0fff0h
4032
 
4033
        db      0eah
4034
        dw      coldboot, 0f000h
4035
        db      '02/05/13'
4036
        db      0ffh, 0ffh, 0
4037
end bios

powered by: WebSVN 2.1.0

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