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

Subversion Repositories next186mp3

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

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

powered by: WebSVN 2.1.0

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