; This file is part of the Next186 SoC PC project
|
; This file is part of the Next186 SoC PC project
|
; http://opencores.org/project,next186
|
; http://opencores.org/project,next186
|
|
|
; Filename: BIOS_Next186.asm
|
; Filename: BIOS_Next186.asm
|
; Description: Part of the Next186 SoC PC project, ROM BIOS code
|
; Description: Part of the Next186 SoC PC project, ROM BIOS code
|
; Version 1.0
|
; Version 1.0
|
; Creation date: Feb-Jun 2013
|
; Creation date: Feb-Jun 2013
|
|
|
; Author: Nicolae Dumitrache
|
; Author: Nicolae Dumitrache
|
; e-mail: ndumitrache@opencores.org
|
; e-mail: ndumitrache@opencores.org
|
|
|
; -------------------------------------------------------------------------------------
|
; -------------------------------------------------------------------------------------
|
|
|
; Copyright (C) 2013 Nicolae Dumitrache
|
; Copyright (C) 2013 Nicolae Dumitrache
|
|
|
; This source file may be used and distributed without
|
; This source file may be used and distributed without
|
; restriction provided that this copyright statement is not
|
; restriction provided that this copyright statement is not
|
; removed from the file and that any derivative work contains
|
; removed from the file and that any derivative work contains
|
; the original copyright notice and the associated disclaimer.
|
; the original copyright notice and the associated disclaimer.
|
|
|
; This source file is free software; you can redistribute it
|
; This source file is free software; you can redistribute it
|
; and/or modify it under the terms of the GNU Lesser General
|
; and/or modify it under the terms of the GNU Lesser General
|
; Public License as published by the Free Software Foundation;
|
; Public License as published by the Free Software Foundation;
|
; either version 2.1 of the License, or (at your option) any
|
; either version 2.1 of the License, or (at your option) any
|
; later version.
|
; later version.
|
|
|
; This source is distributed in the hope that it will be
|
; This source is distributed in the hope that it will be
|
; useful, but WITHOUT ANY WARRANTY; without even the implied
|
; useful, but WITHOUT ANY WARRANTY; without even the implied
|
; warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
; warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
; PURPOSE. See the GNU Lesser General Public License for more
|
; PURPOSE. See the GNU Lesser General Public License for more
|
; details.
|
; details.
|
|
|
; You should have received a copy of the GNU Lesser General
|
; You should have received a copy of the GNU Lesser General
|
; Public License along with this source; if not, download it
|
; Public License along with this source; if not, download it
|
; from http://www.opencores.org/lgpl.shtml
|
; from http://www.opencores.org/lgpl.shtml
|
|
|
; -----------------------------------------------------------------------
|
; -----------------------------------------------------------------------
|
|
|
; Additional Comments:
|
; Additional Comments:
|
; Assembled with MASM v6.14.8444
|
; Assembled with MASM v6.14.8444
|
; Next186 SoC PC have no ROM, only RAM. The bootstrap code is the initial value of cache
|
; Next186 SoC PC have no ROM, only RAM. The bootstrap code is the initial value of cache
|
; (last half 1K = 4 lines of 256bytes each), initially marked as "dirty", in order to
|
; (last half 1K = 4 lines of 256bytes each), initially marked as "dirty", in order to
|
; be saved in RAM at first flush
|
; be saved in RAM at first flush
|
; The bootstrap code may load the BIOS from SD, or from RS232, and place it at F000:E000
|
; The bootstrap code may load the BIOS from SD, or from RS232, and place it at F000:E000
|
|
|
|
|
|
|
.186
|
.186
|
.model tiny
|
.model tiny
|
.code
|
.code
|
|
|
SCANCODE1 equ 1
|
SCANCODE1 equ 1
|
|
|
;-------------------------- BIOS data area (BDA) -----------------
|
;-------------------------- BIOS data area (BDA) -----------------
|
;40:0000 2 Base port address of first RS-232 adapter (COM1) See COM Ports
|
;40:0000 2 Base port address of first RS-232 adapter (COM1) See COM Ports
|
;40:0002 2 Port of COM2
|
;40:0002 2 Port of COM2
|
;40:0004 2 Port of COM3
|
;40:0004 2 Port of COM3
|
;40:0006 2 Port of COM4
|
;40:0006 2 Port of COM4
|
;40:0008 2 Base port addr of first parallel printer (LPT1) Printer Ports
|
;40:0008 2 Base port addr of first parallel printer (LPT1) Printer Ports
|
;40:000A 2 Port of LPT2
|
;40:000A 2 Port of LPT2
|
;40:000C 2 Port of LPT3
|
;40:000C 2 Port of LPT3
|
;40:000E 2 Port of LPT4
|
;40:000E 2 Port of LPT4
|
;40:0010 2 Equipment/hardware installed/active; see Equipment List
|
;40:0010 2 Equipment/hardware installed/active; see Equipment List
|
;40:0012 1 Errors in PCjr infrared keyboard link
|
;40:0012 1 Errors in PCjr infrared keyboard link
|
;40:0013 2 Total memory in K-bytes (same as obtained via INT 12H)
|
;40:0013 2 Total memory in K-bytes (same as obtained via INT 12H)
|
;40:0015 2 Scratch pad for manufacturing error tests
|
;40:0015 2 Scratch pad for manufacturing error tests
|
;
|
;
|
;40:0017 2 Keyboard status bits; see Keyboard Shift Status Flags
|
;40:0017 2 Keyboard status bits; see Keyboard Shift Status Flags
|
;40:0019 1 Current (accumulating) value of Alt+numpad pseudo-key input;
|
;40:0019 1 Current (accumulating) value of Alt+numpad pseudo-key input;
|
; normally 0. When [Alt] is released, value is stored in
|
; normally 0. When [Alt] is released, value is stored in
|
; keyboard buffer at 001e.
|
; keyboard buffer at 001e.
|
;40:001a 2 Addr of keyboard buffer head (keystroke at that addr is next)
|
;40:001a 2 Addr of keyboard buffer head (keystroke at that addr is next)
|
;40:001c 2 Address of keyboard buffer tail
|
;40:001c 2 Address of keyboard buffer tail
|
;40:001e 32 Keyboard buffer. BIOS stores keystrokes here (head and tail
|
;40:001e 32 Keyboard buffer. BIOS stores keystrokes here (head and tail
|
; point to addresses from 041eH to 043dH inclusive).
|
; point to addresses from 041eH to 043dH inclusive).
|
;
|
;
|
;40:003e 1 Diskette drive needs recalibration (bit 0=A, bit 1=B, etc.)
|
;40:003e 1 Diskette drive needs recalibration (bit 0=A, bit 1=B, etc.)
|
; bits 4-5 indicate which drive is currently selected
|
; bits 4-5 indicate which drive is currently selected
|
;40:003f 1 Diskette motor is running (bit 0=drive A, bit 1=B, etc.)
|
;40:003f 1 Diskette motor is running (bit 0=drive A, bit 1=B, etc.)
|
;40:0040 1 Time until motor off. INT 08H turns motor off when this is 0.
|
;40:0040 1 Time until motor off. INT 08H turns motor off when this is 0.
|
;40:0041 1 Diskette error status; same as status returned by INT 13H
|
;40:0041 1 Diskette error status; same as status returned by INT 13H
|
;40:0042 7 Diskette controller status information area
|
;40:0042 7 Diskette controller status information area
|
;
|
;
|
;40:0049 1 Current active video mode. See Video Modes and INT 10H.
|
;40:0049 1 Current active video mode. See Video Modes and INT 10H.
|
;40:004a 2 Screen width in text columns
|
;40:004a 2 Screen width in text columns
|
;40:004c 2 Length (in bytes) of video area (regen size)
|
;40:004c 2 Length (in bytes) of video area (regen size)
|
;40:004e 2 Offset from video segment of active video memory page
|
;40:004e 2 Offset from video segment of active video memory page
|
;40:0050 16 Cursor location (8 byte-pairs; low byte=clm, hi byte=row)
|
;40:0050 16 Cursor location (8 byte-pairs; low byte=clm, hi byte=row)
|
;40:0060 2 Cursor size/shape. Low byte=end scan line; hi byte=start line.
|
;40:0060 2 Cursor size/shape. Low byte=end scan line; hi byte=start line.
|
;40:0062 1 Current active video page number
|
;40:0062 1 Current active video page number
|
;40:0063 2 Port address for 6845 video controller chip; see CGA I/O Ports
|
;40:0063 2 Port address for 6845 video controller chip; see CGA I/O Ports
|
;40:0065 1 Current value of 6845 video ctrlr CRT_MODE (port 3x8H register)
|
;40:0065 1 Current value of 6845 video ctrlr CRT_MODE (port 3x8H register)
|
;40:0066 1 Current value of 6845 video ctrlr CRT_PALETTE (port 3x9H reg)
|
;40:0066 1 Current value of 6845 video ctrlr CRT_PALETTE (port 3x9H reg)
|
;
|
;
|
;40:0067 5 Cassette data area or POST data area
|
;40:0067 5 Cassette data area or POST data area
|
; 40:0067: 1 byte mouse buffer counter (DataCounter)
|
; 40:0067: 1 byte mouse buffer counter (DataCounter)
|
; 40:0068: 1 byte mouse packet size (PacketSize): 0 for 3 bytes, 1 for 4 bytes (Intellimouse)
|
; 40:0068: 1 byte mouse packet size (PacketSize): 0 for 3 bytes, 1 for 4 bytes (Intellimouse)
|
; 40:0069: 1 byte palette paging status
|
; 40:0069: 1 byte palette paging status
|
; 40:006a: 1 byte PalPagingCounter - guards pal paging re-entrance
|
; 40:006a: 1 byte PalPagingCounter - guards pal paging re-entrance
|
;
|
;
|
;40:006c 4 Timer tick counter (count of 55ms ticks since CPU reset)
|
;40:006c 4 Timer tick counter (count of 55ms ticks since CPU reset)
|
;40:0070 1 Timer overflow flag (timer has rolled over 24 hr)
|
;40:0070 1 Timer overflow flag (timer has rolled over 24 hr)
|
;40:0071 1 Ctrl-Break flag. Bit 7=1 when break was pressed. This never
|
;40:0071 1 Ctrl-Break flag. Bit 7=1 when break was pressed. This never
|
; gets reset unless you do it yourself.
|
; gets reset unless you do it yourself.
|
;
|
;
|
;40:0072 2 1234H means Ctrl+Alt+Del reboot is in progress. BIOS checks
|
;40:0072 2 1234H means Ctrl+Alt+Del reboot is in progress. BIOS checks
|
; this to avoid doing a "cold boot" with the time-consuming POST
|
; this to avoid doing a "cold boot" with the time-consuming POST
|
; 4321H means reset, preserving memory
|
; 4321H means reset, preserving memory
|
; 5678H, 9abcH, and abcdH (are internal PC Convertible codes)
|
; 5678H, 9abcH, and abcdH (are internal PC Convertible codes)
|
;
|
;
|
;40:0074 4 PCjr diskette or AT hard disk control area
|
;40:0074 4 PCjr diskette or AT hard disk control area
|
; (0074) 1 Status of last fixed-disk drive operation
|
; (0074) 1 Status of last fixed-disk drive operation
|
; (0075) 1 Number of hard disk drives for AT
|
; (0075) 1 Number of hard disk drives for AT
|
; (0077) 1 Hard disk port for XT. See XT Hard Disk Ports.
|
; (0077) 1 Hard disk port for XT. See XT Hard Disk Ports.
|
;40:0078 4 Printer time-out values (478H=Lpt1, 478H=Lpt2...)
|
;40:0078 4 Printer time-out values (478H=Lpt1, 478H=Lpt2...)
|
;40:007c 4 RS-232 time-out values (47cH=Com1, 47dH=Com2...)
|
;40:007c 4 RS-232 time-out values (47cH=Com1, 47dH=Com2...)
|
;
|
;
|
;40:0080 2 AT PS/2 keyboard buffer offset start address (usually 01eH)
|
;40:0080 2 AT PS/2 keyboard buffer offset start address (usually 01eH)
|
;40:0082 2 end address (usually 003eH)
|
;40:0082 2 end address (usually 003eH)
|
;
|
;
|
;40:0084 1 EGA text rows-1 (maximum valid row value)
|
;40:0084 1 EGA text rows-1 (maximum valid row value)
|
;40:0085 2 EGA bytes per character (scan-lines/char used in active mode)
|
;40:0085 2 EGA bytes per character (scan-lines/char used in active mode)
|
;40:0087 1 EGA flags; see EgaMiscInfoRec
|
;40:0087 1 EGA flags; see EgaMiscInfoRec
|
;40:0088 1 EGA flags; see EgaMiscInfo2Rec
|
;40:0088 1 EGA flags; see EgaMiscInfo2Rec
|
;40:0089 1 VGA flags; see VgaFlagsRec
|
;40:0089 1 VGA flags; see VgaFlagsRec
|
; See also: EGA/VGA Data Areas
|
; See also: EGA/VGA Data Areas
|
;
|
;
|
;40:008b 1 AT PS/2 Media control: data rate, step rate
|
;40:008b 1 AT PS/2 Media control: data rate, step rate
|
;40:008c 1 AT PS/2 Hard disk drive controller status
|
;40:008c 1 AT PS/2 Hard disk drive controller status
|
;40:008d 1 AT PS/2 Hard disk drive error status
|
;40:008d 1 AT PS/2 Hard disk drive error status
|
;40:008e 1 AT PS/2 Hard disk drive interrupt control
|
;40:008e 1 AT PS/2 Hard disk drive interrupt control
|
;
|
;
|
;40:0090 1 AT PS/2 Disk media state bits for drive 0
|
;40:0090 1 AT PS/2 Disk media state bits for drive 0
|
;40:0091 1 for drive 1
|
;40:0091 1 for drive 1
|
;40:0092 1 AT PS/2 Disk operation started flag for drive 0
|
;40:0092 1 AT PS/2 Disk operation started flag for drive 0
|
;40:0093 1 for drive 1
|
;40:0093 1 for drive 1
|
|
|
;40:0094 1 AT PS/2 Present cylinder number for drive 0
|
;40:0094 1 AT PS/2 Present cylinder number for drive 0
|
;40:0095 1 for drive 1
|
;40:0095 1 for drive 1
|
; 2 - Number of 512bytes sectors of HD0
|
; 2 - Number of 512bytes sectors of HD0
|
;
|
;
|
;40:0096 1 AT Keyboard flag bit 4=1 (10H) if 101-key keyboard is attached
|
;40:0096 1 AT Keyboard flag bit 4=1 (10H) if 101-key keyboard is attached
|
;40:0097 1 AT Keyboard flag for LED 'key lock' display
|
;40:0097 1 AT Keyboard flag for LED 'key lock' display
|
; bits 0-2 are ScrollLock, NumLock, CapsLock
|
; bits 0-2 are ScrollLock, NumLock, CapsLock
|
;
|
;
|
;40:0098 4 AT Pointer to 8-bit user wait flag; see INT 15H 86H
|
;40:0098 4 AT Pointer to 8-bit user wait flag; see INT 15H 86H
|
;40:009c 4 AT Microseconds before user wait is done
|
;40:009c 4 AT Microseconds before user wait is done
|
;40:00a0 1 AT User wait activity flag:
|
;40:00a0 1 AT User wait activity flag:
|
; 01H=busy, 80H=posted, 00H=acknowledged
|
; 01H=busy, 80H=posted, 00H=acknowledged
|
;
|
;
|
;40:00a1 7 AT Reserved for network adapters
|
;40:00a1 7 AT Reserved for network adapters
|
; 40:00a1: 4 bytes far pointer to mouse callback (HandlerPtr)
|
; 40:00a1: 4 bytes far pointer to mouse callback (HandlerPtr)
|
; 40:00a5: 3 bytes mouse buffer (DataBuffer)
|
; 40:00a5: 3 bytes mouse buffer (DataBuffer)
|
;
|
;
|
;40:00a8 4 EGA Address of table of pointers; see EgaSavePtrRec
|
;40:00a8 4 EGA Address of table of pointers; see EgaSavePtrRec
|
;40:00ac 68 Reserved
|
;40:00ac 68 Reserved
|
;40:00f0 16 (IAC) Inter-Aapplication Communication area. Programs may use
|
;40:00f0 16 (IAC) Inter-Aapplication Communication area. Programs may use
|
; this area to store status, etc. Might get overwritten by
|
; this area to store status, etc. Might get overwritten by
|
; another program.
|
; another program.
|
|
|
; http://www.ctyme.com/intr/int.htm
|
; http://www.ctyme.com/intr/int.htm
|
|
|
; video memory: 8 physical segments at 0a000h, 0b000h, 0c000h, 0d000h, 0e000h, 0f000h, 10000h, 11000h
|
; video memory: 8 physical segments at 0a000h, 0b000h, 0c000h, 0d000h, 0e000h, 0f000h, 10000h, 11000h
|
; Memory segments mapping
|
; Memory segments mapping
|
; 1Mb virtual seg address physical seg address
|
; 1Mb virtual seg address physical seg address
|
; 0000h 0000h
|
; 0000h 0000h
|
; 1000h 1000h
|
; 1000h 1000h
|
; 2000h 2000h
|
; 2000h 2000h
|
; 3000h 3000h
|
; 3000h 3000h
|
; 4000h 4000h
|
; 4000h 4000h
|
; 5000h 5000h
|
; 5000h 5000h
|
; 6000h 6000h
|
; 6000h 6000h
|
; 7000h 7000h
|
; 7000h 7000h
|
; 8000h 8000h
|
; 8000h 8000h
|
; 9000h 9000h
|
; 9000h 9000h
|
; a000h a000h - video
|
; a000h a000h - video
|
; b000h b000h - video
|
; b000h b000h - video
|
; c000h 12000h
|
; c000h 12000h
|
; d000h 13000h
|
; d000h 13000h
|
; e000h 14000h
|
; e000h 14000h
|
; f000h 15000h
|
; f000h 15000h
|
|
|
|
|
org 0e000h
|
org 0e000h
|
bios:
|
bios:
|
biosmsg db 'Next186 Spartan3AN SoC PC BIOS (C) 2013 Nicolae Dumitrache', 0
|
biosmsg db 'Next186 Spartan3AN SoC PC BIOS (C) 2013 Nicolae Dumitrache', 0
|
msgmb db 'MB SD Card', 13, 10, 0
|
msgmb db 'MB SD Card', 13, 10, 0
|
msgkb db 'PS2 KB detected', 13, 10, 0
|
msgkb db 'PS2 KB detected', 13, 10, 0
|
|
|
|
|
; Graphics character set
|
; Graphics character set
|
font8x8: ; TODO define and place font
|
font8x8: ; TODO define and place font
|
font8x16: ; TODO define and place font
|
font8x16: ; TODO define and place font
|
|
|
org 0e05bh
|
org 0e05bh
|
coldboot:
|
coldboot:
|
warmboot:
|
warmboot:
|
cli
|
cli
|
cld
|
cld
|
mov ax, 30h
|
mov ax, 30h
|
mov ss, ax
|
mov ss, ax
|
mov sp, 100h
|
mov sp, 100h
|
|
|
push 0
|
push 0
|
popf
|
popf
|
|
|
mov al, 36h
|
mov al, 36h
|
out 43h, al
|
out 43h, al
|
xor ax, ax
|
xor ax, ax
|
out 40h, al
|
out 40h, al
|
out 40h, al ; 18Hz PIT CH0
|
out 40h, al ; 18Hz PIT CH0
|
out 61h, al ; speaker off
|
out 61h, al ; speaker off
|
not al
|
not al
|
out 21h, al ; disable all interrupts
|
out 21h, al ; disable all interrupts
|
|
|
|
|
; ------------------ MAP init
|
; ------------------ MAP init
|
call flush
|
call flush
|
mov ax, 15h ; BIOS physical segment 15h mapped on virtual segment 0ch
|
mov ax, 15h ; BIOS physical segment 15h mapped on virtual segment 0ch
|
out 8ch, ax
|
out 8ch, ax
|
push 0c000h
|
push 0c000h
|
pop es
|
pop es
|
push 0f000h
|
push 0f000h
|
pop ds
|
pop ds
|
xor si, si
|
xor si, si
|
xor di, di
|
xor di, di
|
mov cx, 8000h
|
mov cx, 8000h
|
rep movsw ; copy BIOS virtual segment 0fh over physical segment 15h
|
rep movsw ; copy BIOS virtual segment 0fh over physical segment 15h
|
|
|
call flush
|
call flush
|
mov dx, 80h
|
mov dx, 80h
|
xor ax, ax
|
xor ax, ax
|
mapi:
|
mapi:
|
out dx, ax
|
out dx, ax
|
inc ax
|
inc ax
|
inc dx
|
inc dx
|
cmp al, 0ch
|
cmp al, 0ch
|
jne short mapi1
|
jne short mapi1
|
add al, 6
|
add al, 6
|
mapi1:
|
mapi1:
|
cmp al, 16h
|
cmp al, 16h
|
jne short mapi
|
jne short mapi
|
|
|
; -------------------- Interrupt table init
|
; -------------------- Interrupt table init
|
push 0
|
push 0
|
pop ds
|
pop ds
|
push ds
|
push ds
|
pop es
|
pop es
|
xor si, si
|
xor si, si
|
mov di, 4
|
mov di, 4
|
mov word ptr [si], offset defint
|
mov word ptr [si], offset defint
|
mov word ptr [si+2], cs
|
mov word ptr [si+2], cs
|
mov cx, 256-2
|
mov cx, 256-2
|
rep movsw
|
rep movsw
|
mov word ptr ds:[7*4], offset int07
|
mov word ptr ds:[7*4], offset int07
|
mov word ptr ds:[8*4], offset int08
|
mov word ptr ds:[8*4], offset int08
|
mov word ptr ds:[9*4], offset int09
|
mov word ptr ds:[9*4], offset int09
|
mov word ptr ds:[10h*4], offset int10
|
mov word ptr ds:[10h*4], offset int10
|
mov word ptr ds:[11h*4], offset int11
|
mov word ptr ds:[11h*4], offset int11
|
mov word ptr ds:[12h*4], offset int12
|
mov word ptr ds:[12h*4], offset int12
|
mov word ptr ds:[13h*4], offset int13
|
mov word ptr ds:[13h*4], offset int13
|
mov word ptr ds:[15h*4], offset int15
|
mov word ptr ds:[15h*4], offset int15
|
mov word ptr ds:[16h*4], offset int16
|
mov word ptr ds:[16h*4], offset int16
|
mov word ptr ds:[18h*4], offset int18
|
mov word ptr ds:[18h*4], offset int18
|
mov word ptr ds:[19h*4], offset int19
|
mov word ptr ds:[19h*4], offset int19
|
mov word ptr ds:[1ah*4], offset int1a
|
mov word ptr ds:[1ah*4], offset int1a
|
mov word ptr ds:[70h*4], offset int70
|
mov word ptr ds:[70h*4], offset int70
|
mov word ptr ds:[74h*4], offset int74
|
mov word ptr ds:[74h*4], offset int74
|
|
|
; ------------------- BDA init
|
; ------------------- BDA init
|
push 40h
|
push 40h
|
pop ds
|
pop ds
|
push ds
|
push ds
|
pop es
|
pop es
|
xor di, di
|
xor di, di
|
xor si, si
|
xor si, si
|
xor ax, ax
|
xor ax, ax
|
mov cl, 80h
|
mov cl, 80h
|
rep stosw
|
rep stosw
|
mov byte ptr [si+10h], 24h ; equipment word (color 80x25, PS2 mouse present)
|
mov byte ptr [si+10h], 24h ; equipment word (color 80x25, PS2 mouse present)
|
mov word ptr [si+13h], 640 ; memory size in KB
|
mov word ptr [si+13h], 640 ; memory size in KB
|
add word ptr [si+1ah], 1eh ; next char pointer in kb buffer
|
add word ptr [si+1ah], 1eh ; next char pointer in kb buffer
|
add word ptr [si+1ch], 1eh ; last char pointer in kb buffer
|
add word ptr [si+1ch], 1eh ; last char pointer in kb buffer
|
mov word ptr [si+60h], 0e0fh ; cursor shape
|
mov word ptr [si+60h], 0e0fh ; cursor shape
|
mov word ptr [si+63h], 3d4h ; video port address
|
mov word ptr [si+63h], 3d4h ; video port address
|
add word ptr [si+80h], 1eh ; start kb buffer
|
add word ptr [si+80h], 1eh ; start kb buffer
|
add word ptr [si+82h], 3eh ; end kb buffer
|
add word ptr [si+82h], 3eh ; end kb buffer
|
mov word ptr [si+87h], 0940h ; video adapter options (512Kb video)
|
mov word ptr [si+87h], 0940h ; video adapter options (512Kb video)
|
mov word ptr [si+89h], 0b71h ; VGA video flags: 400 line text mode, default palette loading on (0), blinking on
|
mov word ptr [si+89h], 0b71h ; VGA video flags: 400 line text mode, default palette loading on (0), blinking on
|
mov byte ptr [si+96h], 10h ; 101 keyboard installed
|
mov byte ptr [si+96h], 10h ; 101 keyboard installed
|
|
|
; ------------------- Graph mode init
|
; ------------------- Graph mode init
|
mov ax, 3
|
mov ax, 3
|
int 10h
|
int 10h
|
|
|
; ------------------- KB init ----------------
|
; ------------------- KB init ----------------
|
mov al, 0aeh
|
mov al, 0aeh
|
out 64h, al ; enable kb
|
out 64h, al ; enable kb
|
mov al, 0a7h
|
mov al, 0a7h
|
out 64h, al ; disable mouse
|
out 64h, al ; disable mouse
|
mov cx, 25
|
mov cx, 25
|
kbi1:
|
kbi1:
|
call getps2byte
|
call getps2byte
|
loop short kbi1 ; wait for kb timeout
|
loop short kbi1 ; wait for kb timeout
|
mov ah, 0ffh ; reset kb
|
mov ah, 0ffh ; reset kb
|
clc ; kb command
|
clc ; kb command
|
call sendcmd
|
call sendcmd
|
jc short nokb
|
jc short nokb
|
mov cl, 25
|
mov cl, 25
|
kbi2:
|
kbi2:
|
dec cx
|
dec cx
|
jcxz short nokb
|
jcxz short nokb
|
call getps2byte
|
call getps2byte
|
jc short kbi2 ; wait for BAT
|
jc short kbi2 ; wait for BAT
|
cmp al, 0aah
|
cmp al, 0aah
|
jne short nokb
|
jne short nokb
|
mov ah, 0f2h ; kb id
|
mov ah, 0f2h ; kb id
|
call sendcmd ; CF = 0
|
call sendcmd ; CF = 0
|
jc short nokb
|
jc short nokb
|
call getps2byte
|
call getps2byte
|
cmp al, 0abh
|
cmp al, 0abh
|
jne short nokb
|
jne short nokb
|
call getps2byte
|
call getps2byte
|
cmp al, 83h
|
cmp al, 83h
|
; set scan code 1
|
; set scan code 1
|
IFDEF SCANCODE1
|
IFDEF SCANCODE1
|
jne short nokb
|
jne short nokb
|
mov ah, 0f0h ; kb scan set
|
mov ah, 0f0h ; kb scan set
|
call sendcmd
|
call sendcmd
|
jc short nokb
|
jc short nokb
|
mov ah, 1 ; scan set 1
|
mov ah, 1 ; scan set 1
|
call sendcmd
|
call sendcmd
|
jnc short kbok
|
jnc short kbok
|
ELSE
|
ELSE
|
je short kbok
|
je short kbok
|
ENDIF
|
ENDIF
|
|
|
nokb:
|
nokb:
|
mov byte ptr KbdFlags3, 0 ; kb not present
|
mov byte ptr KbdFlags3, 0 ; kb not present
|
kbok:
|
kbok:
|
mov al, 0adh
|
mov al, 0adh
|
out 64h, al ; disable kb interface
|
out 64h, al ; disable kb interface
|
|
|
; ------------------- Mouse init ----------------
|
; ------------------- Mouse init ----------------
|
mov al, 0a8h
|
mov al, 0a8h
|
out 64h, al ; enable mouse
|
out 64h, al ; enable mouse
|
mousei0:
|
mousei0:
|
call getps2byte
|
call getps2byte
|
jnc short mousei0
|
jnc short mousei0
|
mov ah, 0ffh
|
mov ah, 0ffh
|
call sendcmd ; reset mouse (CF = 1)
|
call sendcmd ; reset mouse (CF = 1)
|
jc short nomouse
|
jc short nomouse
|
mov cl, 25
|
mov cl, 25
|
mousei1:
|
mousei1:
|
dec cx
|
dec cx
|
jcxz short nomouse
|
jcxz short nomouse
|
call getps2byte
|
call getps2byte
|
jc short mousei1
|
jc short mousei1
|
cmp al, 0aah ; BAT
|
cmp al, 0aah ; BAT
|
jne short nomouse
|
jne short nomouse
|
call getps2byte
|
call getps2byte
|
cmp al, 0 ; mouse ID
|
cmp al, 0 ; mouse ID
|
je short mouseok
|
je short mouseok
|
nomouse:
|
nomouse:
|
mov al, 0a7h
|
mov al, 0a7h
|
out 64h, al ; disable mouse
|
out 64h, al ; disable mouse
|
and byte ptr EquipmentWord, not 4 ; ps2 mouse not present in equipement word
|
and byte ptr EquipmentWord, not 4 ; ps2 mouse not present in equipement word
|
mouseok:
|
mouseok:
|
call enableKbIfPresent
|
call enableKbIfPresent
|
|
|
mov al, 20h
|
mov al, 20h
|
out 64h, al
|
out 64h, al
|
in al, 60h
|
in al, 60h
|
or al, 3
|
or al, 3
|
mov ah, al
|
mov ah, al
|
mov al, 60h
|
mov al, 60h
|
out 64h, al
|
out 64h, al
|
mov al, ah
|
mov al, ah
|
out 60h, al ; enable 8042 mouse and kb interrupts
|
out 60h, al ; enable 8042 mouse and kb interrupts
|
|
|
mov ax,1000-1 ; 1ms
|
mov ax,1000-1 ; 1ms
|
out 70h, ax ; set RTC frequency
|
out 70h, ax ; set RTC frequency
|
|
|
mov al, 0e4h
|
mov al, 0e4h
|
out 21h, al ; enable all PIC interrupts (8h, 9h, 70h, 74h)
|
out 21h, al ; enable all PIC interrupts (8h, 9h, 70h, 74h)
|
sti ; enable CPU interrupts
|
sti ; enable CPU interrupts
|
|
|
; --------------------- HDD init
|
; --------------------- HDD init
|
call sdinit
|
call sdinit
|
mov HDSize, ax
|
mov HDSize, ax
|
push cs
|
push cs
|
pop es
|
pop es
|
mov si, offset biosmsg
|
mov si, offset biosmsg
|
call prts
|
call prts
|
mov si, offset bioscont
|
mov si, offset bioscont
|
call prts
|
call prts
|
mov ax, HDSize
|
mov ax, HDSize
|
shr ax, 1
|
shr ax, 1
|
call dispAX
|
call dispAX
|
mov si, offset msgmb
|
mov si, offset msgmb
|
call prts
|
call prts
|
test byte ptr KbdFlags3, 10h
|
test byte ptr KbdFlags3, 10h
|
jz nokbmsg
|
jz nokbmsg
|
mov si, offset msgkb
|
mov si, offset msgkb
|
call prts
|
call prts
|
nokbmsg:
|
nokbmsg:
|
test byte ptr EquipmentWord, 4
|
test byte ptr EquipmentWord, 4
|
jz nomousemsg
|
jz nomousemsg
|
mov si, offset msgmouse
|
mov si, offset msgmouse
|
call prts
|
call prts
|
nomousemsg:
|
nomousemsg:
|
|
|
;-------------- HD bootstrap
|
;-------------- HD bootstrap
|
mov ax, 305h
|
mov ax, 305h
|
xor bx, bx
|
xor bx, bx
|
int 16h ; set typematic rate and delay to fastest
|
int 16h ; set typematic rate and delay to fastest
|
int 19h
|
int 19h
|
|
|
msgmouse db 'PS2 Mouse detected', 13, 10, 0
|
msgmouse db 'PS2 Mouse detected', 13, 10, 0
|
bioscont db 13, 10, 'CPU: 80186 33Mhz (33MIPS, 66Mhz 32bit bus)', 13, 10
|
bioscont db 13, 10, 'CPU: 80186 33Mhz (33MIPS, 66Mhz 32bit bus)', 13, 10
|
db 'RAM: 64MB DDR2 133Mhz', 13, 10
|
db 'RAM: 64MB DDR2 133Mhz', 13, 10
|
db 'Cache: 8x256 bytes data/inst', 13, 10
|
db 'Cache: 8x256 bytes data/inst', 13, 10
|
db 'HD0: ', 0
|
db 'HD0: ', 0
|
|
|
; ---------------------------- INT 07 ---------------------
|
; ---------------------------- INT 07 ---------------------
|
int07 proc near ; coprocessor ESC sequence
|
int07 proc near ; coprocessor ESC sequence
|
push ax
|
push ax
|
push bx
|
push bx
|
push ds
|
push ds
|
push bp
|
push bp
|
mov bp, sp
|
mov bp, sp
|
lds bx, [bp+8]
|
lds bx, [bp+8]
|
int07_pfx:
|
int07_pfx:
|
mov al, [bx]
|
mov al, [bx]
|
inc bx
|
inc bx
|
and al, 0f8h
|
and al, 0f8h
|
cmp al, 0d8h ; ESC code
|
cmp al, 0d8h ; ESC code
|
jne short int07_pfx
|
jne short int07_pfx
|
|
|
cmp byte ptr [bx], 0c0h ; mod reg r/m of ESC 8087 instruction
|
cmp byte ptr [bx], 0c0h ; mod reg r/m of ESC 8087 instruction
|
sbb al, al
|
sbb al, al
|
and al, [bx]
|
and al, [bx]
|
and ax, 0c7h
|
and ax, 0c7h
|
cmp al, 6
|
cmp al, 6
|
jne int072
|
jne int072
|
mov al, 80h
|
mov al, 80h
|
int072:
|
int072:
|
shr al, 6
|
shr al, 6
|
inc ax
|
inc ax
|
add ax, bx
|
add ax, bx
|
mov [bp+8], ax
|
mov [bp+8], ax
|
pop bp
|
pop bp
|
pop ds
|
pop ds
|
pop bx
|
pop bx
|
pop ax
|
pop ax
|
iret
|
iret
|
int07 endp
|
int07 endp
|
|
|
|
|
; ---------------------------- INT 08 ---------------------
|
; ---------------------------- INT 08 ---------------------
|
int08 proc near
|
int08 proc near
|
push ds
|
push ds
|
push bx
|
push bx
|
push 40h
|
push 40h
|
pop ds
|
pop ds
|
mov bx, 6ch
|
mov bx, 6ch
|
add word ptr [bx], 1
|
add word ptr [bx], 1
|
adc word ptr [bx+2], 0
|
adc word ptr [bx+2], 0
|
cmp word ptr [bx+2], 18h
|
cmp word ptr [bx+2], 18h
|
jne short int081
|
jne short int081
|
cmp word ptr [bx], 0b0h
|
cmp word ptr [bx], 0b0h
|
jne short int081
|
jne short int081
|
mov word ptr [bx], 0
|
mov word ptr [bx], 0
|
mov word ptr [bx+2], 0
|
mov word ptr [bx+2], 0
|
mov byte ptr [bx+4], 1
|
mov byte ptr [bx+4], 1
|
int081:
|
int081:
|
int 1ch
|
int 1ch
|
sti
|
sti
|
push ax
|
push ax
|
mov ah, 4
|
mov ah, 4
|
kloop:
|
kloop:
|
in al, 64h
|
in al, 64h
|
test al, 1
|
test al, 1
|
jz short nokey
|
jz short nokey
|
dec ah
|
dec ah
|
jnz short kloop
|
jnz short kloop
|
test al, 20h
|
test al, 20h
|
jz short kbdata
|
jz short kbdata
|
int 74h
|
int 74h
|
jmp short nokey
|
jmp short nokey
|
kbdata:
|
kbdata:
|
int 9h
|
int 9h
|
nokey:
|
nokey:
|
pop ax
|
pop ax
|
pop bx
|
pop bx
|
pop ds
|
pop ds
|
iret
|
iret
|
int08 endp
|
int08 endp
|
|
|
; --------------------- INT 09 - keyboard ------------------
|
; --------------------- INT 09 - keyboard ------------------
|
KbdFlags1 equ
|
KbdFlags1 equ
|
KbdFlags2 equ
|
KbdFlags2 equ
|
AltKpd equ
|
AltKpd equ
|
CtrlBreak equ
|
CtrlBreak equ
|
KbdFlags3 equ
|
KbdFlags3 equ
|
KbdFlags4 equ
|
KbdFlags4 equ
|
|
|
; Bits for the KbdFlags1
|
; Bits for the KbdFlags1
|
RShfDown equ 1
|
RShfDown equ 1
|
LShfDown equ 2
|
LShfDown equ 2
|
CtrlDown equ 4
|
CtrlDown equ 4
|
AltDown equ 8
|
AltDown equ 8
|
ScrLock equ 10h
|
ScrLock equ 10h
|
NumLock equ 20h
|
NumLock equ 20h
|
CapsLock equ 40h
|
CapsLock equ 40h
|
Insert equ 80h
|
Insert equ 80h
|
|
|
; Bits for the KbdFlags2
|
; Bits for the KbdFlags2
|
LCtrDown equ 1
|
LCtrDown equ 1
|
LAltDown equ 2
|
LAltDown equ 2
|
SysReqDown equ 4
|
SysReqDown equ 4
|
Pause equ 8
|
Pause equ 8
|
ScrLockDown equ 10h
|
ScrLockDown equ 10h
|
NumLockDown equ 20h
|
NumLockDown equ 20h
|
CapsLockDown equ 40h
|
CapsLockDown equ 40h
|
InsDown equ 80h
|
InsDown equ 80h
|
|
|
; Bits for the KbdFlags3
|
; Bits for the KbdFlags3
|
LastE1 equ 1
|
LastE1 equ 1
|
LastE0 equ 2
|
LastE0 equ 2
|
RCtrDown equ 4
|
RCtrDown equ 4
|
RAltDown equ 8
|
RAltDown equ 8
|
LastF0 equ 20h
|
LastF0 equ 20h
|
|
|
; Bits for the KbdFlags4
|
; Bits for the KbdFlags4
|
ScrLockLED equ 1
|
ScrLockLED equ 1
|
NumLockLED equ 2
|
NumLockLED equ 2
|
CapsLockLED equ 4
|
CapsLockLED equ 4
|
SetRepeat equ 8 ; Set auto repeat command in progress
|
SetRepeat equ 8 ; Set auto repeat command in progress
|
AckReceived equ 10h
|
AckReceived equ 10h
|
LEDUpdate equ 40h
|
LEDUpdate equ 40h
|
|
|
IFDEF SCANCODE1
|
IFDEF SCANCODE1
|
|
|
int09 proc near
|
int09 proc near
|
pusha
|
pusha
|
push ds
|
push ds
|
push es
|
push es
|
push 40h
|
push 40h
|
pop ds
|
pop ds
|
in al, 60h ; al contains the scan code
|
in al, 60h ; al contains the scan code
|
mov dx, KbdFlags1
|
mov dx, KbdFlags1
|
mov cx, KbdFlags3
|
mov cx, KbdFlags3
|
cmp al, 0fah ; ACK
|
cmp al, 0fah ; ACK
|
jne short noACK
|
jne short noACK
|
; ------------ manage ACK response
|
; ------------ manage ACK response
|
test ch, LEDUpdate
|
test ch, LEDUpdate
|
jz short ToggleACK ; no LED update
|
jz short ToggleACK ; no LED update
|
test ch, AckReceived
|
test ch, AckReceived
|
jnz short SecondACK ; second ACK received
|
jnz short SecondACK ; second ACK received
|
mov ah, ch ; LED update command sent, ACK received, need to send second byte
|
mov ah, ch ; LED update command sent, ACK received, need to send second byte
|
and ah, ScrLockLED or NumLockLED or CapsLockLED
|
and ah, ScrLockLED or NumLockLED or CapsLockLED
|
mov bl, 0
|
mov bl, 0
|
call sendps2byte
|
call sendps2byte
|
jmp short ToggleACK
|
jmp short ToggleACK
|
SecondACK:
|
SecondACK:
|
xor ch, LEDUpdate ; second ACK, clear LED update bit
|
xor ch, LEDUpdate ; second ACK, clear LED update bit
|
ToggleACK:
|
ToggleACK:
|
xor ch, AckReceived ; toggle ACK bit
|
xor ch, AckReceived ; toggle ACK bit
|
SetFlags1:
|
SetFlags1:
|
jmp SetFlags
|
jmp SetFlags
|
|
|
; ------------ no ACK
|
; ------------ no ACK
|
noACK:
|
noACK:
|
mov ah,4fh
|
mov ah,4fh
|
stc
|
stc
|
int 15h
|
int 15h
|
jnc int09Exit
|
jnc int09Exit
|
cmp al, 0e0h
|
cmp al, 0e0h
|
jne short noE0
|
jne short noE0
|
or cl, LastE0
|
or cl, LastE0
|
jmp short SetFlags1
|
jmp short SetFlags1
|
noE0:
|
noE0:
|
cmp al, 0e1h
|
cmp al, 0e1h
|
jne short noE1
|
jne short noE1
|
or cl, LastE1
|
or cl, LastE1
|
jmp short SetFlags1
|
jmp short SetFlags1
|
noE1:
|
noE1:
|
cmp al, 53h ; is DEL?
|
cmp al, 53h ; is DEL?
|
jne short noDEL
|
jne short noDEL
|
mov ah, dl
|
mov ah, dl
|
and ah, CtrlDown or AltDown
|
and ah, CtrlDown or AltDown
|
cmp ah, CtrlDown or AltDown
|
cmp ah, CtrlDown or AltDown
|
jne NormalKey ; is DEL, but no CTRL+ALt+DEL
|
jne NormalKey ; is DEL, but no CTRL+ALt+DEL
|
mov word ptr ds:[72h], 1234h ; warm boot flag
|
mov word ptr ds:[72h], 1234h ; warm boot flag
|
db 0eah
|
db 0eah
|
dw 0, 0ffffh ; reboot
|
dw 0, 0ffffh ; reboot
|
noDEL:
|
noDEL:
|
test cl, LastE0
|
test cl, LastE0
|
jnz short noRSUp ; ignore fake shifts
|
jnz short noRSUp ; ignore fake shifts
|
cmp al, 2ah ; left shift
|
cmp al, 2ah ; left shift
|
jne short noLSDown
|
jne short noLSDown
|
or dl, LShfDown
|
or dl, LShfDown
|
jmp short SetFlagsKey2
|
jmp short SetFlagsKey2
|
noLSDown:
|
noLSDown:
|
cmp al, 2ah or 80h
|
cmp al, 2ah or 80h
|
jne short noLSUp
|
jne short noLSUp
|
and dl, not LShfDown
|
and dl, not LShfDown
|
jmp short SetFlagsKey2
|
jmp short SetFlagsKey2
|
noLSUp:
|
noLSUp:
|
cmp al, 36h ; right shift
|
cmp al, 36h ; right shift
|
jne short noRSDown
|
jne short noRSDown
|
or dl, RShfDown
|
or dl, RShfDown
|
jmp short SetFlagsKey2
|
jmp short SetFlagsKey2
|
noRSDown:
|
noRSDown:
|
cmp al, 36h or 80h
|
cmp al, 36h or 80h
|
jne short noRSUP
|
jne short noRSUP
|
and dl, not RShfDown
|
and dl, not RShfDown
|
jmp short SetFlagsKey2
|
jmp short SetFlagsKey2
|
noRSUp:
|
noRSUp:
|
cmp al, 38h ; ALT
|
cmp al, 38h ; ALT
|
jne short noALTDown
|
jne short noALTDown
|
test cl, LastE0
|
test cl, LastE0
|
jz short LALTDn
|
jz short LALTDn
|
or cl, RAltDown
|
or cl, RAltDown
|
or dl, AltDown
|
or dl, AltDown
|
jmp short SetFlagsKey2
|
jmp short SetFlagsKey2
|
LALTDn:
|
LALTDn:
|
or dx, (LAltDown shl 8) or AltDown
|
or dx, (LAltDown shl 8) or AltDown
|
jmp short SetFlagsKey2
|
jmp short SetFlagsKey2
|
noALTDown:
|
noALTDown:
|
cmp al, 38h or 80h
|
cmp al, 38h or 80h
|
jne short noALTUp
|
jne short noALTUp
|
test cl, LastE0
|
test cl, LastE0
|
jz short LALTUp
|
jz short LALTUp
|
and cl, not RAltDown
|
and cl, not RAltDown
|
and dl, not AltDown
|
and dl, not AltDown
|
jmp short ALTup
|
jmp short ALTup
|
LALTUp:
|
LALTUp:
|
and dx, not ((LAltDown shl 8) or AltDown)
|
and dx, not ((LAltDown shl 8) or AltDown)
|
ALTUp:
|
ALTUp:
|
xor ax, ax
|
xor ax, ax
|
xchg al, AltKpd
|
xchg al, AltKpd
|
test al, al
|
test al, al
|
jz short SetFlagsKey2
|
jz short SetFlagsKey2
|
jmp pushKey
|
jmp pushKey
|
noALTUp:
|
noALTUp:
|
cmp al, 1dh ; CTL
|
cmp al, 1dh ; CTL
|
jne short noCTLDown
|
jne short noCTLDown
|
test cl, lastE0
|
test cl, lastE0
|
jz short LCTLDn
|
jz short LCTLDn
|
or cl, RCtrDown
|
or cl, RCtrDown
|
or dl, CtrlDown
|
or dl, CtrlDown
|
SetFlagsKey2:
|
SetFlagsKey2:
|
jmp short SetFlagsKey1
|
jmp short SetFlagsKey1
|
LCTLDn:
|
LCTLDn:
|
or dx, (LCtrDown shl 8) or CtrlDown
|
or dx, (LCtrDown shl 8) or CtrlDown
|
jmp short SetFlagsKey1
|
jmp short SetFlagsKey1
|
noCTLDown:
|
noCTLDown:
|
cmp al, 1dh or 80h
|
cmp al, 1dh or 80h
|
jne short noCTLUp
|
jne short noCTLUp
|
test cl, LastE0
|
test cl, LastE0
|
jz short LCTLUp
|
jz short LCTLUp
|
and cl, not RCtrDown
|
and cl, not RCtrDown
|
and dl, not CtrlDown
|
and dl, not CtrlDown
|
jmp short SetFlagsKey1
|
jmp short SetFlagsKey1
|
LCTLUp:
|
LCTLUp:
|
and dx, not ((LCtrDown shl 8) or CtrlDown)
|
and dx, not ((LCtrDown shl 8) or CtrlDown)
|
jmp short SetFlagsKey1
|
jmp short SetFlagsKey1
|
noCTLUp:
|
noCTLUp:
|
mov bx, 3a00h + CapsLock
|
mov bx, 3a00h + CapsLock
|
call KeyLock
|
call KeyLock
|
jnc short SetFlagsKey1
|
jnc short SetFlagsKey1
|
|
|
mov bx, 4600h + ScrLock
|
mov bx, 4600h + ScrLock
|
push dx ; save ScrLock state bit (dl)
|
push dx ; save ScrLock state bit (dl)
|
call KeyLock
|
call KeyLock
|
pop bx ; restore ScrLock state bit (bl)
|
pop bx ; restore ScrLock state bit (bl)
|
jc short noScrLock
|
jc short noScrLock
|
test dl, CtrlDown
|
test dl, CtrlDown
|
jz short SetFlagsKey1; no break, just ScollLock
|
jz short SetFlagsKey1; no break, just ScollLock
|
mov dl, bl ; restore ScrLock flag
|
mov dl, bl ; restore ScrLock flag
|
test bh, ScrLockDown
|
test bh, ScrLockDown
|
jnz short SetFlagsKey1
|
jnz short SetFlagsKey1
|
mov byte ptr CtrlBreak, 80h ; CTRL+BREAK flag
|
mov byte ptr CtrlBreak, 80h ; CTRL+BREAK flag
|
mov ax, Buffer
|
mov ax, Buffer
|
mov HeadPtr, ax
|
mov HeadPtr, ax
|
mov TailPtr, ax
|
mov TailPtr, ax
|
int 1bh
|
int 1bh
|
xor ax, ax
|
xor ax, ax
|
jmp pushkey
|
jmp pushkey
|
noScrLock:
|
noScrLock:
|
test cl, LastE0 ; INS
|
test cl, LastE0 ; INS
|
jnz short testINS
|
jnz short testINS
|
test dl, RShfDown or LShfDown
|
test dl, RShfDown or LShfDown
|
jnz short testINS
|
jnz short testINS
|
test dl, NumLock
|
test dl, NumLock
|
jnz short NoIns
|
jnz short NoIns
|
testINS:
|
testINS:
|
mov bx, 5200h + Insert
|
mov bx, 5200h + Insert
|
call KeyLock
|
call KeyLock
|
noIns:
|
noIns:
|
mov bx, 4500h + NumLock
|
mov bx, 4500h + NumLock
|
push dx ; save NumLock state bit (dl)
|
push dx ; save NumLock state bit (dl)
|
call KeyLock
|
call KeyLock
|
pop bx ; restore NumLock state bit (bl)
|
pop bx ; restore NumLock state bit (bl)
|
jc short NormalKey ; CTRL+NumLock = Pause
|
jc short NormalKey ; CTRL+NumLock = Pause
|
test dl, CtrlDown
|
test dl, CtrlDown
|
jz short SetFlagsKey1
|
jz short SetFlagsKey1
|
mov dl, bl ; restore NumLock flag
|
mov dl, bl ; restore NumLock flag
|
or dh, Pause ; set Pause bit
|
or dh, Pause ; set Pause bit
|
SetFlagsKey1:
|
SetFlagsKey1:
|
jmp SetFlagsKey
|
jmp SetFlagsKey
|
E0Key:
|
E0Key:
|
mov di, offset E0KeyList
|
mov di, offset E0KeyList
|
push cx
|
push cx
|
mov cx, E0KeyIndex - E0KeyList
|
mov cx, E0KeyIndex - E0KeyList
|
cld
|
cld
|
push cs
|
push cs
|
pop es
|
pop es
|
repne scasb
|
repne scasb
|
pop cx
|
pop cx
|
jne short SetFlagsKey
|
jne short SetFlagsKey
|
mov al, es:[di + E0KeyIndex - E0KeyList - 1]
|
mov al, es:[di + E0KeyIndex - E0KeyList - 1]
|
jmp short KeyDown
|
jmp short KeyDown
|
NormalKey:
|
NormalKey:
|
test al, 80h
|
test al, 80h
|
jnz short SetFlagsKey ; key up
|
jnz short SetFlagsKey ; key up
|
test cl, LastE0
|
test cl, LastE0
|
jnz short E0Key
|
jnz short E0Key
|
cmp al, 59h
|
cmp al, 59h
|
sbb ah, ah
|
sbb ah, ah
|
and al, ah
|
and al, ah
|
mov bx, offset KeyIndex
|
mov bx, offset KeyIndex
|
xlat cs:[bx]
|
xlat cs:[bx]
|
KeyDown:
|
KeyDown:
|
xor bx, bx
|
xor bx, bx
|
test dl, RShfDown or LShfDown
|
test dl, RShfDown or LShfDown
|
jz short noShift
|
jz short noShift
|
mov bl, 2
|
mov bl, 2
|
noShift:
|
noShift:
|
cmp al, 26
|
cmp al, 26
|
ja short noCaps
|
ja short noCaps
|
test dl, CapsLock
|
test dl, CapsLock
|
jz short noNum
|
jz short noNum
|
xor bl, 2
|
xor bl, 2
|
jmp short noNum
|
jmp short noNum
|
noCaps:
|
noCaps:
|
cmp al, 37
|
cmp al, 37
|
ja short noNum
|
ja short noNum
|
test dl, NumLock
|
test dl, NumLock
|
jnz short NumDown
|
jnz short NumDown
|
mov bl, 2
|
mov bl, 2
|
NumDown:
|
NumDown:
|
xor bl, 2
|
xor bl, 2
|
noNum:
|
noNum:
|
test dl, CtrlDown
|
test dl, CtrlDown
|
jz short noCtrl
|
jz short noCtrl
|
mov bl, 4
|
mov bl, 4
|
noCtrl:
|
noCtrl:
|
test dl, AltDown
|
test dl, AltDown
|
jz short noAlt
|
jz short noAlt
|
mov bl, 6
|
mov bl, 6
|
noAlt:
|
noAlt:
|
cbw
|
cbw
|
shl ax, 3
|
shl ax, 3
|
add bx, ax
|
add bx, ax
|
mov ax, cs:KeyCode[bx]
|
mov ax, cs:KeyCode[bx]
|
cmp ax, 000ah
|
cmp ax, 000ah
|
ja short pushKey
|
ja short pushKey
|
dec ax
|
dec ax
|
js short SetFlagsKey ; ax was 0
|
js short SetFlagsKey ; ax was 0
|
mov ah, AltKpd
|
mov ah, AltKpd
|
aad
|
aad
|
mov AltKpd, al
|
mov AltKpd, al
|
jmp short SetFlagsKey
|
jmp short SetFlagsKey
|
pushKey:
|
pushKey:
|
push cx
|
push cx
|
mov cx, ax
|
mov cx, ax
|
mov ah, 5
|
mov ah, 5
|
int 16h
|
int 16h
|
pop cx
|
pop cx
|
and dh, not Pause ; clear Pause bit
|
and dh, not Pause ; clear Pause bit
|
SetFlagsKey:
|
SetFlagsKey:
|
and cl, not (LastE0 or LastE1) ; not prefix key code, clear all prefixes
|
and cl, not (LastE0 or LastE1) ; not prefix key code, clear all prefixes
|
SetFlags:
|
SetFlags:
|
mov al, dl
|
mov al, dl
|
shr al, 4
|
shr al, 4
|
xor al, ch
|
xor al, ch
|
and al, 7
|
and al, 7
|
jz short SF1 ; no LEDs to update
|
jz short SF1 ; no LEDs to update
|
test ch, SetRepeat or AckReceived or LEDUpdate
|
test ch, SetRepeat or AckReceived or LEDUpdate
|
jnz short SF1 ; can not update LEDS, so just write the flags and exit
|
jnz short SF1 ; can not update LEDS, so just write the flags and exit
|
or al, LEDUpdate
|
or al, LEDUpdate
|
xor ch, al ; insert the LEDs in KbdFlags4
|
xor ch, al ; insert the LEDs in KbdFlags4
|
mov ah, 0edh ; set LED
|
mov ah, 0edh ; set LED
|
mov bl, 0
|
mov bl, 0
|
call sendps2byte
|
call sendps2byte
|
SF1:
|
SF1:
|
mov KbdFlags1, dx
|
mov KbdFlags1, dx
|
mov KbdFlags3, cx
|
mov KbdFlags3, cx
|
|
|
int09Exit:
|
int09Exit:
|
pop es
|
pop es
|
pop ds
|
pop ds
|
popa
|
popa
|
iret
|
iret
|
int09 endp
|
int09 endp
|
|
|
ELSE ; SCANCODE2
|
ELSE ; SCANCODE2
|
|
|
int09 proc near
|
int09 proc near
|
pusha
|
pusha
|
push ds
|
push ds
|
push es
|
push es
|
push 40h
|
push 40h
|
pop ds
|
pop ds
|
in al, 60h ; al contains the scan code
|
in al, 60h ; al contains the scan code
|
mov dx, KbdFlags1
|
mov dx, KbdFlags1
|
mov cx, KbdFlags3
|
mov cx, KbdFlags3
|
cmp al, 0fah ; ACK
|
cmp al, 0fah ; ACK
|
jne short noACK
|
jne short noACK
|
; ------------ manage ACK response
|
; ------------ manage ACK response
|
test ch, LEDUpdate
|
test ch, LEDUpdate
|
jz short ToggleACK ; no LED update
|
jz short ToggleACK ; no LED update
|
test ch, AckReceived
|
test ch, AckReceived
|
jnz short SecondACK ; second ACK received
|
jnz short SecondACK ; second ACK received
|
mov ah, ch ; LED update command sent, ACK received, need to send second byte
|
mov ah, ch ; LED update command sent, ACK received, need to send second byte
|
and ah, ScrLockLED or NumLockLED or CapsLockLED
|
and ah, ScrLockLED or NumLockLED or CapsLockLED
|
mov bl, 0
|
mov bl, 0
|
call sendps2byte
|
call sendps2byte
|
jmp short ToggleACK
|
jmp short ToggleACK
|
SecondACK:
|
SecondACK:
|
xor ch, LEDUpdate ; second ACK, clear LED update bit
|
xor ch, LEDUpdate ; second ACK, clear LED update bit
|
ToggleACK:
|
ToggleACK:
|
xor ch, AckReceived ; toggle ACK bit
|
xor ch, AckReceived ; toggle ACK bit
|
SetFlags1:
|
SetFlags1:
|
jmp SetFlags
|
jmp SetFlags
|
|
|
; ------------ no ACK
|
; ------------ no ACK
|
noACK:
|
noACK:
|
cmp al, 0e0h
|
cmp al, 0e0h
|
jne short noE0
|
jne short noE0
|
or cl, LastE0
|
or cl, LastE0
|
jmp short SetFlags1
|
jmp short SetFlags1
|
noE0:
|
noE0:
|
cmp al, 0e1h
|
cmp al, 0e1h
|
jne short noE1
|
jne short noE1
|
or cl, LastE1
|
or cl, LastE1
|
jmp short SetFlags1
|
jmp short SetFlags1
|
noE1:
|
noE1:
|
cmp al, 0f0h
|
cmp al, 0f0h
|
jne short noF0
|
jne short noF0
|
or cl, LastF0
|
or cl, LastF0
|
jmp short SetFlags1
|
jmp short SetFlags1
|
noF0:
|
noF0:
|
cmp al, 71h ; is DEL?
|
cmp al, 71h ; is DEL?
|
jne short noDEL
|
jne short noDEL
|
mov ah, dl
|
mov ah, dl
|
and ah, CtrlDown or AltDown
|
and ah, CtrlDown or AltDown
|
cmp ah, CtrlDown or AltDown
|
cmp ah, CtrlDown or AltDown
|
je short noF01
|
je short noF01
|
NormalKey1:
|
NormalKey1:
|
jmp NormalKey
|
jmp NormalKey
|
noF01:
|
noF01:
|
mov word ptr ds:[72h], 1234h ; warm boot flag
|
mov word ptr ds:[72h], 1234h ; warm boot flag
|
db 0eah
|
db 0eah
|
dw 0, 0ffffh ; reboot
|
dw 0, 0ffffh ; reboot
|
noDEL:
|
noDEL:
|
cmp al, 83h ; is F7
|
cmp al, 83h ; is F7
|
je short NormalKey1
|
je short NormalKey1
|
ja short SetFlags1
|
ja short SetFlags1
|
test cl, LastF0 ; key up?
|
test cl, LastF0 ; key up?
|
jz short noKeyUp
|
jz short noKeyUp
|
or al, 80h ; key up flag
|
or al, 80h ; key up flag
|
noKeyUp:
|
noKeyUp:
|
test cl, LastE0
|
test cl, LastE0
|
jnz short noRSUp ; ignore fake shifts
|
jnz short noRSUp ; ignore fake shifts
|
cmp al, 12h ; left shift
|
cmp al, 12h ; left shift
|
jne short noLSDown
|
jne short noLSDown
|
or dl, LShfDown
|
or dl, LShfDown
|
jmp short SetFlagsKey2
|
jmp short SetFlagsKey2
|
noLSDown:
|
noLSDown:
|
cmp al, 12h or 80h
|
cmp al, 12h or 80h
|
jne short noLSUp
|
jne short noLSUp
|
and dl, not LShfDown
|
and dl, not LShfDown
|
jmp short SetFlagsKey2
|
jmp short SetFlagsKey2
|
noLSUp:
|
noLSUp:
|
cmp al, 59h ; right shift
|
cmp al, 59h ; right shift
|
jne short noRSDown
|
jne short noRSDown
|
or dl, RShfDown
|
or dl, RShfDown
|
jmp short SetFlagsKey2
|
jmp short SetFlagsKey2
|
noRSDown:
|
noRSDown:
|
cmp al, 59h or 80h
|
cmp al, 59h or 80h
|
jne short noRSUP
|
jne short noRSUP
|
and dl, not RShfDown
|
and dl, not RShfDown
|
jmp short SetFlagsKey2
|
jmp short SetFlagsKey2
|
noRSUp:
|
noRSUp:
|
cmp al, 11h ; ALT
|
cmp al, 11h ; ALT
|
jne short noALTDown
|
jne short noALTDown
|
test cl, LastE0
|
test cl, LastE0
|
jz short LALTDn
|
jz short LALTDn
|
or cl, RAltDown
|
or cl, RAltDown
|
or dl, AltDown
|
or dl, AltDown
|
jmp short SetFlagsKey2
|
jmp short SetFlagsKey2
|
LALTDn:
|
LALTDn:
|
or dx, (LAltDown shl 8) or AltDown
|
or dx, (LAltDown shl 8) or AltDown
|
jmp short SetFlagsKey2
|
jmp short SetFlagsKey2
|
noALTDown:
|
noALTDown:
|
cmp al, 11h or 80h
|
cmp al, 11h or 80h
|
jne short noALTUp
|
jne short noALTUp
|
test cl, LastE0
|
test cl, LastE0
|
jz short LALTUp
|
jz short LALTUp
|
and cl, not RAltDown
|
and cl, not RAltDown
|
and dl, not AltDown
|
and dl, not AltDown
|
jmp short ALTup
|
jmp short ALTup
|
LALTUp:
|
LALTUp:
|
and dx, not ((LAltDown shl 8) or AltDown)
|
and dx, not ((LAltDown shl 8) or AltDown)
|
ALTUp:
|
ALTUp:
|
xor ax, ax
|
xor ax, ax
|
xchg al, AltKpd
|
xchg al, AltKpd
|
test al, al
|
test al, al
|
jz short SetFlagsKey2
|
jz short SetFlagsKey2
|
jmp pushKey
|
jmp pushKey
|
noALTUp:
|
noALTUp:
|
cmp al, 14h ; CTL
|
cmp al, 14h ; CTL
|
jne short noCTLDown
|
jne short noCTLDown
|
test cl, lastE0
|
test cl, lastE0
|
jz short LCTLDn
|
jz short LCTLDn
|
or cl, RCtrDown
|
or cl, RCtrDown
|
or dl, CtrlDown
|
or dl, CtrlDown
|
SetFlagsKey2:
|
SetFlagsKey2:
|
jmp short SetFlagsKey1
|
jmp short SetFlagsKey1
|
LCTLDn:
|
LCTLDn:
|
or dx, (LCtrDown shl 8) or CtrlDown
|
or dx, (LCtrDown shl 8) or CtrlDown
|
jmp short SetFlagsKey1
|
jmp short SetFlagsKey1
|
noCTLDown:
|
noCTLDown:
|
cmp al, 14h or 80h
|
cmp al, 14h or 80h
|
jne short noCTLUp
|
jne short noCTLUp
|
test cl, LastE0
|
test cl, LastE0
|
jz short LCTLUp
|
jz short LCTLUp
|
and cl, not RCtrDown
|
and cl, not RCtrDown
|
and dl, not CtrlDown
|
and dl, not CtrlDown
|
jmp short SetFlagsKey1
|
jmp short SetFlagsKey1
|
LCTLUp:
|
LCTLUp:
|
and dx, not ((LCtrDown shl 8) or CtrlDown)
|
and dx, not ((LCtrDown shl 8) or CtrlDown)
|
jmp short SetFlagsKey1
|
jmp short SetFlagsKey1
|
noCTLUp:
|
noCTLUp:
|
mov bx, 5800h + CapsLock
|
mov bx, 5800h + CapsLock
|
call KeyLock
|
call KeyLock
|
jnc short SetFlagsKey1
|
jnc short SetFlagsKey1
|
|
|
mov bx, 7e00h + ScrLock
|
mov bx, 7e00h + ScrLock
|
push dx ; save ScrLock state bit (dl)
|
push dx ; save ScrLock state bit (dl)
|
call KeyLock
|
call KeyLock
|
pop bx ; restore ScrLock state bit (bl)
|
pop bx ; restore ScrLock state bit (bl)
|
jc short noScrLock
|
jc short noScrLock
|
test dl, CtrlDown
|
test dl, CtrlDown
|
jz short SetFlagsKey1; no break, just ScollLock
|
jz short SetFlagsKey1; no break, just ScollLock
|
mov dl, bl ; restore ScrLock flag
|
mov dl, bl ; restore ScrLock flag
|
test bh, ScrLockDown
|
test bh, ScrLockDown
|
jnz short SetFlagsKey1
|
jnz short SetFlagsKey1
|
mov byte ptr CtrlBreak, 80h ; CTRL+BREAK flag
|
mov byte ptr CtrlBreak, 80h ; CTRL+BREAK flag
|
mov ax, Buffer
|
mov ax, Buffer
|
mov HeadPtr, ax
|
mov HeadPtr, ax
|
mov TailPtr, ax
|
mov TailPtr, ax
|
int 1bh
|
int 1bh
|
xor ax, ax
|
xor ax, ax
|
jmp pushkey
|
jmp pushkey
|
noScrLock:
|
noScrLock:
|
test cl, LastE0 ; INS
|
test cl, LastE0 ; INS
|
jnz short testINS
|
jnz short testINS
|
test dl, RShfDown or LShfDown
|
test dl, RShfDown or LShfDown
|
jnz short testINS
|
jnz short testINS
|
test dl, NumLock
|
test dl, NumLock
|
jnz short NoIns
|
jnz short NoIns
|
testINS:
|
testINS:
|
mov bx, 7000h + Insert
|
mov bx, 7000h + Insert
|
call KeyLock
|
call KeyLock
|
noIns:
|
noIns:
|
mov bx, 7700h + NumLock
|
mov bx, 7700h + NumLock
|
push dx ; save NumLock state bit (dl)
|
push dx ; save NumLock state bit (dl)
|
call KeyLock
|
call KeyLock
|
pop bx ; restore NumLock state bit (bl)
|
pop bx ; restore NumLock state bit (bl)
|
jc short noPause
|
jc short noPause
|
test dl, CtrlDown
|
test dl, CtrlDown
|
jz short SetFlagsKey1
|
jz short SetFlagsKey1
|
mov dl, bl ; restore NumLock flag
|
mov dl, bl ; restore NumLock flag
|
or dh, Pause ; set Pause bit
|
or dh, Pause ; set Pause bit
|
SetFlagsKey1:
|
SetFlagsKey1:
|
jmp SetFlagsKey
|
jmp SetFlagsKey
|
E0Key:
|
E0Key:
|
mov di, offset E0KeyList
|
mov di, offset E0KeyList
|
push cx
|
push cx
|
mov cx, E0KeyIndex - E0KeyList
|
mov cx, E0KeyIndex - E0KeyList
|
cld
|
cld
|
push cs
|
push cs
|
pop es
|
pop es
|
repne scasb
|
repne scasb
|
pop cx
|
pop cx
|
jne short SetFlagsKey
|
jne short SetFlagsKey
|
mov al, es:[di + E0KeyIndex - E0KeyList - 1]
|
mov al, es:[di + E0KeyIndex - E0KeyList - 1]
|
jmp short KeyDown
|
jmp short KeyDown
|
noPause:
|
noPause:
|
and al, 07fh ; delete up bit
|
and al, 07fh ; delete up bit
|
NormalKey:
|
NormalKey:
|
test cl, LastF0
|
test cl, LastF0
|
jnz short SetFlagsKey ; key up
|
jnz short SetFlagsKey ; key up
|
test cl, LastE0
|
test cl, LastE0
|
jnz short E0Key
|
jnz short E0Key
|
mov bx, offset KeyIndex
|
mov bx, offset KeyIndex
|
xlat cs:[bx]
|
xlat cs:[bx]
|
KeyDown:
|
KeyDown:
|
xor bx, bx
|
xor bx, bx
|
test dl, RShfDown or LShfDown
|
test dl, RShfDown or LShfDown
|
jz short noShift
|
jz short noShift
|
mov bl, 2
|
mov bl, 2
|
noShift:
|
noShift:
|
cmp al, 26
|
cmp al, 26
|
ja short noCaps
|
ja short noCaps
|
test dl, CapsLock
|
test dl, CapsLock
|
jz short noNum
|
jz short noNum
|
xor bl, 2
|
xor bl, 2
|
jmp short noNum
|
jmp short noNum
|
noCaps:
|
noCaps:
|
cmp al, 37
|
cmp al, 37
|
ja short noNum
|
ja short noNum
|
test dl, NumLock
|
test dl, NumLock
|
jnz short NumDown
|
jnz short NumDown
|
mov bl, 2
|
mov bl, 2
|
NumDown:
|
NumDown:
|
xor bl, 2
|
xor bl, 2
|
noNum:
|
noNum:
|
test dl, CtrlDown
|
test dl, CtrlDown
|
jz short noCtrl
|
jz short noCtrl
|
mov bl, 4
|
mov bl, 4
|
noCtrl:
|
noCtrl:
|
test dl, AltDown
|
test dl, AltDown
|
jz short noAlt
|
jz short noAlt
|
mov bl, 6
|
mov bl, 6
|
noAlt:
|
noAlt:
|
cbw
|
cbw
|
shl ax, 3
|
shl ax, 3
|
add bx, ax
|
add bx, ax
|
mov ax, cs:KeyCode[bx]
|
mov ax, cs:KeyCode[bx]
|
cmp ax, 000ah
|
cmp ax, 000ah
|
ja short pushKey
|
ja short pushKey
|
dec ax
|
dec ax
|
js short SetFlagsKey ; ax was 0
|
js short SetFlagsKey ; ax was 0
|
mov ah, AltKpd
|
mov ah, AltKpd
|
aad
|
aad
|
mov AltKpd, al
|
mov AltKpd, al
|
jmp short SetFlagsKey
|
jmp short SetFlagsKey
|
pushKey:
|
pushKey:
|
push cx
|
push cx
|
mov cx, ax
|
mov cx, ax
|
mov al, ah ; scan code
|
mov al, ah ; scan code
|
mov ah,4fh
|
mov ah,4fh
|
stc
|
stc
|
int 15h
|
int 15h
|
jnc nopush
|
jnc nopush
|
mov ah, 5
|
mov ah, 5
|
int 16h
|
int 16h
|
nopush:
|
nopush:
|
pop cx
|
pop cx
|
and dh, not Pause ; clear Pause bit
|
and dh, not Pause ; clear Pause bit
|
SetFlagsKey:
|
SetFlagsKey:
|
and cl, not (LastE0 or LastE1 or LastF0) ; not prefix key code, clear all prefixes
|
and cl, not (LastE0 or LastE1 or LastF0) ; not prefix key code, clear all prefixes
|
SetFlags:
|
SetFlags:
|
mov al, dl
|
mov al, dl
|
shr al, 4
|
shr al, 4
|
xor al, ch
|
xor al, ch
|
and al, 7
|
and al, 7
|
jz short SF1 ; no LEDs to update
|
jz short SF1 ; no LEDs to update
|
test ch, SetRepeat or AckReceived or LEDUpdate
|
test ch, SetRepeat or AckReceived or LEDUpdate
|
jnz short SF1 ; can not update LEDS, so just write the flags and exit
|
jnz short SF1 ; can not update LEDS, so just write the flags and exit
|
or al, LEDUpdate
|
or al, LEDUpdate
|
xor ch, al ; insert the LEDs in KbdFlags4
|
xor ch, al ; insert the LEDs in KbdFlags4
|
mov ah, 0edh ; set LED
|
mov ah, 0edh ; set LED
|
mov bl, 0
|
mov bl, 0
|
call sendps2byte
|
call sendps2byte
|
SF1:
|
SF1:
|
mov KbdFlags1, dx
|
mov KbdFlags1, dx
|
mov KbdFlags3, cx
|
mov KbdFlags3, cx
|
|
|
int09Exit:
|
int09Exit:
|
pop es
|
pop es
|
pop ds
|
pop ds
|
popa
|
popa
|
iret
|
iret
|
int09 endp
|
int09 endp
|
|
|
ENDIF
|
ENDIF
|
|
|
KeyLock proc near ; input: BH = expected scan code, al = scan code, BL = key lock flag. Returns CF=1 to continue, CF=0 to exit
|
KeyLock proc near ; input: BH = expected scan code, al = scan code, BL = key lock flag. Returns CF=1 to continue, CF=0 to exit
|
xor bh, al
|
xor bh, al
|
jnz short s2
|
jnz short s2
|
mov ah, dh
|
mov ah, dh
|
or dh, bl ; set flag
|
or dh, bl ; set flag
|
xor ah, dh ; get flag difference
|
xor ah, dh ; get flag difference
|
xor dl, ah ; toggle only if key was not already down
|
xor dl, ah ; toggle only if key was not already down
|
ret
|
ret
|
s2: cmp bh, 80h
|
s2: cmp bh, 80h
|
stc
|
stc
|
jne short exit
|
jne short exit
|
xor dh, bl ; key up
|
xor dh, bl ; key up
|
exit:
|
exit:
|
ret
|
ret
|
KeyLock endp
|
KeyLock endp
|
|
|
|
|
; --------------------- INT 10h - Video ----------------
|
; --------------------- INT 10h - Video ----------------
|
ActiveVideoMode equ ; 1 byte
|
ActiveVideoMode equ ; 1 byte
|
ScreenWidth equ ; 2 Screen width in text columns
|
ScreenWidth equ ; 2 Screen width in text columns
|
RegenLength equ ; 2 Length (in bytes) of video area (regen size)
|
RegenLength equ ; 2 Length (in bytes) of video area (regen size)
|
PageOffset equ ; 2 Offset from video segment of active video memory page
|
PageOffset equ ; 2 Offset from video segment of active video memory page
|
CursorPos equ ; 16 Cursor location (8 byte-pairs; low byte=col, hi byte=row)
|
CursorPos equ ; 16 Cursor location (8 byte-pairs; low byte=col, hi byte=row)
|
CursorShape equ ; 2 Cursor size/shape. Low byte=end scan line; hi byte=start line.
|
CursorShape equ ; 2 Cursor size/shape. Low byte=end scan line; hi byte=start line.
|
ActivePage equ ; 1 Current active video page number
|
ActivePage equ ; 1 Current active video page number
|
PortAddress equ ; 2 Port address for 6845 video controller chip; see CGA I/O Ports
|
PortAddress equ ; 2 Port address for 6845 video controller chip; see CGA I/O Ports
|
CrtMode equ ; 1 Current value of 6845 video ctrlr CRT_MODE (port 3x8H register)
|
CrtMode equ ; 1 Current value of 6845 video ctrlr CRT_MODE (port 3x8H register)
|
CrtPalette equ ; 1 Current value of 6845 video ctrlr CRT_PALETTE (port 3x9H reg)
|
CrtPalette equ ; 1 Current value of 6845 video ctrlr CRT_PALETTE (port 3x9H reg)
|
ScreenRows equ ; 1 EGA text rows-1 (maximum valid row value)
|
ScreenRows equ ; 1 EGA text rows-1 (maximum valid row value)
|
ScanLinesChar equ ; 2 EGA bytes per character (scan-lines/char used in active mode)
|
ScanLinesChar equ ; 2 EGA bytes per character (scan-lines/char used in active mode)
|
EgaMiscInfo equ ; 1 EGA flags; see EgaMiscInfoRec
|
EgaMiscInfo equ ; 1 EGA flags; see EgaMiscInfoRec
|
EgaMiscInfo2 equ ; 1 EGA flags; see EgaMiscInfo2Rec
|
EgaMiscInfo2 equ ; 1 EGA flags; see EgaMiscInfo2Rec
|
VgaFlags equ ; 1 VGA flags; see VgaFlagsRec
|
VgaFlags equ ; 1 VGA flags; see VgaFlagsRec
|
VgaFlags2 equ ; 1 VGA flags2
|
VgaFlags2 equ ; 1 VGA flags2
|
PalPaging equ ; 1 Palette paging status: bit7=0 for 4x64, 1 for 16x16. bit3:0=active page
|
PalPaging equ ; 1 Palette paging status: bit7=0 for 4x64, 1 for 16x16. bit3:0=active page
|
PalPagingCounter equ ; 1 Palette paging counter
|
PalPagingCounter equ ; 1 Palette paging counter
|
|
|
|
|
int10 proc near
|
int10 proc near
|
sti ; no interrupt reentrant
|
sti ; no interrupt reentrant
|
cld
|
cld
|
push ds
|
push ds
|
push si
|
push si
|
push 40h
|
push 40h
|
pop ds
|
pop ds
|
cmp ah, 4fh
|
cmp ah, 4fh
|
je short svga
|
je short svga
|
cmp ah, 1ch
|
cmp ah, 1ch
|
ja short exit
|
ja short exit
|
mov si, ax
|
mov si, ax
|
shr si, 7
|
shr si, 7
|
and si, 1feh
|
and si, 1feh
|
call cs:vidtbl[si]
|
call cs:vidtbl[si]
|
exit:
|
exit:
|
pop si
|
pop si
|
pop ds
|
pop ds
|
iret
|
iret
|
svga:
|
svga:
|
cmp al, 5
|
cmp al, 5
|
je short VESAMemControl
|
je short VESAMemControl
|
cmp al, 1
|
cmp al, 1
|
jb short VESAGetInfo
|
jb short VESAGetInfo
|
je short VESAGetModeInfo
|
je short VESAGetModeInfo
|
cmp al, 3
|
cmp al, 3
|
jb short VESASetMode
|
jb short VESASetMode
|
je short VESAGetMode
|
je short VESAGetMode
|
mov ax, 100h
|
mov ax, 100h
|
jmp short exit
|
jmp short exit
|
|
|
; ---------------- VESA fn00
|
; ---------------- VESA fn00
|
VESAGetInfo:
|
VESAGetInfo:
|
push cx
|
push cx
|
push di
|
push di
|
mov si, offset VESAInfo
|
mov si, offset VESAInfo
|
mov cx, 10
|
mov cx, 10
|
rep movsw es:[di], cs:[si]
|
rep movsw es:[di], cs:[si]
|
mov cl, 118 ; 236 bytes 0
|
mov cl, 118 ; 236 bytes 0
|
VESASupportedClear:
|
VESASupportedClear:
|
xor ax, ax
|
xor ax, ax
|
rep stosw
|
rep stosw
|
pop di
|
pop di
|
pop cx
|
pop cx
|
VESASupported:
|
VESASupported:
|
mov ah, 0 ; success
|
mov ah, 0 ; success
|
VESASupportedErr:
|
VESASupportedErr:
|
mov al, 4fh
|
mov al, 4fh
|
jmp short exit
|
jmp short exit
|
|
|
; ---------------- VESA fn01
|
; ---------------- VESA fn01
|
VESAGetModeInfo:
|
VESAGetModeInfo:
|
cmp cx, 101h
|
cmp cx, 101h
|
VESAGetModeInfo1:
|
VESAGetModeInfo1:
|
mov ah, 1 ; error
|
mov ah, 1 ; error
|
jne short VESASupportedErr
|
jne short VESASupportedErr
|
push cx
|
push cx
|
push di
|
push di
|
mov cx, 9
|
mov cx, 9
|
mov si, offset VESAModeInfo
|
mov si, offset VESAModeInfo
|
rep movsw es:[di], cs:[si]
|
rep movsw es:[di], cs:[si]
|
mov cl, 119
|
mov cl, 119
|
jmp short VESASupportedClear
|
jmp short VESASupportedClear
|
|
|
; ---------------- VESA fn02
|
; ---------------- VESA fn02
|
VESASetMode:
|
VESASetMode:
|
imul ax, bx, 2
|
imul ax, bx, 2
|
cmp ax, 101h*2
|
cmp ax, 101h*2
|
jne short VESASetMode1
|
jne short VESASetMode1
|
lea ax, [bx+23ffh]
|
lea ax, [bx+23ffh]
|
xchg ah, al
|
xchg ah, al
|
int 10h
|
int 10h
|
jmp short VESASupported
|
jmp short VESASupported
|
VESASetMode1:
|
VESASetMode1:
|
mov al, bl
|
mov al, bl
|
mov ah, 0
|
mov ah, 0
|
int 10h
|
int 10h
|
jmp short VESASupported
|
jmp short VESASupported
|
|
|
; ---------------- VESA fn03
|
; ---------------- VESA fn03
|
VESAGetMode:
|
VESAGetMode:
|
mov bh, EgaMiscInfo
|
mov bh, EgaMiscInfo
|
and bh, 80h
|
and bh, 80h
|
mov bl, ActiveVideoMode
|
mov bl, ActiveVideoMode
|
cmp bl, 25h
|
cmp bl, 25h
|
je short VESAGetMode1
|
je short VESAGetMode1
|
or bl, bh
|
or bl, bh
|
mov bh, 0
|
mov bh, 0
|
jmp short VESASupported
|
jmp short VESASupported
|
VESAGetMode1:
|
VESAGetMode1:
|
add bx, 257-25
|
add bx, 257-25
|
jmp short VESASupported
|
jmp short VESASupported
|
|
|
; ---------------- VESA fn05
|
; ---------------- VESA fn05
|
VESAMemControl:
|
VESAMemControl:
|
test bx, not 101h ; BX validation
|
test bx, not 101h ; BX validation
|
jnz short VESAGetModeInfo1 ; error
|
jnz short VESAGetModeInfo1 ; error
|
push cs
|
push cs
|
call VESAMemControlCB
|
call VESAMemControlCB
|
jmp short VESASupported
|
jmp short VESASupported
|
VESAMemControlCB:
|
VESAMemControlCB:
|
push ax
|
push ax
|
push dx
|
push dx
|
mov ax, bx
|
mov ax, bx
|
and ax, 1
|
and ax, 1
|
add al, 8ah
|
add al, 8ah
|
xchg ax, dx
|
xchg ax, dx
|
and ax, 7
|
and ax, 7
|
add al, 0ah
|
add al, 0ah
|
test bh, bh
|
test bh, bh
|
jnz getpageinfo
|
jnz getpageinfo
|
call flush
|
call flush
|
out dx, ax
|
out dx, ax
|
pop dx
|
pop dx
|
pop ax
|
pop ax
|
retf
|
retf
|
getpageinfo:
|
getpageinfo:
|
in ax, dx
|
in ax, dx
|
sub al, 0ah
|
sub al, 0ah
|
and ax, 7
|
and ax, 7
|
xchg ax, dx
|
xchg ax, dx
|
pop ax
|
pop ax
|
pop ax
|
pop ax
|
retf
|
retf
|
|
|
VESAInfo db 'VESA'
|
VESAInfo db 'VESA'
|
dw 100h, VESAOEM, 0f000h, 2, 0, VESAModes, 0f000h, 8
|
dw 100h, VESAOEM, 0f000h, 2, 0, VESAModes, 0f000h, 8
|
VESAOEM db 'Nicolae Dumitrache', 0
|
VESAOEM db 'Nicolae Dumitrache', 0
|
VESAModes dw 101h, 0ffffh
|
VESAModes dw 101h, 0ffffh
|
VESAModeInfo:
|
VESAModeInfo:
|
;Bit(s) Description - mode attributes
|
;Bit(s) Description - mode attributes
|
;0 mode supported by present hardware configuration
|
;0 mode supported by present hardware configuration
|
;1 optional information available (must be =1 for VBE v1.2+)
|
;1 optional information available (must be =1 for VBE v1.2+)
|
;2 BIOS output supported
|
;2 BIOS output supported
|
;3 set if color, clear if monochrome
|
;3 set if color, clear if monochrome
|
;4 set if graphics mode, clear if text mode
|
;4 set if graphics mode, clear if text mode
|
;---VBE v2.0+ ---
|
;---VBE v2.0+ ---
|
;5 mode is not VGA-compatible
|
;5 mode is not VGA-compatible
|
;6 bank-switched mode not supported
|
;6 bank-switched mode not supported
|
;7 linear framebuffer mode supported
|
;7 linear framebuffer mode supported
|
;8 double-scan mode available (e.g. 320x200 and 320x240)
|
;8 double-scan mode available (e.g. 320x200 and 320x240)
|
;---VBE v3.0 ---
|
;---VBE v3.0 ---
|
;9 interlaced mode available
|
;9 interlaced mode available
|
;10 hardware supports triple buffering
|
;10 hardware supports triple buffering
|
;11 hardware supports stereoscopic display
|
;11 hardware supports stereoscopic display
|
;12 dual display start address support
|
;12 dual display start address support
|
;13-15 reserved
|
;13-15 reserved
|
dw 0000000010011001b
|
dw 0000000010011001b
|
;Bit(s) Description - window attributes
|
;Bit(s) Description - window attributes
|
;0 exists
|
;0 exists
|
;1 readable
|
;1 readable
|
;2 writable
|
;2 writable
|
;3-7 reserved
|
;3-7 reserved
|
db 00000111b, 00000111b
|
db 00000111b, 00000111b
|
dw 64, 64, 0a000h, 0b000h, VESAMemControlCB, 0f000h, 640
|
dw 64, 64, 0a000h, 0b000h, VESAMemControlCB, 0f000h, 640
|
|
|
|
|
; --------------- fn 00h, set video mode
|
; --------------- fn 00h, set video mode
|
setmode:
|
setmode:
|
pusha
|
pusha
|
push es
|
push es
|
add al, al ; CF = cls bit
|
add al, al ; CF = cls bit
|
rcl byte ptr EgaMiscInfo, 1
|
rcl byte ptr EgaMiscInfo, 1
|
ror byte ptr EgaMiscInfo, 1
|
ror byte ptr EgaMiscInfo, 1
|
cmp al, 3*2
|
cmp al, 3*2
|
ja short setmode1
|
ja short setmode1
|
mov al, 0b6h ; reset sound generator
|
mov al, 0b6h ; reset sound generator
|
out 43h, al
|
out 43h, al
|
mov al, 0
|
mov al, 0
|
out 42h, al
|
out 42h, al
|
out 42h, al
|
out 42h, al
|
mov ax, 0806h ; text mode (80x25, 16 colors), flash enabled
|
mov ax, 0806h ; text mode (80x25, 16 colors), flash enabled
|
mov word ptr ScreenWidth, 80
|
mov word ptr ScreenWidth, 80
|
mov word ptr RegenLength, 1000h
|
mov word ptr RegenLength, 1000h
|
mov byte ptr ScreenRows, 25-1
|
mov byte ptr ScreenRows, 25-1
|
mov word ptr ScanLinesChar, 16
|
mov word ptr ScanLinesChar, 16
|
mov bx, 0b800h ; segment
|
mov bx, 0b800h ; segment
|
mov cx, 4000h ; video len/2
|
mov cx, 4000h ; video len/2
|
mov si, 0720h ; clear value
|
mov si, 0720h ; clear value
|
jmp short setmode2
|
jmp short setmode2
|
setmode1:
|
setmode1:
|
cmp al, 13h*2
|
cmp al, 13h*2
|
jne short setmode3
|
jne short setmode3
|
mov ah, 41h ; graphic mode, 320x200, 256 colors
|
mov ah, 41h ; graphic mode, 320x200, 256 colors
|
mov word ptr ScreenWidth, 40
|
mov word ptr ScreenWidth, 40
|
mov word ptr RegenLength, 2000h
|
mov word ptr RegenLength, 2000h
|
jmp short setmode21
|
jmp short setmode21
|
setmode3:
|
setmode3:
|
cmp al, 25h*2
|
cmp al, 25h*2
|
jne short setmodeexit
|
jne short setmodeexit
|
mov ah, 1 ; graphic mode, 640x400, 256 colors
|
mov ah, 1 ; graphic mode, 640x400, 256 colors
|
mov word ptr ScreenWidth, 80
|
mov word ptr ScreenWidth, 80
|
mov word ptr RegenLength, 2000h
|
mov word ptr RegenLength, 2000h
|
setmode21:
|
setmode21:
|
mov bx, 0a000h ; segment
|
mov bx, 0a000h ; segment
|
mov cx, 8000h ; video len/2 - clears only the first segment (TODO clear full screen)
|
mov cx, 8000h ; video len/2 - clears only the first segment (TODO clear full screen)
|
xor si, si ; clear value
|
xor si, si ; clear value
|
setmode2:
|
setmode2:
|
shr al, 1
|
shr al, 1
|
mov ActiveVideoMode, al
|
mov ActiveVideoMode, al
|
push ax
|
push ax
|
push cx
|
push cx
|
push ds
|
push ds
|
pop es
|
pop es
|
xor ax, ax
|
xor ax, ax
|
mov di, offset CursorPos
|
mov di, offset CursorPos
|
mov cx, 8
|
mov cx, 8
|
rep stosw ; reset cursor position for all pages
|
rep stosw ; reset cursor position for all pages
|
mov ax, 0500h
|
mov ax, 0500h
|
int 10h ; set page0
|
int 10h ; set page0
|
pop cx
|
pop cx
|
pop ax
|
pop ax
|
test byte ptr EgaMiscInfo, 80h
|
test byte ptr EgaMiscInfo, 80h
|
jnz short setmode4 ; no clear video memory
|
jnz short setmode4 ; no clear video memory
|
mov es, bx
|
mov es, bx
|
xchg ax, si
|
xchg ax, si
|
xor di, di
|
xor di, di
|
rep stosw
|
rep stosw
|
xchg ax, si
|
xchg ax, si
|
call palpageset
|
call palpageset
|
mov byte ptr PalPaging, cl ; reset paging
|
mov byte ptr PalPaging, cl ; reset paging
|
setmode4:
|
setmode4:
|
mov dx, 3c0h
|
mov dx, 3c0h
|
mov al, 10h
|
mov al, 10h
|
out dx, al
|
out dx, al
|
mov al, ah
|
mov al, ah
|
out dx, al ; set video mode
|
out dx, al ; set video mode
|
mov ax, 1123h
|
mov ax, 1123h
|
int 10h ; set ROM 8x8 font for graphics mode
|
int 10h ; set ROM 8x8 font for graphics mode
|
mov ah, 1
|
mov ah, 1
|
xor cx, cx
|
xor cx, cx
|
int 10h ; show cursor
|
int 10h ; show cursor
|
test byte ptr VgaFlags, 8 ; test default palette loading
|
test byte ptr VgaFlags, 8 ; test default palette loading
|
jnz short setmodeexit ; no default palette
|
jnz short setmodeexit ; no default palette
|
mov ax, 1012h
|
mov ax, 1012h
|
xor bx, bx
|
xor bx, bx
|
mov cx, 100h
|
mov cx, 100h
|
mov dx, offset default_pal
|
mov dx, offset default_pal
|
push cs
|
push cs
|
pop es
|
pop es
|
int 10h ; set default palette
|
int 10h ; set default palette
|
setmodeexit:
|
setmodeexit:
|
pop es
|
pop es
|
popa
|
popa
|
nullproc:
|
nullproc:
|
ret
|
ret
|
|
|
; --------------- fn 01h, set cursor shape and visibility (shape is ignored, always lines 14&15 of text mode char)
|
; --------------- fn 01h, set cursor shape and visibility (shape is ignored, always lines 14&15 of text mode char)
|
cursor: ; CH bit 6 or 5 -> cursor off
|
cursor: ; CH bit 6 or 5 -> cursor off
|
push ax
|
push ax
|
push dx
|
push dx
|
mov dx, 3d4h
|
mov dx, 3d4h
|
mov al, 0ah
|
mov al, 0ah
|
out dx, al
|
out dx, al
|
mov al, ch
|
mov al, ch
|
shr al, 1
|
shr al, 1
|
or al, ch
|
or al, ch
|
inc dx
|
inc dx
|
out dx, al
|
out dx, al
|
pop dx
|
pop dx
|
pop ax
|
pop ax
|
ret
|
ret
|
|
|
;---------------- fn 02h, set cursor pos
|
;---------------- fn 02h, set cursor pos
|
curpos:
|
curpos:
|
push ax
|
push ax
|
push bx
|
push bx
|
mov al, bh
|
mov al, bh
|
shr bx, 7
|
shr bx, 7
|
and bx, 0eh
|
and bx, 0eh
|
mov CursorPos[bx], dx
|
mov CursorPos[bx], dx
|
cmp byte ptr ActiveVideoMode, 3
|
cmp byte ptr ActiveVideoMode, 3
|
jne short curpos1
|
jne short curpos1
|
cmp al, ActivePage
|
cmp al, ActivePage
|
jne short curpos1
|
jne short curpos1
|
push dx
|
push dx
|
xor ax, ax
|
xor ax, ax
|
xchg al, dh
|
xchg al, dh
|
imul ax, 80
|
imul ax, 80
|
add ax, dx
|
add ax, dx
|
mov dx, 3d4h
|
mov dx, 3d4h
|
push ax
|
push ax
|
mov al, 0fh
|
mov al, 0fh
|
out dx, al
|
out dx, al
|
inc dx
|
inc dx
|
pop ax
|
pop ax
|
out dx, al
|
out dx, al
|
dec dx
|
dec dx
|
mov al, 0eh
|
mov al, 0eh
|
out dx, al
|
out dx, al
|
inc dx
|
inc dx
|
mov al, ah
|
mov al, ah
|
out dx, al
|
out dx, al
|
pop dx
|
pop dx
|
curpos1:
|
curpos1:
|
pop bx
|
pop bx
|
pop ax
|
pop ax
|
ret
|
ret
|
|
|
;---------------- fn 03h, get cursor pos
|
;---------------- fn 03h, get cursor pos
|
getcurpos:
|
getcurpos:
|
push bx
|
push bx
|
shr bx, 7
|
shr bx, 7
|
and bx, 0eh
|
and bx, 0eh
|
mov dx, CursorPos[bx]
|
mov dx, CursorPos[bx]
|
mov cx, CursorShape
|
mov cx, CursorShape
|
pop bx
|
pop bx
|
ret
|
ret
|
|
|
;---------------- fn 04h, light pen
|
;---------------- fn 04h, light pen
|
lightpen:
|
lightpen:
|
mov ah, 0 ; not triggered
|
mov ah, 0 ; not triggered
|
ret
|
ret
|
|
|
;---------------- fn 05h, set active video page
|
;---------------- fn 05h, set active video page
|
apage:
|
apage:
|
pusha
|
pusha
|
call flush
|
call flush
|
and al, 7
|
and al, 7
|
mov bh, al
|
mov bh, al
|
mov ActivePage, al
|
mov ActivePage, al
|
mov al, ActiveVideoMode
|
mov al, ActiveVideoMode
|
cmp al, 3
|
cmp al, 3
|
jne short apage1
|
jne short apage1
|
mov ax, 0ah
|
mov ax, 0ah
|
out 8ah, ax
|
out 8ah, ax
|
inc ax
|
inc ax
|
out 8bh, ax
|
out 8bh, ax
|
mov ah, 3
|
mov ah, 3
|
int 10h ; get cursor pos
|
int 10h ; get cursor pos
|
mov ah, 2
|
mov ah, 2
|
int 10h ; set cursor pos
|
int 10h ; set cursor pos
|
mov ax, 200h ; page size / 8
|
mov ax, 200h ; page size / 8
|
jmp short apage2
|
jmp short apage2
|
apage1: ; mode 13h and 25h
|
apage1: ; mode 13h and 25h
|
mov ax, 0ah
|
mov ax, 0ah
|
add al, bh
|
add al, bh
|
out 8ah, ax
|
out 8ah, ax
|
inc ax
|
inc ax
|
cmp al, 12h
|
cmp al, 12h
|
jne short apage4
|
jne short apage4
|
mov al, 0ah
|
mov al, 0ah
|
apage4: out 8bh, ax
|
apage4: out 8bh, ax
|
mov ax, 2000h ; page size / 8
|
mov ax, 2000h ; page size / 8
|
apage2:
|
apage2:
|
shr bx, 8 ; page number
|
shr bx, 8 ; page number
|
mul bx
|
mul bx
|
push ax
|
push ax
|
shl ax, 3
|
shl ax, 3
|
mov PageOffset, ax
|
mov PageOffset, ax
|
mov dx, 3d4h
|
mov dx, 3d4h
|
mov al, 0dh
|
mov al, 0dh
|
out dx, al
|
out dx, al
|
inc dx
|
inc dx
|
pop ax
|
pop ax
|
out dx, al
|
out dx, al
|
dec dx
|
dec dx
|
mov al, 0ch
|
mov al, 0ch
|
out dx, al
|
out dx, al
|
inc dx
|
inc dx
|
mov al, ah
|
mov al, ah
|
out dx, al
|
out dx, al
|
popa
|
popa
|
ret
|
ret
|
|
|
;---------------- fn 06h, scroll up / clr
|
;---------------- fn 06h, scroll up / clr
|
scrollup:
|
scrollup:
|
pusha
|
pusha
|
push es
|
push es
|
xchg cx, dx
|
xchg cx, dx
|
sub cx, dx
|
sub cx, dx
|
inc cx
|
inc cx
|
cmp byte ptr ActiveVideoMode, 13h
|
cmp byte ptr ActiveVideoMode, 13h
|
jae short scrollup1
|
jae short scrollup1
|
call scr_params
|
call scr_params
|
scrollup6:
|
scrollup6:
|
push 0b800h ; segment
|
push 0b800h ; segment
|
pop es
|
pop es
|
add dl, dl
|
add dl, dl
|
add di, di
|
add di, di
|
add di, PageOffset ; di = top left corner address
|
add di, PageOffset ; di = top left corner address
|
xchg ax, cx ; ah = 0
|
xchg ax, cx ; ah = 0
|
test bl, bl
|
test bl, bl
|
jz short scrollup3 ; clear
|
jz short scrollup3 ; clear
|
sub ah, bl
|
sub ah, bl
|
jb short scrollup3 ; clear
|
jb short scrollup3 ; clear
|
add si, di
|
add si, di
|
scrollup4:
|
scrollup4:
|
mov cl, al
|
mov cl, al
|
rep movsw es:[si], es:[di]
|
rep movsw es:[si], es:[di]
|
add si, dx
|
add si, dx
|
add di, dx
|
add di, dx
|
dec ah
|
dec ah
|
jns short scrollup4 ; ch = lines - 1
|
jns short scrollup4 ; ch = lines - 1
|
scrollup3:
|
scrollup3:
|
add ah, bl ; clear rectangle: DI=address, ah=lines, al=columns, bh=attribute
|
add ah, bl ; clear rectangle: DI=address, ah=lines, al=columns, bh=attribute
|
xchg ax, bx
|
xchg ax, bx
|
mov al, ' '
|
mov al, ' '
|
scrollup5:
|
scrollup5:
|
mov cl, bl
|
mov cl, bl
|
rep stosw
|
rep stosw
|
add di, dx
|
add di, dx
|
dec bh
|
dec bh
|
jns short scrollup5 ; ch = lines - 1
|
jns short scrollup5 ; ch = lines - 1
|
scrollexit:
|
scrollexit:
|
pop es
|
pop es
|
popa
|
popa
|
ret
|
ret
|
scrollup1:
|
scrollup1:
|
ja short scrollup2
|
ja short scrollup2
|
; TODO mode13h scroll up
|
; TODO mode13h scroll up
|
jmp short scrollexit
|
jmp short scrollexit
|
scrollup2:
|
scrollup2:
|
; TODO mode25h scroll up
|
; TODO mode25h scroll up
|
jmp short scrollexit
|
jmp short scrollexit
|
|
|
;---------------- fn 07h, scroll dn / clr
|
;---------------- fn 07h, scroll dn / clr
|
scrolldn:
|
scrolldn:
|
std
|
std
|
pusha
|
pusha
|
push es
|
push es
|
neg cx
|
neg cx
|
add cx, dx
|
add cx, dx
|
inc cx
|
inc cx
|
cmp byte ptr ActiveVideoMode, 13h
|
cmp byte ptr ActiveVideoMode, 13h
|
jae short scrolldn1
|
jae short scrolldn1
|
call scr_params
|
call scr_params
|
neg dx
|
neg dx
|
neg si
|
neg si
|
jmp short scrollup6
|
jmp short scrollup6
|
|
|
scrolldn1:
|
scrolldn1:
|
ja short scrolldn2
|
ja short scrolldn2
|
; TODO mode13h scroll down
|
; TODO mode13h scroll down
|
jmp short scrollexit
|
jmp short scrollexit
|
scrolldn2:
|
scrolldn2:
|
; TODO mode25h scroll down
|
; TODO mode25h scroll down
|
jmp short scrollexit
|
jmp short scrollexit
|
|
|
scr_params:
|
scr_params:
|
mov bl, al ; lines
|
mov bl, al ; lines
|
xor ax, ax
|
xor ax, ax
|
xchg al, dh
|
xchg al, dh
|
imul di, ax, 80
|
imul di, ax, 80
|
add di, dx
|
add di, dx
|
mov dl, 80 ; dh = 0
|
mov dl, 80 ; dh = 0
|
sub dl, cl
|
sub dl, cl
|
mov al, bl
|
mov al, bl
|
imul si, ax, 160
|
imul si, ax, 160
|
ret
|
ret
|
;---------------- fn 08h, read char/attr
|
;---------------- fn 08h, read char/attr
|
readchar:
|
readchar:
|
push bx
|
push bx
|
mov al, ActiveVideoMode
|
mov al, ActiveVideoMode
|
cmp al, 3
|
cmp al, 3
|
xor ax, ax
|
xor ax, ax
|
jne short readchar1
|
jne short readchar1
|
call mode3chaddr
|
call mode3chaddr
|
mov ax, [bx]
|
mov ax, [bx]
|
readcharexit:
|
readcharexit:
|
pop bx
|
pop bx
|
ret
|
ret
|
readchar1:
|
readchar1:
|
cmp al, 13h
|
cmp al, 13h
|
jne short readchar2
|
jne short readchar2
|
; TODO mode13h
|
; TODO mode13h
|
jmp short readcharexit
|
jmp short readcharexit
|
readchar2:
|
readchar2:
|
; TODO mode25h
|
; TODO mode25h
|
jmp short readcharexit
|
jmp short readcharexit
|
|
|
mode3chaddr: ; returns current char address in mode3 in ds:bx. Input: bh=page, ds=40h
|
mode3chaddr: ; returns current char address in mode3 in ds:bx. Input: bh=page, ds=40h
|
push ax
|
push ax
|
and bx, 700h
|
and bx, 700h
|
lea ax, [bx+0b800h]
|
lea ax, [bx+0b800h]
|
shr bx, 7
|
shr bx, 7
|
mov bx, CursorPos[bx]
|
mov bx, CursorPos[bx]
|
mov ds, ax
|
mov ds, ax
|
xor ax, ax
|
xor ax, ax
|
xchg al, bh
|
xchg al, bh
|
imul ax, 80
|
imul ax, 80
|
add bx, ax
|
add bx, ax
|
add bx, bx
|
add bx, bx
|
pop ax
|
pop ax
|
ret
|
ret
|
|
|
;---------------- fn 09h, write char/attr
|
;---------------- fn 09h, write char/attr
|
writecharattr:
|
writecharattr:
|
push ax
|
push ax
|
push es
|
push es
|
push bx
|
push bx
|
push cx
|
push cx
|
cmp byte ptr ActiveVideoMode, 3
|
cmp byte ptr ActiveVideoMode, 3
|
jne short writecharattr1
|
jne short writecharattr1
|
mov ah, bl
|
mov ah, bl
|
call mode3chaddr
|
call mode3chaddr
|
push ds
|
push ds
|
pop es
|
pop es
|
xchg di, bx
|
xchg di, bx
|
rep stosw
|
rep stosw
|
xchg di, bx
|
xchg di, bx
|
writecharattrexit:
|
writecharattrexit:
|
pop cx
|
pop cx
|
pop bx
|
pop bx
|
pop es
|
pop es
|
pop ax
|
pop ax
|
ret
|
ret
|
writecharattr1:
|
writecharattr1:
|
cmp byte ptr ActiveVideoMode, 13h
|
cmp byte ptr ActiveVideoMode, 13h
|
jne short writecharattr2
|
jne short writecharattr2
|
; TODO mode13h
|
; TODO mode13h
|
jmp short writecharattrexit
|
jmp short writecharattrexit
|
writecharattr2:
|
writecharattr2:
|
; TODO mode25h
|
; TODO mode25h
|
jmp short writecharattrexit
|
jmp short writecharattrexit
|
|
|
;---------------- fn 0ah, write char
|
;---------------- fn 0ah, write char
|
writechar:
|
writechar:
|
jcxz short writecharskip
|
jcxz short writecharskip
|
push bx
|
push bx
|
push cx
|
push cx
|
cmp byte ptr ActiveVideoMode, 3
|
cmp byte ptr ActiveVideoMode, 3
|
jne short writechar1
|
jne short writechar1
|
call mode3chaddr
|
call mode3chaddr
|
writechar3:
|
writechar3:
|
mov [bx], al
|
mov [bx], al
|
add bx, 2
|
add bx, 2
|
loop short writechar3
|
loop short writechar3
|
writecharexit:
|
writecharexit:
|
pop cx
|
pop cx
|
pop bx
|
pop bx
|
writecharskip:
|
writecharskip:
|
ret
|
ret
|
writechar1:
|
writechar1:
|
cmp byte ptr ActiveVideoMode, 13h
|
cmp byte ptr ActiveVideoMode, 13h
|
jne short writechar2
|
jne short writechar2
|
; TODO mode13h
|
; TODO mode13h
|
jmp short writecharexit
|
jmp short writecharexit
|
writechar2:
|
writechar2:
|
; TODO mode25h
|
; TODO mode25h
|
jmp short writecharexit
|
jmp short writecharexit
|
|
|
;---------------- fn 0eh, write char as TTY
|
;---------------- fn 0eh, write char as TTY
|
writecharTTY:
|
writecharTTY:
|
push ax
|
push ax
|
push bx
|
push bx
|
push dx
|
push dx
|
mov bl, ActivePage
|
mov bl, ActivePage
|
mov bh, 0
|
mov bh, 0
|
add bx, bx
|
add bx, bx
|
mov dx, CursorPos[bx]
|
mov dx, CursorPos[bx]
|
shl bx, 7
|
shl bx, 7
|
mov ah, 0ah
|
mov ah, 0ah
|
call tty
|
call tty
|
mov ah, 2 ; set cursor pos
|
mov ah, 2 ; set cursor pos
|
int 10h
|
int 10h
|
pop dx
|
pop dx
|
pop bx
|
pop bx
|
pop ax
|
pop ax
|
ret
|
ret
|
|
|
tty: ; dx=xy, bh=page, al=char, bl=attr, ah=0ah(no attr) or 09h(with attr)
|
tty: ; dx=xy, bh=page, al=char, bl=attr, ah=0ah(no attr) or 09h(with attr)
|
test word ptr KbdFlags2, Pause
|
test word ptr KbdFlags2, Pause
|
jnz short tty
|
jnz short tty
|
push cx
|
push cx
|
cmp al, 7
|
cmp al, 7
|
je short bell
|
je short bell
|
cmp al, 8
|
cmp al, 8
|
je short bs
|
je short bs
|
cmp al, 0ah
|
cmp al, 0ah
|
je short cr
|
je short cr
|
cmp al, 0dh
|
cmp al, 0dh
|
je short lf
|
je short lf
|
mov cx, 1
|
mov cx, 1
|
int 10h ; write char at cursor
|
int 10h ; write char at cursor
|
inc dx
|
inc dx
|
cmp dl, ScreenWidth
|
cmp dl, ScreenWidth
|
jae short crlf
|
jae short crlf
|
tty1:
|
tty1:
|
pop cx
|
pop cx
|
ret
|
ret
|
bell:
|
bell:
|
; TODO bell code
|
; TODO bell code
|
jmp short tty1
|
jmp short tty1
|
bs:
|
bs:
|
sub dl, 1
|
sub dl, 1
|
adc dl, 0
|
adc dl, 0
|
jmp short tty1
|
jmp short tty1
|
lf:
|
lf:
|
mov dl, 0
|
mov dl, 0
|
jmp short tty1
|
jmp short tty1
|
crlf:
|
crlf:
|
mov dl, 0
|
mov dl, 0
|
cr:
|
cr:
|
inc dh
|
inc dh
|
cmp dh, ScreenRows
|
cmp dh, ScreenRows
|
jbe short tty1
|
jbe short tty1
|
dec dh
|
dec dh
|
; mov ah, 8
|
; mov ah, 8
|
; int 10h ; read attribute at cursor pos
|
; int 10h ; read attribute at cursor pos
|
push bx ; save active page in bh
|
push bx ; save active page in bh
|
push dx
|
push dx
|
; xchg ax, bx
|
; xchg ax, bx
|
mov bh, 7 ; default attribute
|
mov bh, 7 ; default attribute
|
mov ax, 601h
|
mov ax, 601h
|
mov dh, ScreenRows
|
mov dh, ScreenRows
|
mov dl, ScreenWidth
|
mov dl, ScreenWidth
|
dec dx
|
dec dx
|
xor cx, cx
|
xor cx, cx
|
int 10h ; scroll up
|
int 10h ; scroll up
|
pop dx
|
pop dx
|
pop bx ; restore active page in bh
|
pop bx ; restore active page in bh
|
jmp short tty1
|
jmp short tty1
|
|
|
;---------------- fn 0fh, read video mode
|
;---------------- fn 0fh, read video mode
|
readmode:
|
readmode:
|
mov al, EgaMiscInfo
|
mov al, EgaMiscInfo
|
and al, 80h
|
and al, 80h
|
or al, ActiveVideoMode
|
or al, ActiveVideoMode
|
mov ah, ScreenWidth
|
mov ah, ScreenWidth
|
mov bh, ActivePage
|
mov bh, ActivePage
|
ret
|
ret
|
|
|
|
|
;---------------- fn 10h, palette
|
;---------------- fn 10h, palette
|
paltable dw setonereg, palexit, setallreg, setblink, palexit, palexit, palexit, readonereg, readoverscan, readallreg, palexit, palexit, palexit, palexit, palexit, palexit
|
paltable dw setonereg, palexit, setallreg, setblink, palexit, palexit, palexit, readonereg, readoverscan, readallreg, palexit, palexit, palexit, palexit, palexit, palexit
|
dw setoneDAC, palexit, setblockDAC, paging, palexit, readoneDAC, palexit, readblockDAC, setPELmask, getPELmask, getpaging, grayscale
|
dw setoneDAC, palexit, setblockDAC, paging, palexit, readoneDAC, palexit, readblockDAC, setPELmask, getPELmask, getpaging, grayscale
|
|
|
pal:
|
pal:
|
cmp al, 1bh
|
cmp al, 1bh
|
ja short palexit
|
ja short palexit
|
mov si, ax
|
mov si, ax
|
add si, si
|
add si, si
|
add byte ptr PalPagingCounter, ah ; prevents re-entrance on recursive calls
|
add byte ptr PalPagingCounter, ah ; prevents re-entrance on recursive calls
|
call palpage
|
call palpage
|
call cs:paltable[si-2000h]
|
call cs:paltable[si-2000h]
|
call palpage
|
call palpage
|
sub byte ptr PalPagingCounter, ah
|
sub byte ptr PalPagingCounter, ah
|
palexit:
|
palexit:
|
ret
|
ret
|
|
|
palpage: ; executes only if PalPagingCounter == ah
|
palpage: ; executes only if PalPagingCounter == ah
|
cmp byte ptr PalPagingCounter, ah
|
cmp byte ptr PalPagingCounter, ah
|
jne short palpageexit
|
jne short palpageexit
|
palpageset:
|
palpageset:
|
test byte ptr PalPaging, 0fh
|
test byte ptr PalPaging, 0fh
|
jz short palpageexit
|
jz short palpageexit
|
pusha
|
pusha
|
mov bl, byte ptr PalPaging
|
mov bl, byte ptr PalPaging
|
add bl, bl
|
add bl, bl
|
jc short page16
|
jc short page16
|
shl bl, 2
|
shl bl, 2
|
page16:
|
page16:
|
shl bx, 11 ; bh=target page, bl=0 page
|
shl bx, 11 ; bh=target page, bl=0 page
|
palpage1:
|
palpage1:
|
mov al, 15h
|
mov al, 15h
|
int 10h ; read 0 page DAC reg
|
int 10h ; read 0 page DAC reg
|
push cx
|
push cx
|
push dx
|
push dx
|
xchg bl, bh
|
xchg bl, bh
|
int 10h ; read target page DAC register
|
int 10h ; read target page DAC register
|
xchg bl, bh
|
xchg bl, bh
|
mov al, 10h
|
mov al, 10h
|
int 10h ; write 0 page DAC register
|
int 10h ; write 0 page DAC register
|
pop dx
|
pop dx
|
pop cx
|
pop cx
|
xchg bl, bh
|
xchg bl, bh
|
int 10h ; write target page DAC register
|
int 10h ; write target page DAC register
|
xchg bl, bh
|
xchg bl, bh
|
add bx, 101h; next DAC reg
|
add bx, 101h; next DAC reg
|
test bl, 0fh
|
test bl, 0fh
|
jnz short palpage1
|
jnz short palpage1
|
popa
|
popa
|
palpageexit:
|
palpageexit:
|
ret
|
ret
|
|
|
setonereg:
|
setonereg:
|
cmp bl, 10h
|
cmp bl, 10h
|
jae setonereg1
|
jae setonereg1
|
pusha
|
pusha
|
call colfrombits
|
call colfrombits
|
mov cl, al
|
mov cl, al
|
call colfrombits
|
call colfrombits
|
mov ch, al
|
mov ch, al
|
call colfrombits
|
call colfrombits
|
mov dh, al
|
mov dh, al
|
mov al, 10h
|
mov al, 10h
|
int 10h
|
int 10h
|
popa
|
popa
|
setonereg1:
|
setonereg1:
|
ret
|
ret
|
|
|
setallreg:
|
setallreg:
|
pusha
|
pusha
|
mov al, 0
|
mov al, 0
|
mov si, dx
|
mov si, dx
|
mov bl, 15
|
mov bl, 15
|
setallreg1:
|
setallreg1:
|
mov bh, es:[si+15]
|
mov bh, es:[si+15]
|
int 10h
|
int 10h
|
dec si
|
dec si
|
dec bl
|
dec bl
|
jns short setallreg1
|
jns short setallreg1
|
popa
|
popa
|
ret
|
ret
|
|
|
setblink:
|
setblink:
|
pusha
|
pusha
|
cmp byte ptr ActiveVideoMode, 3
|
cmp byte ptr ActiveVideoMode, 3
|
jne short setblink1
|
jne short setblink1
|
mov dx, 3c0h
|
mov dx, 3c0h
|
mov al, 10h
|
mov al, 10h
|
out dx, al
|
out dx, al
|
mov al, bl
|
mov al, bl
|
and al, 1
|
and al, 1
|
shl al, 3
|
shl al, 3
|
out dx, al ; set video mode (0 or 8)
|
out dx, al ; set video mode (0 or 8)
|
shl al, 2
|
shl al, 2
|
xor al, VgaFlags
|
xor al, VgaFlags
|
and al, 20h
|
and al, 20h
|
xor VgaFlags, al
|
xor VgaFlags, al
|
setblink1:
|
setblink1:
|
popa
|
popa
|
ret
|
ret
|
|
|
readonereg:
|
readonereg:
|
cmp bl, 10h
|
cmp bl, 10h
|
jae readonereg1
|
jae readonereg1
|
push ax
|
push ax
|
push cx
|
push cx
|
push dx
|
push dx
|
mov al, 15h
|
mov al, 15h
|
int 10h
|
int 10h
|
mov al, dh ; al = R
|
mov al, dh ; al = R
|
and al, 00110000b
|
and al, 00110000b
|
shr al, 2
|
shr al, 2
|
add al, 01111000b
|
add al, 01111000b
|
and al, 10000100b
|
and al, 10000100b
|
mov bh, al
|
mov bh, al
|
xchg ax, cx ; ax = GB
|
xchg ax, cx ; ax = GB
|
and ax, 0011000000110000b
|
and ax, 0011000000110000b
|
shr ax, 3
|
shr ax, 3
|
shr al, 1
|
shr al, 1
|
add ax, 0011110000011110b
|
add ax, 0011110000011110b
|
and ax, 0100001000100001b
|
and ax, 0100001000100001b
|
or bh, ah
|
or bh, ah
|
or bh, al
|
or bh, al
|
rol bh, 3
|
rol bh, 3
|
pop dx
|
pop dx
|
pop cx
|
pop cx
|
pop ax
|
pop ax
|
readonereg1:
|
readonereg1:
|
ret
|
ret
|
|
|
readallreg:
|
readallreg:
|
pusha
|
pusha
|
mov di, dx
|
mov di, dx
|
mov bl, 0
|
mov bl, 0
|
readllreg1:
|
readllreg1:
|
mov al, 7
|
mov al, 7
|
int 10h
|
int 10h
|
mov al, bh
|
mov al, bh
|
stosb
|
stosb
|
inc bx
|
inc bx
|
cmp bl, 16
|
cmp bl, 16
|
jne short readllreg1
|
jne short readllreg1
|
mov al, 0 ; overscan color
|
mov al, 0 ; overscan color
|
stosb
|
stosb
|
popa
|
popa
|
ret
|
ret
|
|
|
readoverscan:
|
readoverscan:
|
mov bh, 0
|
mov bh, 0
|
ret
|
ret
|
|
|
setoneDAC:
|
setoneDAC:
|
push ax
|
push ax
|
push dx
|
push dx
|
xchg ax, dx
|
xchg ax, dx
|
mov al, bl
|
mov al, bl
|
mov dx, 3c8h
|
mov dx, 3c8h
|
out dx, al
|
out dx, al
|
inc dx
|
inc dx
|
mov al, ah
|
mov al, ah
|
out dx, al
|
out dx, al
|
mov al, ch
|
mov al, ch
|
out dx, al
|
out dx, al
|
mov al, cl
|
mov al, cl
|
out dx, al
|
out dx, al
|
pop dx
|
pop dx
|
pop ax
|
pop ax
|
ret
|
ret
|
|
|
setblockDAC:
|
setblockDAC:
|
pusha
|
pusha
|
mov si, dx
|
mov si, dx
|
mov dx, 3c8h
|
mov dx, 3c8h
|
xchg ax, bx
|
xchg ax, bx
|
out dx, al
|
out dx, al
|
inc dx
|
inc dx
|
imul cx, 3
|
imul cx, 3
|
rep outsb dx, es:[si]
|
rep outsb dx, es:[si]
|
popa
|
popa
|
ret
|
ret
|
|
|
paging:
|
paging:
|
push bx
|
push bx
|
test bl, bl
|
test bl, bl
|
mov bl, PalPaging
|
mov bl, PalPaging
|
jnz short paging1
|
jnz short paging1
|
add bl, bl
|
add bl, bl
|
ror bx, 1
|
ror bx, 1
|
jmp short paging2
|
jmp short paging2
|
paging1:
|
paging1:
|
and bx, 0f80h ; bl=old page, bh=new page
|
and bx, 0f80h ; bl=old page, bh=new page
|
or bl, bh
|
or bl, bh
|
paging2:
|
paging2:
|
mov PalPaging, bl
|
mov PalPaging, bl
|
pop bx
|
pop bx
|
ret
|
ret
|
|
|
readoneDAC:
|
readoneDAC:
|
push ax
|
push ax
|
push dx
|
push dx
|
mov al, bl
|
mov al, bl
|
mov dx, 3c7h
|
mov dx, 3c7h
|
out dx, al
|
out dx, al
|
inc dx
|
inc dx
|
inc dx
|
inc dx
|
in al, dx
|
in al, dx
|
mov ah, al
|
mov ah, al
|
in al, dx
|
in al, dx
|
mov ch, al
|
mov ch, al
|
in al, dx
|
in al, dx
|
mov cl, al
|
mov cl, al
|
pop dx
|
pop dx
|
mov dh, ah
|
mov dh, ah
|
pop ax
|
pop ax
|
ret
|
ret
|
|
|
readblockDAC:
|
readblockDAC:
|
pusha
|
pusha
|
mov di, dx
|
mov di, dx
|
mov dx, 3c7h
|
mov dx, 3c7h
|
xchg ax, bx
|
xchg ax, bx
|
out dx, al
|
out dx, al
|
inc dx
|
inc dx
|
inc dx
|
inc dx
|
imul cx, 3
|
imul cx, 3
|
rep insb
|
rep insb
|
popa
|
popa
|
ret
|
ret
|
|
|
setPELmask:
|
setPELmask:
|
push dx
|
push dx
|
xchg ax, bx
|
xchg ax, bx
|
mov dx, 3c6h
|
mov dx, 3c6h
|
out dx, al
|
out dx, al
|
xchg ax, bx
|
xchg ax, bx
|
pop dx
|
pop dx
|
ret
|
ret
|
|
|
getPELmask:
|
getPELmask:
|
push dx
|
push dx
|
xchg ax, bx
|
xchg ax, bx
|
mov dx, 3c6h
|
mov dx, 3c6h
|
in al, dx
|
in al, dx
|
xchg ax, bx
|
xchg ax, bx
|
pop dx
|
pop dx
|
ret
|
ret
|
|
|
getpaging:
|
getpaging:
|
mov bh, PalPaging
|
mov bh, PalPaging
|
mov bl, 0
|
mov bl, 0
|
rol bx, 1
|
rol bx, 1
|
shr bh, 1
|
shr bh, 1
|
ret
|
ret
|
|
|
grayscale:
|
grayscale:
|
jcxz short grayscale2
|
jcxz short grayscale2
|
pusha
|
pusha
|
mov bh, cl
|
mov bh, cl
|
grayscale1:
|
grayscale1:
|
mov al, 15h
|
mov al, 15h
|
int 10h
|
int 10h
|
shr dx, 8
|
shr dx, 8
|
imul si, dx, 77
|
imul si, dx, 77
|
mov dl, ch
|
mov dl, ch
|
imul dx, 151
|
imul dx, 151
|
mov ch, 0
|
mov ch, 0
|
imul cx, 28
|
imul cx, 28
|
add dx, si
|
add dx, si
|
add dx, cx
|
add dx, cx
|
mov ch, dh
|
mov ch, dh
|
mov cl, dh
|
mov cl, dh
|
mov al, 10h
|
mov al, 10h
|
int 10h
|
int 10h
|
inc bl
|
inc bl
|
dec bh
|
dec bh
|
jne short grayscale1
|
jne short grayscale1
|
popa
|
popa
|
grayscale2:
|
grayscale2:
|
ret
|
ret
|
|
|
colfrombits: ; input: bh, output: al
|
colfrombits: ; input: bh, output: al
|
shr bh, 1
|
shr bh, 1
|
sbb al, al
|
sbb al, al
|
and al, 2ah
|
and al, 2ah
|
test bh, 4
|
test bh, 4
|
jz short col1
|
jz short col1
|
or al, 15h
|
or al, 15h
|
col1:
|
col1:
|
ret
|
ret
|
|
|
|
|
;---------------- fn 11h, character generator
|
;---------------- fn 11h, character generator
|
loadUDF:
|
loadUDF:
|
cmp bx, 1000h
|
cmp bx, 1000h
|
jne loadUDFexit ; only 16bytes chars and font block 0 supported
|
jne loadUDFexit ; only 16bytes chars and font block 0 supported
|
pusha
|
pusha
|
xchg ax, dx
|
xchg ax, dx
|
mov dx, 03cbh
|
mov dx, 03cbh
|
out dx, ax
|
out dx, ax
|
mov si, bp
|
mov si, bp
|
shl cx, 4
|
shl cx, 4
|
rep outsb dx, es:[si]
|
rep outsb dx, es:[si]
|
popa
|
popa
|
loadUDFexit:
|
loadUDFexit:
|
ret
|
ret
|
|
|
chargen:
|
chargen:
|
test al, not 10h ; test for 00h and 10h
|
test al, not 10h ; test for 00h and 10h
|
jz short loadUDF
|
jz short loadUDF
|
test al, not 11h ; test for 01h and 11h
|
test al, not 11h ; test for 01h and 11h
|
jz short loadROMfont
|
jz short loadROMfont
|
test al, not 12h ; test for 02h and 12h
|
test al, not 12h ; test for 02h and 12h
|
jz short loadROMfont
|
jz short loadROMfont
|
test al, not 14h ; test for 04h and 14h
|
test al, not 14h ; test for 04h and 14h
|
jz short loadROMfont
|
jz short loadROMfont
|
cmp al, 20h
|
cmp al, 20h
|
jb loadUDFexit
|
jb loadUDFexit
|
je short set1f
|
je short set1f
|
cmp al, 21h
|
cmp al, 21h
|
je short setgrUDF
|
je short setgrUDF
|
cmp al, 24h
|
cmp al, 24h
|
jbe short setROMgrFont
|
jbe short setROMgrFont
|
cmp al, 30h
|
cmp al, 30h
|
je short getfontinfo
|
je short getfontinfo
|
ret
|
ret
|
|
|
loadROMFont:
|
loadROMFont:
|
push es
|
push es
|
pusha
|
pusha
|
mov bx, 1000h ; 8x16 chars, block 0
|
mov bx, 1000h ; 8x16 chars, block 0
|
mov cx, 100h ; all chars
|
mov cx, 100h ; all chars
|
xor dx, dx
|
xor dx, dx
|
mov bp, offset font8x16
|
mov bp, offset font8x16
|
push cs
|
push cs
|
pop es
|
pop es
|
mov al, 0
|
mov al, 0
|
; int 10h ; loadUDF
|
; int 10h ; loadUDF
|
popa
|
popa
|
pop es
|
pop es
|
ret
|
ret
|
|
|
set1f:
|
set1f:
|
xor si, si
|
xor si, si
|
mov ds, si
|
mov ds, si
|
mov [si+1fh*4], bp
|
mov [si+1fh*4], bp
|
mov [si+1fh*4+2], es
|
mov [si+1fh*4+2], es
|
ret
|
ret
|
|
|
setgrUDF:
|
setgrUDF:
|
pusha
|
pusha
|
jcxz short loadUDFexit
|
jcxz short loadUDFexit
|
push ds
|
push ds
|
xor si, si
|
xor si, si
|
mov ds, si
|
mov ds, si
|
mov [si+43h*4], bp
|
mov [si+43h*4], bp
|
mov [si+43h*4+2], es
|
mov [si+43h*4+2], es
|
pop ds
|
pop ds
|
mov ax, 200
|
mov ax, 200
|
cmp byte ptr ActiveVideoMode, 13h
|
cmp byte ptr ActiveVideoMode, 13h
|
jb short setgrUDFexit
|
jb short setgrUDFexit
|
je short setgrUDF1
|
je short setgrUDF1
|
mov ax, 480 ; mode 25h, 480 lines
|
mov ax, 480 ; mode 25h, 480 lines
|
setgrUDF1:
|
setgrUDF1:
|
mov ScanLinesChar, cx
|
mov ScanLinesChar, cx
|
cwd
|
cwd
|
div cx
|
div cx
|
dec ax
|
dec ax
|
mov ScreenRows, al
|
mov ScreenRows, al
|
setgrUDFexit:
|
setgrUDFexit:
|
popa
|
popa
|
ret
|
ret
|
|
|
setROMgrFont:
|
setROMgrFont:
|
pusha
|
pusha
|
push es
|
push es
|
mov cx, 8
|
mov cx, 8
|
push cs
|
push cs
|
pop es
|
pop es
|
mov bp, offset font8x8
|
mov bp, offset font8x8
|
cmp al, 23h
|
cmp al, 23h
|
je short setROMgrFont1
|
je short setROMgrFont1
|
mov bp, offset font8x16
|
mov bp, offset font8x16
|
setROMgrFont1:
|
setROMgrFont1:
|
mov al, 21h
|
mov al, 21h
|
int 10h ; set graphic UDF
|
int 10h ; set graphic UDF
|
dec ax
|
dec ax
|
mov bp, offset font8x8 + 128*8
|
mov bp, offset font8x8 + 128*8
|
int 10h ; set INT 1fh
|
int 10h ; set INT 1fh
|
pop es
|
pop es
|
popa
|
popa
|
ret
|
ret
|
|
|
getfontinfo:
|
getfontinfo:
|
mov cx, ScanLinesChar
|
mov cx, ScanLinesChar
|
mov dl, ScreenRows
|
mov dl, ScreenRows
|
cmp bh, 1
|
cmp bh, 1
|
ja short getfontinfo1
|
ja short getfontinfo1
|
push 0
|
push 0
|
pop ds
|
pop ds
|
les bp, ds:[1fh*4]
|
les bp, ds:[1fh*4]
|
jb short getfontinfoexit
|
jb short getfontinfoexit
|
les bp, ds:[43h*4]
|
les bp, ds:[43h*4]
|
ret
|
ret
|
getfontinfo1:
|
getfontinfo1:
|
cmp bh, 7
|
cmp bh, 7
|
ja short getfontinfoexit
|
ja short getfontinfoexit
|
mov si, bx
|
mov si, bx
|
shr si, 8
|
shr si, 8
|
add si, si
|
add si, si
|
mov bp, cs:fontinfo[si-4]
|
mov bp, cs:fontinfo[si-4]
|
push cs
|
push cs
|
pop es
|
pop es
|
getfontinfoexit:
|
getfontinfoexit:
|
ret
|
ret
|
|
|
fontinfo dw font8x16, font8x8, font8x8+128*8, font8x16, font8x16, font8x16
|
fontinfo dw font8x16, font8x8, font8x8+128*8, font8x16, font8x16, font8x16
|
|
|
;---------------- fn 12h, special functions
|
;---------------- fn 12h, special functions
|
special:
|
special:
|
cmp bl, 10h
|
cmp bl, 10h
|
jne short special1
|
jne short special1
|
mov cl, EgaMiscInfo2 ; cl = switch settings
|
mov cl, EgaMiscInfo2 ; cl = switch settings
|
and cx, 15 ; ch <- 0 (feature bits)
|
and cx, 15 ; ch <- 0 (feature bits)
|
mov bx, 3 ; bh <- 0 (color mode), bl = video memory size
|
mov bx, 3 ; bh <- 0 (color mode), bl = video memory size
|
ret
|
ret
|
special1:
|
special1:
|
cmp bl, 31h
|
cmp bl, 31h
|
jne short special2
|
jne short special2
|
neg al
|
neg al
|
xor al, VgaFlags
|
xor al, VgaFlags
|
and al, 8 ; transfer palette loading bit to VgaFlags
|
and al, 8 ; transfer palette loading bit to VgaFlags
|
xor VgaFlags, al
|
xor VgaFlags, al
|
mov al, 12h ; supported function
|
mov al, 12h ; supported function
|
ret
|
ret
|
special2:
|
special2:
|
mov al, 0 ; unsupported function
|
mov al, 0 ; unsupported function
|
ret
|
ret
|
|
|
|
|
;---------------- fn 13h, write string
|
;---------------- fn 13h, write string
|
writestr:
|
writestr:
|
jcxz short wstrexit
|
jcxz short wstrexit
|
pusha
|
pusha
|
mov si, bx
|
mov si, bx
|
shr si, 8
|
shr si, 8
|
add si, si
|
add si, si
|
push CursorPos[si]
|
push CursorPos[si]
|
mov ah, 9 ; write tty char/attribute
|
mov ah, 9 ; write tty char/attribute
|
wstr1:
|
wstr1:
|
push ax
|
push ax
|
test al, 2
|
test al, 2
|
mov al, es:[bp]
|
mov al, es:[bp]
|
jz short noattr
|
jz short noattr
|
inc bp
|
inc bp
|
mov bl, es:[bp]
|
mov bl, es:[bp]
|
noattr:
|
noattr:
|
inc bp
|
inc bp
|
mov CursorPos[si], dx
|
mov CursorPos[si], dx
|
call tty
|
call tty
|
pop ax
|
pop ax
|
loop short wstr1
|
loop short wstr1
|
pop CursorPos[si]
|
pop CursorPos[si]
|
test al, 1
|
test al, 1
|
jz short wstr2
|
jz short wstr2
|
mov ah, 2 ; set cursor pos
|
mov ah, 2 ; set cursor pos
|
int 10h
|
int 10h
|
wstr2:
|
wstr2:
|
popa
|
popa
|
wstrexit:
|
wstrexit:
|
ret
|
ret
|
|
|
;---------------- fn 1ah, get/set display combination code
|
;---------------- fn 1ah, get/set display combination code
|
getdcc:
|
getdcc:
|
cmp al, 1
|
cmp al, 1
|
ja short getdccexit
|
ja short getdccexit
|
mov al, ah
|
mov al, ah
|
je short setdcc
|
je short setdcc
|
mov bx, 08h
|
mov bx, 08h
|
dccval label word
|
dccval label word
|
setdcc:
|
setdcc:
|
mov cs:[dccval-2], bx
|
mov cs:[dccval-2], bx
|
getdccexit:
|
getdccexit:
|
ret
|
ret
|
|
|
;---------------- fn 1bh, query status
|
;---------------- fn 1bh, query status
|
querystatus:
|
querystatus:
|
pusha
|
pusha
|
mov ax, offset staticfunctable
|
mov ax, offset staticfunctable
|
stosw
|
stosw
|
mov ax, cs
|
mov ax, cs
|
stosw
|
stosw
|
mov si, offset ActiveVideoMode
|
mov si, offset ActiveVideoMode
|
cmp byte ptr [si], 13h
|
cmp byte ptr [si], 13h
|
mov cx, 33 ; info copied from BDA
|
mov cx, 33 ; info copied from BDA
|
rep movsb
|
rep movsb
|
mov ax, 8
|
mov ax, 8
|
stosw ; display info (one VGA analog color monitor)
|
stosw ; display info (one VGA analog color monitor)
|
mov bx, 208h ; 400 scan lines, 8 pages
|
mov bx, 208h ; 400 scan lines, 8 pages
|
mov al, 10h ; 16 colors
|
mov al, 10h ; 16 colors
|
jb short querystatus1 ; mode03h
|
jb short querystatus1 ; mode03h
|
mov bh, 0 ; scan lines code (0=200, 1=350, 2=400, 3=480), 8 pages
|
mov bh, 0 ; scan lines code (0=200, 1=350, 2=400, 3=480), 8 pages
|
mov ax, 100h ; 256 colors
|
mov ax, 100h ; 256 colors
|
je short querystatus1 ; mode13h
|
je short querystatus1 ; mode13h
|
mov bx, 301h ; 480 scan lines, 1 page
|
mov bx, 301h ; 480 scan lines, 1 page
|
querystatus1:
|
querystatus1:
|
stosw
|
stosw
|
xchg ax, bx
|
xchg ax, bx
|
stosw
|
stosw
|
xor ax, ax
|
xor ax, ax
|
stosw ; font block info (45)
|
stosw ; font block info (45)
|
mov al, VgaFlags
|
mov al, VgaFlags
|
and al, 00101111b
|
and al, 00101111b
|
stosw
|
stosw
|
stosw
|
stosw
|
mov al, EgaMiscInfo
|
mov al, EgaMiscInfo
|
shr al, 4
|
shr al, 4
|
and al, 7 ; video memory size
|
and al, 7 ; video memory size
|
stosw
|
stosw
|
mov al, 2
|
mov al, 2
|
stosb ; color display attached
|
stosb ; color display attached
|
mov cl, 6
|
mov cl, 6
|
xor ax, ax
|
xor ax, ax
|
rep stosw ; 12 reserved bytes
|
rep stosw ; 12 reserved bytes
|
popa
|
popa
|
mov al, ah ; supported function
|
mov al, ah ; supported function
|
ret
|
ret
|
|
|
staticfunctable db 00001100b ; video mode 2h, 3h supported
|
staticfunctable db 00001100b ; video mode 2h, 3h supported
|
db 00000000b
|
db 00000000b
|
db 00001000b ; video mode 13h supported
|
db 00001000b ; video mode 13h supported
|
db 00000000b
|
db 00000000b
|
db 00100000b ; video mode 25h supported
|
db 00100000b ; video mode 25h supported
|
db 0, 0
|
db 0, 0
|
db 00000100b ; 400 scanline supported
|
db 00000100b ; 400 scanline supported
|
db 1 ; font blocks available in text mode
|
db 1 ; font blocks available in text mode
|
db 1 ; max active font blocks available in text mode
|
db 1 ; max active font blocks available in text mode
|
|
|
;Bit(s) Description
|
;Bit(s) Description
|
;0 all modes on all displays function supported
|
;0 all modes on all displays function supported
|
;1 gray summing function supported
|
;1 gray summing function supported
|
;2 character font loading function supported
|
;2 character font loading function supported
|
;3 default palette loading enable/disable supported
|
;3 default palette loading enable/disable supported
|
;4 cursor emulation function supported
|
;4 cursor emulation function supported
|
;5 EGA palette present
|
;5 EGA palette present
|
;6 color palette present
|
;6 color palette present
|
;7 color-register paging function supported
|
;7 color-register paging function supported
|
;8 light pen supported (see AH=04h)
|
;8 light pen supported (see AH=04h)
|
;9 save/restore state function 1Ch supported
|
;9 save/restore state function 1Ch supported
|
;10 intensity/blinking function supported (see AX=1003h)
|
;10 intensity/blinking function supported (see AX=1003h)
|
;11 Display Combination Code supported (see #00039)
|
;11 Display Combination Code supported (see #00039)
|
;12-15 unused (0)
|
;12-15 unused (0)
|
db 11101111b ; miscellaneous function support flags
|
db 11101111b ; miscellaneous function support flags
|
db 00001100b ; miscellaneous function support flags
|
db 00001100b ; miscellaneous function support flags
|
|
|
db 0, 0 ; reserved
|
db 0, 0 ; reserved
|
db 0 ; save pointer function flags
|
db 0 ; save pointer function flags
|
db 0 ; reserved
|
db 0 ; reserved
|
|
|
|
|
vidtbl dw setmode, cursor, curpos, getcurpos, lightpen, apage, scrollup, scrolldn, readchar, writecharattr
|
vidtbl dw setmode, cursor, curpos, getcurpos, lightpen, apage, scrollup, scrolldn, readchar, writecharattr
|
dw writechar, nullproc, nullproc, nullproc, writecharTTY, readmode
|
dw writechar, nullproc, nullproc, nullproc, writecharTTY, readmode
|
dw pal, chargen, special, writestr, nullproc, nullproc, nullproc, nullproc, nullproc, nullproc, getdcc, querystatus, nullproc
|
dw pal, chargen, special, writestr, nullproc, nullproc, nullproc, nullproc, nullproc, nullproc, getdcc, querystatus, nullproc
|
int10 endp
|
int10 endp
|
|
|
; --------------------- INT 11h - Equipment ----------------
|
; --------------------- INT 11h - Equipment ----------------
|
EquipmentWord equ
|
EquipmentWord equ
|
|
|
int11 proc near
|
int11 proc near
|
push ds
|
push ds
|
push 40h
|
push 40h
|
pop ds
|
pop ds
|
mov ax, EquipmentWord
|
mov ax, EquipmentWord
|
pop ds
|
pop ds
|
iret
|
iret
|
int11 endp
|
int11 endp
|
|
|
; --------------------- INT 12h - Memory size ----------------
|
; --------------------- INT 12h - Memory size ----------------
|
MemorySize equ
|
MemorySize equ
|
|
|
int12 proc near
|
int12 proc near
|
push ds
|
push ds
|
push 40h
|
push 40h
|
pop ds
|
pop ds
|
mov ax, MemorySize
|
mov ax, MemorySize
|
pop ds
|
pop ds
|
iret
|
iret
|
int12 endp
|
int12 endp
|
|
|
; --------------------- INT 13h - Disk services ----------------
|
; --------------------- INT 13h - Disk services ----------------
|
HDLastError equ
|
HDLastError equ
|
HDOpStarted equ ; bit 3: in INT13h (all other bits must be 0)
|
HDOpStarted equ ; bit 3: in INT13h (all other bits must be 0)
|
HDSize equ
|
HDSize equ
|
|
|
int13 proc near
|
int13 proc near
|
push ds
|
push ds
|
push bp
|
push bp
|
push 40h
|
push 40h
|
pop ds
|
pop ds
|
xor byte ptr HDOpStarted, 8
|
xor byte ptr HDOpStarted, 8
|
jz short inINT13
|
jz short inINT13
|
sti
|
sti
|
cld
|
cld
|
cmp ah, 1ah
|
cmp ah, 1ah
|
jbe short Disk1
|
jbe short Disk1
|
sub ah, 41h-1bh ; extensions
|
sub ah, 41h-1bh ; extensions
|
cmp ah, 22h
|
cmp ah, 22h
|
jbe short Disk1
|
jbe short Disk1
|
mov ah, 1 ; bad command error
|
mov ah, 1 ; bad command error
|
jmp short exit
|
jmp short exit
|
inINT13:
|
inINT13:
|
mov ah, 0aah ; drive not ready
|
mov ah, 0aah ; drive not ready
|
jmp short exit2
|
jmp short exit2
|
Disk1:
|
Disk1:
|
mov bp, ax
|
mov bp, ax
|
shr bp, 7
|
shr bp, 7
|
and bp, 1feh
|
and bp, 1feh
|
push ds
|
push ds
|
call cs:disktbl[bp]
|
call cs:disktbl[bp]
|
pop ds
|
pop ds
|
exit:
|
exit:
|
mov HDLastError, ah
|
mov HDLastError, ah
|
exit2:
|
exit2:
|
xor byte ptr HDOpStarted, 8
|
xor byte ptr HDOpStarted, 8
|
neg ah ; CF <- (AH != 0)
|
neg ah ; CF <- (AH != 0)
|
exit1:
|
exit1:
|
mov bp, sp
|
mov bp, sp
|
rcr byte ptr [bp+8], 1
|
rcr byte ptr [bp+8], 1
|
rol byte ptr [bp+8], 1 ; insert error CF on stack
|
rol byte ptr [bp+8], 1 ; insert error CF on stack
|
neg ah
|
neg ah
|
pop bp
|
pop bp
|
pop ds
|
pop ds
|
iret
|
iret
|
|
|
disktbl dw DiskReset, DiskGetStatus, DiskRead, DiskWrite, DiskVerify, DiskFormat, DiskFormat, DiskFormat, DiskGetParams, DiskInit, DiskRead, DiskWrite, DiskSeek, DiskRst, DiskReadSectBuffer, DiskWriteSectBuffer
|
disktbl dw DiskReset, DiskGetStatus, DiskRead, DiskWrite, DiskVerify, DiskFormat, DiskFormat, DiskFormat, DiskGetParams, DiskInit, DiskRead, DiskWrite, DiskSeek, DiskRst, DiskReadSectBuffer, DiskWriteSectBuffer
|
dw DiskReady, DiskRecalibrate, DiskDiag, DiskDiag, DiskDiag, DiskGetType, DiskChanged, DiskSetDASDType, DiskSetMediaType, DiskPark, DiskFormat, DiskExtInstCheck, DiskExtRead, DiskExtWrite, DiskExtVerify, DiskExtLock
|
dw DiskReady, DiskRecalibrate, DiskDiag, DiskDiag, DiskDiag, DiskGetType, DiskChanged, DiskSetDASDType, DiskSetMediaType, DiskPark, DiskFormat, DiskExtInstCheck, DiskExtRead, DiskExtWrite, DiskExtVerify, DiskExtLock
|
dw DiskExtEject, DiskExtSeek, DiskExtGetParams
|
dw DiskExtEject, DiskExtSeek, DiskExtGetParams
|
|
|
DiskGetType:
|
DiskGetType:
|
cmp dl, 80h
|
cmp dl, 80h
|
jne short DiskReset ; ah=0, drive not present
|
jne short DiskReset ; ah=0, drive not present
|
mov cx, HDSize
|
mov cx, HDSize
|
mov dx, cx
|
mov dx, cx
|
test cx, cx
|
test cx, cx
|
jz short DiskReset ; ah=0, drive not present
|
jz short DiskReset ; ah=0, drive not present
|
mov ah, -3 ; HD present
|
mov ah, -3 ; HD present
|
shr cx, 6
|
shr cx, 6
|
shl dx, 10 ; CX:DX = HDSize * 1024
|
shl dx, 10 ; CX:DX = HDSize * 1024
|
DiskGetTypeexit:
|
DiskGetTypeexit:
|
pop ds ; discard ret address
|
pop ds ; discard ret address
|
pop ds ; discard DS
|
pop ds ; discard DS
|
xor byte ptr HDOpStarted, 8 ; CF <- 0
|
xor byte ptr HDOpStarted, 8 ; CF <- 0
|
jmp short exit1
|
jmp short exit1
|
|
|
DiskExtInstCheck:
|
DiskExtInstCheck:
|
xchg bl, bh
|
xchg bl, bh
|
mov ah, -1
|
mov ah, -1
|
mov cx, 1 ; extended disk access functions (AH=42h-44h,47h,48h) supported
|
mov cx, 1 ; extended disk access functions (AH=42h-44h,47h,48h) supported
|
cmp dl, 80h
|
cmp dl, 80h
|
jne short notready
|
jne short notready
|
jmp short DiskGetTypeexit
|
jmp short DiskGetTypeexit
|
|
|
DiskReset:
|
DiskReset:
|
DiskChanged:
|
DiskChanged:
|
DiskPark:
|
DiskPark:
|
mov ah, 0 ; success
|
mov ah, 0 ; success
|
ret
|
ret
|
|
|
DiskGetStatus:
|
DiskGetStatus:
|
mov ah, HDLastError
|
mov ah, HDLastError
|
ret
|
ret
|
|
|
DiskVerify:
|
DiskVerify:
|
mov bp, sdverify
|
mov bp, sdverify
|
jmp short DiskRead1
|
jmp short DiskRead1
|
DiskWrite:
|
DiskWrite:
|
mov bp, sdwrite
|
mov bp, sdwrite
|
jmp short DiskRead1
|
jmp short DiskRead1
|
DiskRead:
|
DiskRead:
|
mov bp, sdread
|
mov bp, sdread
|
DiskRead1:
|
DiskRead1:
|
test al, al
|
test al, al
|
jz short DiskReset
|
jz short DiskReset
|
cmp dl, 80h
|
cmp dl, 80h
|
jne short notready
|
jne short notready
|
mov ah, 4
|
mov ah, 4
|
test cl, 3fh
|
test cl, 3fh
|
jz short DiskReadend ; bad sector 0
|
jz short DiskReadend ; bad sector 0
|
pusha
|
pusha
|
mov ah, 0
|
mov ah, 0
|
push ax
|
push ax
|
call HCStoLBA
|
call HCStoLBA
|
pop cx
|
pop cx
|
push cx
|
push cx
|
call bp ; DX:AX sector, ES:BX buffer, CX=sectors, returns AX=read sectors
|
call bp ; DX:AX sector, ES:BX buffer, CX=sectors, returns AX=read sectors
|
pop cx
|
pop cx
|
sub cx, ax
|
sub cx, ax
|
neg cx ; CF=1 if cx != 0
|
neg cx ; CF=1 if cx != 0
|
rcl ah, 3 ; AH = 4*CF (sector not found / read error)
|
rcl ah, 3 ; AH = 4*CF (sector not found / read error)
|
mov ds, ax
|
mov ds, ax
|
popa
|
popa
|
mov ax, ds
|
mov ax, ds
|
DiskReadend:
|
DiskReadend:
|
ret
|
ret
|
|
|
HCStoLBA: ; CX = {cyl[7:0], cyl[9:8], sect[5:0]}, DH = head. Returns DX:AX LBA
|
HCStoLBA: ; CX = {cyl[7:0], cyl[9:8], sect[5:0]}, DH = head. Returns DX:AX LBA
|
mov al, ch
|
mov al, ch
|
mov ah, cl
|
mov ah, cl
|
shr ah, 6
|
shr ah, 6
|
shr dx, 8
|
shr dx, 8
|
imul dx, 63
|
imul dx, 63
|
and cx, 3fh
|
and cx, 3fh
|
add cx, dx
|
add cx, dx
|
dec cx
|
dec cx
|
mov dx, 255*63
|
mov dx, 255*63
|
mul dx
|
mul dx
|
add ax, cx
|
add ax, cx
|
adc dx, 0
|
adc dx, 0
|
ret
|
ret
|
; unsigned int s = cs & 0x3f;
|
; unsigned int s = cs & 0x3f;
|
; unsigned int c = ((cs & 0xc0) << 2) | (cs >> 8);
|
; unsigned int c = ((cs & 0xc0) << 2) | (cs >> 8);
|
; return (c*255l + h)*63l + s - 1l;
|
; return (c*255l + h)*63l + s - 1l;
|
|
|
DiskFormat:
|
DiskFormat:
|
DiskInit:
|
DiskInit:
|
DiskSeek:
|
DiskSeek:
|
DiskRst:
|
DiskRst:
|
DiskReady:
|
DiskReady:
|
DiskRecalibrate:
|
DiskRecalibrate:
|
DiskDiag:
|
DiskDiag:
|
DiskExtSeek:
|
DiskExtSeek:
|
cmp word ptr HDSize, 0
|
cmp word ptr HDSize, 0
|
je short notready
|
je short notready
|
cmp dl, 80h
|
cmp dl, 80h
|
je short DiskReset
|
je short DiskReset
|
notready:
|
notready:
|
mov ah, 0aah ; disk not ready
|
mov ah, 0aah ; disk not ready
|
ret
|
ret
|
|
|
DiskGetParams:
|
DiskGetParams:
|
cmp dl, 80h
|
cmp dl, 80h
|
mov ah, 7
|
mov ah, 7
|
jne short DiskReadend ; ret
|
jne short DiskReadend ; ret
|
mov bl, 0 ; ???
|
mov bl, 0 ; ???
|
mov ax, HDSize
|
mov ax, HDSize
|
mov dx, ax
|
mov dx, ax
|
shl ax, 10
|
shl ax, 10
|
shr dx, 6
|
shr dx, 6
|
sub ax, 30
|
sub ax, 30
|
sbb dx, 0
|
sbb dx, 0
|
mov cx, 63*255
|
mov cx, 63*255
|
div cx
|
div cx
|
dec ax
|
dec ax
|
cmp ax, 3feh
|
cmp ax, 3feh
|
jbe dgpok
|
jbe dgpok
|
mov ax, 3feh
|
mov ax, 3feh
|
dgpok:
|
dgpok:
|
xchg al, ah
|
xchg al, ah
|
shl al, 6
|
shl al, 6
|
or al, 3fh
|
or al, 3fh
|
mov cx, ax
|
mov cx, ax
|
mov dx, 0fe01h
|
mov dx, 0fe01h
|
xor ax, ax
|
xor ax, ax
|
ret
|
ret
|
|
|
DiskExtVerify:
|
DiskExtVerify:
|
mov bp, sdverify
|
mov bp, sdverify
|
jmp short DiskExtRead1
|
jmp short DiskExtRead1
|
DiskExtWrite:
|
DiskExtWrite:
|
mov bp, sdwrite
|
mov bp, sdwrite
|
jmp short DiskExtRead1
|
jmp short DiskExtRead1
|
DiskExtRead:
|
DiskExtRead:
|
mov bp, sdread
|
mov bp, sdread
|
DiskExtRead1:
|
DiskExtRead1:
|
cmp dl, 80h
|
cmp dl, 80h
|
jne short notready
|
jne short notready
|
push es
|
push es
|
push ax
|
push ax
|
pusha
|
pusha
|
mov bx, sp
|
mov bx, sp
|
mov ds, ss:[bx+26]
|
mov ds, ss:[bx+26]
|
mov cx, [si+2]
|
mov cx, [si+2]
|
les bx, [si+4]
|
les bx, [si+4]
|
mov ax, [si+8]
|
mov ax, [si+8]
|
mov dx, [si+10]
|
mov dx, [si+10]
|
push ds
|
push ds
|
push si
|
push si
|
call bp
|
call bp
|
pop si
|
pop si
|
pop ds
|
pop ds
|
sub ax, [si+2]
|
sub ax, [si+2]
|
add [si+2], ax
|
add [si+2], ax
|
popa
|
popa
|
pop ax
|
pop ax
|
sbb ah, ah
|
sbb ah, ah
|
and ah, 4
|
and ah, 4
|
pop es
|
pop es
|
ret
|
ret
|
|
|
DiskExtGetParams:
|
DiskExtGetParams:
|
cmp dl, 80h
|
cmp dl, 80h
|
jne short notready
|
jne short notready
|
push ax
|
push ax
|
mov ax, HDSize
|
mov ax, HDSize
|
mov bp, sp
|
mov bp, sp
|
mov ds, [bp+8]
|
mov ds, [bp+8]
|
xor bp, bp
|
xor bp, bp
|
mov word ptr [si], 1ah ; size
|
mov word ptr [si], 1ah ; size
|
mov word ptr [si+2], 0bh ; flags
|
mov word ptr [si+2], 0bh ; flags
|
mov word ptr [si+4], 1023 ; cylinders
|
mov word ptr [si+4], 1023 ; cylinders
|
mov word ptr [si+6], bp
|
mov word ptr [si+6], bp
|
mov word ptr [si+8], 255 ; heads
|
mov word ptr [si+8], 255 ; heads
|
mov word ptr [si+10], bp
|
mov word ptr [si+10], bp
|
mov word ptr [si+12], 63 ; sectors/track
|
mov word ptr [si+12], 63 ; sectors/track
|
mov word ptr [si+14], bp
|
mov word ptr [si+14], bp
|
mov word ptr [si+16], ax
|
mov word ptr [si+16], ax
|
shl word ptr [si+16], 10
|
shl word ptr [si+16], 10
|
shr ax, 6
|
shr ax, 6
|
mov word ptr [si+18], ax
|
mov word ptr [si+18], ax
|
mov word ptr [si+20], bp
|
mov word ptr [si+20], bp
|
mov word ptr [si+22], bp
|
mov word ptr [si+22], bp
|
mov word ptr [si+24], 512 ; bytes/sector
|
mov word ptr [si+24], 512 ; bytes/sector
|
pop ax
|
pop ax
|
mov ah, 0
|
mov ah, 0
|
ret
|
ret
|
|
|
DiskReadSectBuffer:
|
DiskReadSectBuffer:
|
DiskWriteSectBuffer:
|
DiskWriteSectBuffer:
|
DiskSetDASDType:
|
DiskSetDASDType:
|
DiskSetMediaType:
|
DiskSetMediaType:
|
DiskExtLock:
|
DiskExtLock:
|
DiskExtEject:
|
DiskExtEject:
|
mov ah, 1 ; unsupported fn
|
mov ah, 1 ; unsupported fn
|
ret
|
ret
|
|
|
int13 endp
|
int13 endp
|
|
|
|
|
; --------------------- INT 15h - Extended services ----------------
|
; --------------------- INT 15h - Extended services ----------------
|
UFPtr equ
|
UFPtr equ
|
WaitCount equ
|
WaitCount equ
|
UWaitFlag equ
|
UWaitFlag equ
|
HandlerPtr equ ; 4 bytes
|
HandlerPtr equ ; 4 bytes
|
DataBuffer equ ; 3 bytes
|
DataBuffer equ ; 3 bytes
|
DataCounter equ ; 1 byte
|
DataCounter equ ; 1 byte
|
PacketSize equ ; 1 byte, 0->3bytes, 1->4bytes
|
PacketSize equ ; 1 byte, 0->3bytes, 1->4bytes
|
FreeXMSKb equ (1024 - 16 - 6)*64
|
FreeXMSKb equ (1024 - 16 - 6)*64
|
|
|
; ------------ MovExt
|
; ------------ MovExt
|
IncSeg: ; DX = segment port address
|
IncSeg: ; DX = segment port address
|
jnz short SetSegExit
|
jnz short SetSegExit
|
in ax, dx
|
in ax, dx
|
and ax, 3ffh
|
and ax, 3ffh
|
inc ax
|
inc ax
|
cmp ax, 12h
|
cmp ax, 12h
|
jne short IncSeg1
|
jne short IncSeg1
|
xor ax, ax
|
xor ax, ax
|
IncSeg1:
|
IncSeg1:
|
cmp ax, 0ch
|
cmp ax, 0ch
|
jne short SetSeg2
|
jne short SetSeg2
|
SetSeg: ; DX = segment port address, ax = logical segment (0..1023)
|
SetSeg: ; DX = segment port address, ax = logical segment (0..1023)
|
and ax, 3ffh
|
and ax, 3ffh
|
cmp ax, 0ch
|
cmp ax, 0ch
|
jb short SetSeg1
|
jb short SetSeg1
|
add ax, 6
|
add ax, 6
|
SetSeg2:
|
SetSeg2:
|
cmp ax, 400h
|
cmp ax, 400h
|
jb short SetSeg1
|
jb short SetSeg1
|
sub ax, 400h - 0ch
|
sub ax, 400h - 0ch
|
SetSeg1:
|
SetSeg1:
|
out dx, ax
|
out dx, ax
|
SetSegExit:
|
SetSegExit:
|
ret
|
ret
|
|
|
MovSeg equ 01h
|
MovSeg equ 01h
|
savess dw 0
|
savess dw 0
|
savesp dw MovExt, 0 ; tmp stack
|
savesp dw MovExt, 0 ; tmp stack
|
; Log(idx) to Phy(val) segment map (1024segs): 0,1,2,3,4,5,6,7,8,9,a,b,12h,13h,...,3feh,3ffh,c,d,e,f,10h,11h, then wrap to 0,1,2,...
|
; Log(idx) to Phy(val) segment map (1024segs): 0,1,2,3,4,5,6,7,8,9,a,b,12h,13h,...,3feh,3ffh,c,d,e,f,10h,11h, then wrap to 0,1,2,...
|
MovExt:
|
MovExt:
|
push es
|
push es
|
push ds
|
push ds
|
pusha
|
pusha
|
cli
|
cli
|
mov cs:savess, ss
|
mov cs:savess, ss
|
push cs
|
push cs
|
pop ss
|
pop ss
|
xchg sp, cs:savesp
|
xchg sp, cs:savesp
|
mov dx, 80h + MovSeg + 1
|
mov dx, 80h + MovSeg + 1
|
jcxz short MovExt_exit
|
jcxz short MovExt_exit
|
push es
|
push es
|
pop ds
|
pop ds
|
cld
|
cld
|
mov al, [si+1ch]
|
mov al, [si+1ch]
|
mov ah, [si+1fh]
|
mov ah, [si+1fh]
|
mov bl, [si+14h]
|
mov bl, [si+14h]
|
mov bh, [si+17h]
|
mov bh, [si+17h]
|
mov di, [si+1ah]
|
mov di, [si+1ah]
|
mov si, [si+12h]
|
mov si, [si+12h]
|
call flush
|
call flush
|
call SetSeg ; 02000h = destination, DX=82h
|
call SetSeg ; 02000h = destination, DX=82h
|
dec dx
|
dec dx
|
xchg ax, bx
|
xchg ax, bx
|
call SetSeg ; 01000h = source, DX=81h
|
call SetSeg ; 01000h = source, DX=81h
|
push MovSeg shl 12
|
push MovSeg shl 12
|
pop ds
|
pop ds
|
push (MovSeg + 1) shl 12
|
push (MovSeg + 1) shl 12
|
pop es
|
pop es
|
xor bx, bx
|
xor bx, bx
|
add cx, cx
|
add cx, cx
|
adc bx, bx ; BX:CX = bytes to transfer
|
adc bx, bx ; BX:CX = bytes to transfer
|
; move from 01000h:si to 02000h:di, 2*cx bytes
|
; move from 01000h:si to 02000h:di, 2*cx bytes
|
MovExtLoop:
|
MovExtLoop:
|
inc dx ; 82h
|
inc dx ; 82h
|
mov ax, si
|
mov ax, si
|
cmp ax, di
|
cmp ax, di
|
ja short MovExt1
|
ja short MovExt1
|
mov ax, di
|
mov ax, di
|
MovExt1:
|
MovExt1:
|
neg ax
|
neg ax
|
adc bx, -1
|
adc bx, -1
|
sub cx, ax
|
sub cx, ax
|
sbb bx, 0
|
sbb bx, 0
|
xchg ax, cx ; cx = bytes to move, bx:ax = bytes left for the next transfer
|
xchg ax, cx ; cx = bytes to move, bx:ax = bytes left for the next transfer
|
jns short MovExt2 ; ax <= bx:cx
|
jns short MovExt2 ; ax <= bx:cx
|
add cx, ax
|
add cx, ax
|
xor ax, ax
|
xor ax, ax
|
inc bx
|
inc bx
|
MovExt2:
|
MovExt2:
|
movsb ; if CX = 0 transfer 10000h bytes
|
movsb ; if CX = 0 transfer 10000h bytes
|
dec cx
|
dec cx
|
jz short MovExt_next
|
jz short MovExt_next
|
test si, 1 ; read align
|
test si, 1 ; read align
|
jz short raligned
|
jz short raligned
|
movsb
|
movsb
|
dec cx
|
dec cx
|
raligned:
|
raligned:
|
shr cx, 1
|
shr cx, 1
|
rep movsw
|
rep movsw
|
jnc short MovExt_next
|
jnc short MovExt_next
|
movsb
|
movsb
|
MovExt_next:
|
MovExt_next:
|
call flush
|
call flush
|
mov cx, ax
|
mov cx, ax
|
or ax, bx
|
or ax, bx
|
jz short MovExt_exit ; finalized
|
jz short MovExt_exit ; finalized
|
test di, di
|
test di, di
|
call incseg ; does nothing if ZF == 0, dx = 8bh
|
call incseg ; does nothing if ZF == 0, dx = 8bh
|
dec dx ; 81h
|
dec dx ; 81h
|
test si, si
|
test si, si
|
call incseg ; dx = 81h
|
call incseg ; dx = 81h
|
jmp short MovExtLoop
|
jmp short MovExtLoop
|
MovExt_exit:
|
MovExt_exit:
|
mov ax, MovSeg + 1
|
mov ax, MovSeg + 1
|
out dx, ax ; 82h
|
out dx, ax ; 82h
|
dec ax
|
dec ax
|
dec dx
|
dec dx
|
out dx, ax ; 81h
|
out dx, ax ; 81h
|
mov ss, cs:savess
|
mov ss, cs:savess
|
xchg sp, cs:savesp
|
xchg sp, cs:savesp
|
popa
|
popa
|
pop ds
|
pop ds
|
pop es
|
pop es
|
xor ah, ah
|
xor ah, ah
|
jmp short exit_ax
|
jmp short exit_ax
|
MovExtProxy:
|
MovExtProxy:
|
jmp MovExt
|
jmp MovExt
|
|
|
int15:
|
int15:
|
cmp ah, 4fh
|
cmp ah, 4fh
|
je short exit_iret
|
je short exit_iret
|
xchg al, ah
|
xchg al, ah
|
cmp al, 80h
|
cmp al, 80h
|
jb short exit15; CF=1 for <80h
|
jb short exit15; CF=1 for <80h
|
cmp al, 83h
|
cmp al, 83h
|
jb short done ; no error for 80, 81, 82
|
jb short done ; no error for 80, 81, 82
|
je short SetEventWait; 83
|
je short SetEventWait; 83
|
cmp al, 86h
|
cmp al, 86h
|
jb short exit15; CF=1 for 84, 85
|
jb short exit15; CF=1 for 84, 85
|
je short Wait1 ; 86
|
je short Wait1 ; 86
|
cmp al, 88h
|
cmp al, 88h
|
jb short MovExtProxy ; 87
|
jb short MovExtProxy ; 87
|
je short ExtSize ; 88
|
je short ExtSize ; 88
|
cmp al, 90h
|
cmp al, 90h
|
jb short exit15; CF=1 for 89..8f
|
jb short exit15; CF=1 for 89..8f
|
cmp al, 92h
|
cmp al, 92h
|
jb short done ; no error for 90, 91
|
jb short done ; no error for 90, 91
|
cmp al, 0c0h
|
cmp al, 0c0h
|
jb short exit15; CF=1 for 92..bf
|
jb short exit15; CF=1 for 92..bf
|
je short GetConfig ; c0
|
je short GetConfig ; c0
|
cmp al, 0c2h
|
cmp al, 0c2h
|
jb short exit15; CF=1 for c1
|
jb short exit15; CF=1 for c1
|
je short Mouse ; c2
|
je short Mouse ; c2
|
done:
|
done:
|
cmc ; CF=1 for >c2
|
cmc ; CF=1 for >c2
|
exit15:
|
exit15:
|
mov ax, 8600h
|
mov ax, 8600h
|
exit_ax:
|
exit_ax:
|
sti
|
sti
|
retf 2 ; discard flags (need to keep CF)
|
retf 2 ; discard flags (need to keep CF)
|
exit_iret:
|
exit_iret:
|
iret
|
iret
|
|
|
; ------------ SetEventWait
|
; ------------ SetEventWait
|
SetEventWait:
|
SetEventWait:
|
push ds
|
push ds
|
push 40h
|
push 40h
|
pop ds
|
pop ds
|
xor ah, 1
|
xor ah, 1
|
jz short cancel
|
jz short cancel
|
test ah, byte ptr UWaitFlag ; ah=1
|
test ah, byte ptr UWaitFlag ; ah=1
|
jnz short busy ; CF=0
|
jnz short busy ; CF=0
|
mov ax, 1000-1 ; 1ms
|
mov ax, 1000-1 ; 1ms
|
out 70h, ax ; restart RTC timer
|
out 70h, ax ; restart RTC timer
|
mov UFPtr[0], bx
|
mov UFPtr[0], bx
|
mov UFPtr[2], es
|
mov UFPtr[2], es
|
add ax, dx
|
add ax, dx
|
adc cx, 0
|
adc cx, 0
|
mov WaitCount[0], ax
|
mov WaitCount[0], ax
|
mov WaitCount[2], cx
|
mov WaitCount[2], cx
|
mov ah, 1 ; wait in progress
|
mov ah, 1 ; wait in progress
|
cancel:
|
cancel:
|
mov byte ptr UWaitFlag, ah
|
mov byte ptr UWaitFlag, ah
|
int 70h
|
int 70h
|
stc ; no error
|
stc ; no error
|
busy:
|
busy:
|
cmc ; eror
|
cmc ; eror
|
nowait:
|
nowait:
|
pop ds
|
pop ds
|
jmp short exit15
|
jmp short exit15
|
|
|
; ------------ Wait
|
; ------------ Wait
|
Wait1:
|
Wait1:
|
push es
|
push es
|
push bx
|
push bx
|
mov ax, 8300h
|
mov ax, 8300h
|
push 4ah
|
push 4ah
|
pop es
|
pop es
|
xor bx, bx ; user wait flag address=0040:00a0
|
xor bx, bx ; user wait flag address=0040:00a0
|
int 15h ; returns with IF = 1
|
int 15h ; returns with IF = 1
|
jc short wbusy
|
jc short wbusy
|
wloop:
|
wloop:
|
hlt
|
hlt
|
test byte ptr es:[bx], 80h
|
test byte ptr es:[bx], 80h
|
jz short wloop
|
jz short wloop
|
wbusy:
|
wbusy:
|
pop bx
|
pop bx
|
pop es
|
pop es
|
jmp short exit15
|
jmp short exit15
|
|
|
|
|
; ------------ ExtSize
|
; ------------ ExtSize
|
ExtSize:
|
ExtSize:
|
mov ax, FreeXMSKb
|
mov ax, FreeXMSKb
|
jmp short exit_ax
|
jmp short exit_ax
|
|
|
; ------------ GetConfig
|
; ------------ GetConfig
|
GetConfig:
|
GetConfig:
|
xor ax, ax
|
xor ax, ax
|
push cs
|
push cs
|
pop es
|
pop es
|
mov bx, offset SysParams
|
mov bx, offset SysParams
|
jmp short exit_ax
|
jmp short exit_ax
|
|
|
; ------------ Mouse
|
; ------------ Mouse
|
Mouse:
|
Mouse:
|
push ds
|
push ds
|
push dx
|
push dx
|
push 40h
|
push 40h
|
pop ds
|
pop ds
|
test byte ptr EquipmentWord, 4 ; ps2 mouse equipement word
|
test byte ptr EquipmentWord, 4 ; ps2 mouse equipement word
|
jnz short mouse_present
|
jnz short mouse_present
|
if_err:
|
if_err:
|
mov ax, 03a7h ; interface error (no mouse present)
|
mov ax, 03a7h ; interface error (no mouse present)
|
out 64h, al ; disable mouse
|
out 64h, al ; disable mouse
|
errexit:
|
errexit:
|
stc ; error
|
stc ; error
|
exitok:
|
exitok:
|
pushf ; save CF
|
pushf ; save CF
|
in al, 21h
|
in al, 21h
|
and al, not 10h
|
and al, not 10h
|
out 21h, al ; enable mouse interrupts
|
out 21h, al ; enable mouse interrupts
|
call enableKbIfPresent
|
call enableKbIfPresent
|
popf
|
popf
|
pop dx
|
pop dx
|
pop ds
|
pop ds
|
jmp exit_ax
|
jmp exit_ax
|
mouse_present:
|
mouse_present:
|
mov al, ah
|
mov al, ah
|
mov ah, 1 ; invalid function
|
mov ah, 1 ; invalid function
|
cmp al, 7
|
cmp al, 7
|
ja short errexit
|
ja short errexit
|
push ax
|
push ax
|
in al, 21h
|
in al, 21h
|
or al, 10h
|
or al, 10h
|
out 21h, al ; disable mouse interrupts
|
out 21h, al ; disable mouse interrupts
|
sti ; allow interrupts for a short time, to flush possible pending KB/mouse requests
|
sti ; allow interrupts for a short time, to flush possible pending KB/mouse requests
|
mov al, 0adh
|
mov al, 0adh
|
out 64h, al ; disable kb interface
|
out 64h, al ; disable kb interface
|
pop ax
|
pop ax
|
cmp al, 1
|
cmp al, 1
|
cli ; from now on we are working with ints disabled, as the following code is highly non re-entrant
|
cli ; from now on we are working with ints disabled, as the following code is highly non re-entrant
|
jb short en_dis
|
jb short en_dis
|
je short reset
|
je short reset
|
cmp al, 3
|
cmp al, 3
|
jb short sampling
|
jb short sampling
|
je short resolution
|
je short resolution
|
cmp al, 5
|
cmp al, 5
|
jb short gettype
|
jb short gettype
|
je short reset
|
je short reset
|
cmp al, 6
|
cmp al, 6
|
je short extend
|
je short extend
|
|
|
; ------------- set handler
|
; ------------- set handler
|
mov HandlerPtr[0], bx
|
mov HandlerPtr[0], bx
|
mov HandlerPtr[2], es
|
mov HandlerPtr[2], es
|
jmp short exit_success1
|
jmp short exit_success1
|
|
|
; ------------- enable/disable
|
; ------------- enable/disable
|
en_dis:
|
en_dis:
|
mov ax, 02f5h ; ah = invalid input
|
mov ax, 02f5h ; ah = invalid input
|
sub al, bh
|
sub al, bh
|
cmp bh, ah
|
cmp bh, ah
|
jnc short errexit
|
jnc short errexit
|
mov ah, al
|
mov ah, al
|
call sendcmd ; enable/disable data reporting (CF = 1)
|
call sendcmd ; enable/disable data reporting (CF = 1)
|
if_err1:
|
if_err1:
|
jc short if_err
|
jc short if_err
|
exit_success:
|
exit_success:
|
mov byte ptr DataCounter, 0
|
mov byte ptr DataCounter, 0
|
exit_success1:
|
exit_success1:
|
xor ah, ah ; success
|
xor ah, ah ; success
|
jmp short exitok
|
jmp short exitok
|
|
|
; ------------- reset
|
; ------------- reset
|
reset:
|
reset:
|
mov ah, 0f6h ; set defaults
|
mov ah, 0f6h ; set defaults
|
stc ; mouse command
|
stc ; mouse command
|
call sendcmd
|
call sendcmd
|
jc short if_err
|
jc short if_err
|
mov bx, 00aah
|
mov bx, 00aah
|
mov byte ptr PacketSize, bh ; 3bytes packet
|
mov byte ptr PacketSize, bh ; 3bytes packet
|
jmp short exit_success
|
jmp short exit_success
|
|
|
; ------------- sampling
|
; ------------- sampling
|
sampling:
|
sampling:
|
cmp bh, 6
|
cmp bh, 6
|
badparam:
|
badparam:
|
mov ah, 2 ; invalid input
|
mov ah, 2 ; invalid input
|
ja short errexit
|
ja short errexit
|
shr bx, 8
|
shr bx, 8
|
mov ah, cs:sample_tbl[bx]
|
mov ah, cs:sample_tbl[bx]
|
push ax
|
push ax
|
mov ah, 0f3h ; st sample rate
|
mov ah, 0f3h ; st sample rate
|
send2c:
|
send2c:
|
stc
|
stc
|
call sendcmd
|
call sendcmd
|
pop ax
|
pop ax
|
jc short if_err1
|
jc short if_err1
|
send1c:
|
send1c:
|
stc
|
stc
|
call sendcmd
|
call sendcmd
|
jmp short if_err1
|
jmp short if_err1
|
|
|
; ------------- resolution
|
; ------------- resolution
|
resolution:
|
resolution:
|
cmp bh, 3
|
cmp bh, 3
|
ja short badparam
|
ja short badparam
|
push bx
|
push bx
|
mov ah, 0e8h ; set resolution
|
mov ah, 0e8h ; set resolution
|
jmp short send2c
|
jmp short send2c
|
|
|
; ------------- gettype
|
; ------------- gettype
|
gettype:
|
gettype:
|
mov ah, 0f2h
|
mov ah, 0f2h
|
stc
|
stc
|
call sendcmd
|
call sendcmd
|
jc short if_err1
|
jc short if_err1
|
call getps2byte
|
call getps2byte
|
jc short if_err1
|
jc short if_err1
|
mov bh, al
|
mov bh, al
|
neg al ; CF=1 if al != 0
|
neg al ; CF=1 if al != 0
|
adc al, bh
|
adc al, bh
|
mov byte ptr PacketSize, al ; 3 or 4 bytes packet
|
mov byte ptr PacketSize, al ; 3 or 4 bytes packet
|
jmp short exit_success
|
jmp short exit_success
|
|
|
; ------------- extended commands
|
; ------------- extended commands
|
extend:
|
extend:
|
test bh, bh
|
test bh, bh
|
jnz short setscaling
|
jnz short setscaling
|
mov ah, 0e9h ; status request
|
mov ah, 0e9h ; status request
|
stc
|
stc
|
call sendcmd
|
call sendcmd
|
jc short if_err1
|
jc short if_err1
|
call getps2byte
|
call getps2byte
|
jc short if_err1
|
jc short if_err1
|
mov bl, al
|
mov bl, al
|
call getps2byte
|
call getps2byte
|
jc short if_err1
|
jc short if_err1
|
mov cl, al
|
mov cl, al
|
call getps2byte
|
call getps2byte
|
jc short if_err1
|
jc short if_err1
|
pop dx
|
pop dx
|
push ax ; replace dx on stack
|
push ax ; replace dx on stack
|
jmp short exit_success
|
jmp short exit_success
|
setscaling:
|
setscaling:
|
cmp bh, 2
|
cmp bh, 2
|
ja short badparam
|
ja short badparam
|
mov ah, 0e5h ; set scaling 1:1 or 2:1
|
mov ah, 0e5h ; set scaling 1:1 or 2:1
|
add ah, bh
|
add ah, bh
|
jmp short send1c
|
jmp short send1c
|
|
|
sample_tbl db 10, 20, 40, 60, 80, 100, 200
|
sample_tbl db 10, 20, 40, 60, 80, 100, 200
|
SysParams db 8, 0, 0fch, 0, 0
|
SysParams db 8, 0, 0fch, 0, 0
|
;--------------------------------------------------------------------------
|
;--------------------------------------------------------------------------
|
; Feature byte 1
|
; Feature byte 1
|
; b7: 1=DMA channel 3 used by hard disk
|
; b7: 1=DMA channel 3 used by hard disk
|
; b6: 1=2 interrupt controllers present
|
; b6: 1=2 interrupt controllers present
|
; b5: 1=RTC present
|
; b5: 1=RTC present
|
; b4: 1=BIOS calls int 15h/4Fh every key
|
; b4: 1=BIOS calls int 15h/4Fh every key
|
; b3: 1=wait for extern event supported (Int 15h/41h)
|
; b3: 1=wait for extern event supported (Int 15h/41h)
|
; b2: 1=extended BIOS data area used
|
; b2: 1=extended BIOS data area used
|
; b1: 0=AT or ESDI bus, 1=MicroChannel
|
; b1: 0=AT or ESDI bus, 1=MicroChannel
|
; b0: 1=Dual bus (MicroChannel + ISA)
|
; b0: 1=Dual bus (MicroChannel + ISA)
|
;--------------------------------------------------------------------------
|
;--------------------------------------------------------------------------
|
db 10h
|
db 10h
|
;--------------------------------------------------------------------------
|
;--------------------------------------------------------------------------
|
; Feature byte 2
|
; Feature byte 2
|
; b7: 1=32-bit DMA supported
|
; b7: 1=32-bit DMA supported
|
; b6: 1=int16h, function 9 supported
|
; b6: 1=int16h, function 9 supported
|
; b5: 1=int15h/C6h (get POS data) supported
|
; b5: 1=int15h/C6h (get POS data) supported
|
; b4: 1=int15h/C7h (get mem map info) supported
|
; b4: 1=int15h/C7h (get mem map info) supported
|
; b3: 1=int15h/C8h (en/dis CPU) supported
|
; b3: 1=int15h/C8h (en/dis CPU) supported
|
; b2: 1=non-8042 kb controller
|
; b2: 1=non-8042 kb controller
|
; b1: 1=data streaming supported
|
; b1: 1=data streaming supported
|
; b0: reserved
|
; b0: reserved
|
;--------------------------------------------------------------------------
|
;--------------------------------------------------------------------------
|
db 44h
|
db 44h
|
;--------------------------------------------------------------------------
|
;--------------------------------------------------------------------------
|
; Feature byte 3
|
; Feature byte 3
|
; b7: not used
|
; b7: not used
|
; b6: reserved
|
; b6: reserved
|
; b5: reserved
|
; b5: reserved
|
; b4: POST supports ROM-to-RAM enable/disable
|
; b4: POST supports ROM-to-RAM enable/disable
|
; b3: SCSI on system board
|
; b3: SCSI on system board
|
; b2: info panel installed
|
; b2: info panel installed
|
; b1: Initial Machine Load (IML) system - BIOS on disk
|
; b1: Initial Machine Load (IML) system - BIOS on disk
|
; b0: SCSI supported in IML
|
; b0: SCSI supported in IML
|
;--------------------------------------------------------------------------
|
;--------------------------------------------------------------------------
|
db 0
|
db 0
|
;--------------------------------------------------------------------------
|
;--------------------------------------------------------------------------
|
; Feature byte 4
|
; Feature byte 4
|
; b7: IBM private
|
; b7: IBM private
|
; b6: EEPROM present
|
; b6: EEPROM present
|
; b5-3: ABIOS presence (011 = not supported)
|
; b5-3: ABIOS presence (011 = not supported)
|
; b2: private
|
; b2: private
|
; b1: memory split above 16Mb supported
|
; b1: memory split above 16Mb supported
|
; b0: POSTEXT directly supported by POST
|
; b0: POSTEXT directly supported by POST
|
;--------------------------------------------------------------------------
|
;--------------------------------------------------------------------------
|
db 0
|
db 0
|
;--------------------------------------------------------------------------
|
;--------------------------------------------------------------------------
|
; Feature byte 5 (IBM)
|
; Feature byte 5 (IBM)
|
; b1: enhanced mouse
|
; b1: enhanced mouse
|
; b0: flash EPROM
|
; b0: flash EPROM
|
;--------------------------------------------------------------------------
|
;--------------------------------------------------------------------------
|
db 0
|
db 0
|
|
|
|
|
; --------------------- INT 16h - keyboard interface ----------------
|
; --------------------- INT 16h - keyboard interface ----------------
|
; AH Description
|
; AH Description
|
; -- ------------------------------------------------
|
; -- ------------------------------------------------
|
; 00h Get a key from the keyboard, return code in AX.
|
; 00h Get a key from the keyboard, return code in AX.
|
; 01h Test for available key, ZF=1 if none, ZF=0 and
|
; 01h Test for available key, ZF=1 if none, ZF=0 and
|
; AX contains next key code if key available.
|
; AX contains next key code if key available.
|
; 02h Get shift status. Returns shift key status in AL.
|
; 02h Get shift status. Returns shift key status in AL.
|
; 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.
|
; 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.
|
; 05h Store scan code (in CX) in the type ahead buffer.
|
; 05h Store scan code (in CX) in the type ahead buffer.
|
; 10h Get a key (same as 00h in this implementation).
|
; 10h Get a key (same as 00h in this implementation).
|
; 11h Test for key (same as 01h).
|
; 11h Test for key (same as 01h).
|
; 12h Get extended key status. Returns status in AX.
|
; 12h Get extended key status. Returns status in AX.
|
|
|
AltKpd equ
|
AltKpd equ
|
HeadPtr equ
|
HeadPtr equ
|
TailPtr equ
|
TailPtr equ
|
Buffer equ ;1eh
|
Buffer equ ;1eh
|
EndBuf equ ;3eh
|
EndBuf equ ;3eh
|
|
|
int16 proc near
|
int16 proc near
|
push ds
|
push ds
|
push si
|
push si
|
push 40h
|
push 40h
|
pop ds
|
pop ds
|
xchg al, ah ;shorter opcodes for al than ah
|
xchg al, ah ;shorter opcodes for al than ah
|
dec ax
|
dec ax
|
test al, 0EFh ;Check for 01h and 11h
|
test al, 0EFh ;Check for 01h and 11h
|
jz short TestKey ;TestKey does not need cld
|
jz short TestKey ;TestKey does not need cld
|
inc ax
|
inc ax
|
cld
|
cld
|
test al, 0EFh ;Check for 0h and 10h
|
test al, 0EFh ;Check for 0h and 10h
|
jz short GetKey
|
jz short GetKey
|
cmp al, 3 ;Check for 02h and 03h
|
cmp al, 3 ;Check for 02h and 03h
|
jb short GetStatus
|
jb short GetStatus
|
je short SetAutoRpt
|
je short SetAutoRpt
|
cmp al, 5 ;Check for StoreKey function.
|
cmp al, 5 ;Check for StoreKey function.
|
je short StoreKey
|
je short StoreKey
|
cmp al, 9 ;Get KB functionality
|
cmp al, 9 ;Get KB functionality
|
je short kbfunc
|
je short kbfunc
|
cmp al, 12h ;Extended status call
|
cmp al, 12h ;Extended status call
|
je short ExtStatus
|
je short ExtStatus
|
cmp al, 92h ;stupid keyb.com
|
cmp al, 92h ;stupid keyb.com
|
jne short Exit
|
jne short Exit
|
kbfunc:
|
kbfunc:
|
mov al, 24h ;AL=20h (fn 10h, 12h supported, set typematic supported)
|
mov al, 24h ;AL=20h (fn 10h, 12h supported, set typematic supported)
|
Exit:
|
Exit:
|
pop si
|
pop si
|
pop ds
|
pop ds
|
iret ; unknown function, Restores flags.
|
iret ; unknown function, Restores flags.
|
|
|
GetKey1: ; wait for interrupt
|
GetKey1: ; wait for interrupt
|
hlt
|
hlt
|
GetKey: ; ----------- fn 00h, 10h
|
GetKey: ; ----------- fn 00h, 10h
|
mov ah, 11h
|
mov ah, 11h
|
int 16h ;See if key is available (IF becomes 1 after this int)
|
int 16h ;See if key is available (IF becomes 1 after this int)
|
jz short GetKey1 ;Wait for keystroke.
|
jz short GetKey1 ;Wait for keystroke.
|
cli ;Critical region! Ints off.
|
cli ;Critical region! Ints off.
|
mov si, HeadPtr ;Ptr to next character.
|
mov si, HeadPtr ;Ptr to next character.
|
lodsw ;Get the character, Bump up HeadPtr
|
lodsw ;Get the character, Bump up HeadPtr
|
cmp si, EndBuf
|
cmp si, EndBuf
|
jb short noWrap
|
jb short noWrap
|
mov si, Buffer
|
mov si, Buffer
|
noWrap:
|
noWrap:
|
mov HeadPtr, si
|
mov HeadPtr, si
|
jmp short Exit
|
jmp short Exit
|
|
|
TestKey: ; ---------- fn 01h
|
TestKey: ; ---------- fn 01h
|
mov si, HeadPtr
|
mov si, HeadPtr
|
cmp si, TailPtr ;ZF=1, if empty buffer
|
cmp si, TailPtr ;ZF=1, if empty buffer
|
lodsw ;BIOS returns avail keycode.
|
lodsw ;BIOS returns avail keycode.
|
sti ;Ints back on.
|
sti ;Ints back on.
|
pop si
|
pop si
|
pop ds
|
pop ds
|
retf 2 ;Pop flags (ZF is important!)
|
retf 2 ;Pop flags (ZF is important!)
|
|
|
StoreKey: ; ---------- fn 05h - Inserts the value in CX into the type ahead buffer.
|
StoreKey: ; ---------- fn 05h - Inserts the value in CX into the type ahead buffer.
|
mov si, TailPtr ;Address where we can put next key code.
|
mov si, TailPtr ;Address where we can put next key code.
|
mov [si], cx ;Store the key code away
|
mov [si], cx ;Store the key code away
|
inc si
|
inc si
|
inc si ;Move on to next entry in buf
|
inc si ;Move on to next entry in buf
|
cmp si, EndBuf
|
cmp si, EndBuf
|
jb short NoWrap1
|
jb short NoWrap1
|
mov si, Buffer
|
mov si, Buffer
|
NoWrap1:
|
NoWrap1:
|
mov al, 1 ;no room
|
mov al, 1 ;no room
|
cmp si, HeadPtr ;Data overrun?
|
cmp si, HeadPtr ;Data overrun?
|
je short Exit ;if so, ignore key entry.
|
je short Exit ;if so, ignore key entry.
|
mov TailPtr, si
|
mov TailPtr, si
|
dec ax ;al=0
|
dec ax ;al=0
|
jmp short Exit
|
jmp short Exit
|
|
|
ExtStatus: ; ------- fn 12h - Retrieve the extended keyboard status and return it in AH, and the standard keyboard status in AL.
|
ExtStatus: ; ------- fn 12h - Retrieve the extended keyboard status and return it in AH, and the standard keyboard status in AL.
|
mov al, KbdFlags2
|
mov al, KbdFlags2
|
and al, 01110111b ;Clear final sysreq field, and final right alt bit.
|
and al, 01110111b ;Clear final sysreq field, and final right alt bit.
|
test al, 100b ;Test cur sysreq bit.
|
test al, 100b ;Test cur sysreq bit.
|
jz short NoSysReq ;Skip if it's zero.
|
jz short NoSysReq ;Skip if it's zero.
|
sub al, 10000100b ;Set final sysreq bit, clear final right ctl bit.
|
sub al, 10000100b ;Set final sysreq bit, clear final right ctl bit.
|
NoSysReq:
|
NoSysReq:
|
mov ah, KbdFlags3
|
mov ah, KbdFlags3
|
and ah, 1100b ;Grab rt alt/ctrl bits.
|
and ah, 1100b ;Grab rt alt/ctrl bits.
|
or ah, al ;Merge into AH.
|
or ah, al ;Merge into AH.
|
|
|
GetStatus: ; --------- fn 02h
|
GetStatus: ; --------- fn 02h
|
mov al, KbdFlags1 ;Just return Std Status.
|
mov al, KbdFlags1 ;Just return Std Status.
|
Exit1:
|
Exit1:
|
jmp short Exit
|
jmp short Exit
|
|
|
SetAutoRpt: ; ------ fn 03h
|
SetAutoRpt: ; ------ fn 03h
|
cmp ah, 5
|
cmp ah, 5
|
jne short Exit
|
jne short Exit
|
push dx
|
push dx
|
shl bh, 5
|
shl bh, 5
|
and bl, 1fh
|
and bl, 1fh
|
or bl, bh
|
or bl, bh
|
and bl, 7fh
|
and bl, 7fh
|
mov ah, 0 ; wait LED update progress to finalize
|
mov ah, 0 ; wait LED update progress to finalize
|
call WaitFlag ; leaves with IF=0
|
call WaitFlag ; leaves with IF=0
|
jc short timeout
|
jc short timeout
|
or byte ptr KbdFlags4, SetRepeat ; set auto repeat in progress
|
or byte ptr KbdFlags4, SetRepeat ; set auto repeat in progress
|
mov ah, 0f3h ; set typematic rate and delay
|
mov ah, 0f3h ; set typematic rate and delay
|
push bx
|
push bx
|
xor bl, bl ; send to kb
|
xor bl, bl ; send to kb
|
call sendps2byte
|
call sendps2byte
|
pop bx
|
pop bx
|
jc short timeout1 ; send timeout
|
jc short timeout1 ; send timeout
|
mov ah, SetRepeat or AckReceived ; test if ACK received
|
mov ah, SetRepeat or AckReceived ; test if ACK received
|
call WaitFlag
|
call WaitFlag
|
jc short timeout1
|
jc short timeout1
|
mov ah, bl
|
mov ah, bl
|
xor bl, bl ; send to kb
|
xor bl, bl ; send to kb
|
call sendps2byte ; send data
|
call sendps2byte ; send data
|
timeout1:
|
timeout1:
|
and byte ptr KbdFlags4, not SetRepeat
|
and byte ptr KbdFlags4, not SetRepeat
|
timeout:
|
timeout:
|
pop dx
|
pop dx
|
jmp short Exit1
|
jmp short Exit1
|
|
|
|
|
WaitFlag: ; ah = desired KbdFlags4 & (AckReceived | LEDUpdate | SetRepeat)
|
WaitFlag: ; ah = desired KbdFlags4 & (AckReceived | LEDUpdate | SetRepeat)
|
mov dx, 3dah
|
mov dx, 3dah
|
mov bh, 8*25 ; wait for max 25 * VGA frame time
|
mov bh, 8*25 ; wait for max 25 * VGA frame time
|
wf_loop:
|
wf_loop:
|
cli
|
cli
|
mov al, KbdFlags4
|
mov al, KbdFlags4
|
and al, AckReceived or LEDUpdate or SetRepeat
|
and al, AckReceived or LEDUpdate or SetRepeat
|
cmp al, ah
|
cmp al, ah
|
je short wf_ok ; flag ok, CF=0
|
je short wf_ok ; flag ok, CF=0
|
sti
|
sti
|
in al, dx ; get vblank
|
in al, dx ; get vblank
|
xor al, bh
|
xor al, bh
|
and al, 8h
|
and al, 8h
|
sub bh, al
|
sub bh, al
|
jnc short wf_loop ; IBF - buffer full, no timeout
|
jnc short wf_loop ; IBF - buffer full, no timeout
|
wf_ok:
|
wf_ok:
|
ret
|
ret
|
int16 endp
|
int16 endp
|
|
|
; --------------------- INT 18h - BIOS Basic ------------------
|
; --------------------- INT 18h - BIOS Basic ------------------
|
int18 proc near
|
int18 proc near
|
push cs
|
push cs
|
pop es
|
pop es
|
mov si, offset booterrmsg
|
mov si, offset booterrmsg
|
call prts
|
call prts
|
|
|
;-------------- RS232 bootstrap
|
;-------------- RS232 bootstrap
|
mov al, 0b4h
|
mov al, 0b4h
|
out 43h, al
|
out 43h, al
|
mov ax, 0f000h
|
mov ax, 0f000h
|
out 42h, al
|
out 42h, al
|
out 42h, al ; 18Hz PIT CH2
|
out 42h, al ; 18Hz PIT CH2
|
mov ds,ax
|
mov ds,ax
|
mov es,ax
|
mov es,ax
|
|
|
mov si,100h
|
mov si,100h
|
call srecb
|
call srecb
|
cli
|
cli
|
mov bh,ah
|
mov bh,ah
|
call srecb
|
call srecb
|
mov bl,ah
|
mov bl,ah
|
sloop:
|
sloop:
|
call srecb
|
call srecb
|
mov [si],ah
|
mov [si],ah
|
inc si
|
inc si
|
dec bx
|
dec bx
|
jnz short sloop
|
jnz short sloop
|
db 0eah
|
db 0eah
|
dw 100h,0f000h
|
dw 100h,0f000h
|
|
|
booterrmsg db 'No boot device available, waiting on RS232 (115200bps, f000:100) ...', 13, 10, 0
|
booterrmsg db 'No boot device available, waiting on RS232 (115200bps, f000:100) ...', 13, 10, 0
|
int18 endp
|
int18 endp
|
|
|
; --------------------- INT 19h - OS Bootstrap loader ------------------
|
; --------------------- INT 19h - OS Bootstrap loader ------------------
|
int19 proc near
|
int19 proc near
|
mov ax, 201h
|
mov ax, 201h
|
mov cx, 1
|
mov cx, 1
|
mov dx, 80h
|
mov dx, 80h
|
push 0
|
push 0
|
pop es
|
pop es
|
mov bx, 7c00h
|
mov bx, 7c00h
|
int 13h
|
int 13h
|
jc int19err
|
jc int19err
|
db 0eah
|
db 0eah
|
dw 7c00h, 0 ; jmp far 0000h:7c00h
|
dw 7c00h, 0 ; jmp far 0000h:7c00h
|
int19err:
|
int19err:
|
int 18h
|
int 18h
|
int19 endp
|
int19 endp
|
|
|
|
|
; --------------------- INT 1ah - Get System Time ------------------
|
; --------------------- INT 1ah - Get System Time ------------------
|
int1a proc near
|
int1a proc near
|
push ds
|
push ds
|
push 40h
|
push 40h
|
pop ds
|
pop ds
|
cmp ah, 1
|
cmp ah, 1
|
je setclock
|
|
ja clockexit
|
ja clockexit
|
|
je setclock
|
mov dx, ds:[6ch] ; read clock
|
mov dx, ds:[6ch] ; read clock
|
mov cx, ds:[6eh]
|
mov cx, ds:[6eh]
|
mov al, ds:[70h]
|
mov al, ds:[70h]
|
|
clockexit1:
|
|
mov byte ptr ds:[70h], 0
|
clockexit:
|
clockexit:
|
cmc ; CF = 1 on error
|
cmc ; CF = 1 on error
|
clockexit1:
|
|
pop ds
|
pop ds
|
sti
|
sti
|
retf 2
|
retf 2
|
|
|
setclock:
|
setclock:
|
mov ds:[6ch], dx
|
mov ds:[6ch], dx
|
mov ds:[6eh], cx
|
mov ds:[6eh], cx
|
jmp short clockexit1 ; CF = 0
|
stc
|
|
jmp short clockexit1
|
int1a endp
|
int1a endp
|
|
|
|
|
; --------------------- INT 70h - RTC ------------------
|
; --------------------- INT 70h - RTC ------------------
|
int70 proc near
|
int70 proc near
|
push ds
|
push ds
|
push 40h
|
push 40h
|
pop ds
|
pop ds
|
test byte ptr UWaitFlag, 1 ; is wait in progress?
|
test byte ptr UWaitFlag, 1 ; is wait in progress?
|
jz short exit
|
jz short exit
|
sub word ptr WaitCount[0], 1000
|
sub word ptr WaitCount[0], 1000
|
sbb word ptr WaitCount[2], 0
|
sbb word ptr WaitCount[2], 0
|
jnc short exit
|
jnc short exit
|
mov byte ptr UWaitFlag, 0
|
mov byte ptr UWaitFlag, 0
|
push bx
|
push bx
|
lds bx, UFPtr
|
lds bx, UFPtr
|
or byte ptr [bx], 80h
|
or byte ptr [bx], 80h
|
pop bx
|
pop bx
|
exit:
|
exit:
|
pop ds
|
pop ds
|
iret
|
iret
|
int70 endp
|
int70 endp
|
|
|
|
|
; --------------------- INT 74h - mouse ------------------
|
; --------------------- INT 74h - mouse ------------------
|
int74 proc near
|
int74 proc near
|
cld
|
cld
|
pusha
|
pusha
|
push ds
|
push ds
|
push 40h
|
push 40h
|
pop ds
|
pop ds
|
mov ah, 0
|
mov ah, 0
|
in al, 60h
|
in al, 60h
|
mov bx, ax
|
mov bx, ax
|
inc byte ptr DataCounter
|
inc byte ptr DataCounter
|
mov al, DataCounter
|
mov al, DataCounter
|
mov si, ax
|
mov si, ax
|
sub al, 3
|
sub al, 3
|
ja short docall
|
ja short docall
|
mov DataBuffer[si-1], bl
|
mov DataBuffer[si-1], bl
|
cmp al, PacketSize
|
cmp al, PacketSize
|
jne short nocall
|
jne short nocall
|
mov bl, 0
|
mov bl, 0
|
docall:
|
docall:
|
mov byte ptr DataCounter, bh ; BH=0
|
mov byte ptr DataCounter, bh ; BH=0
|
mov si, offset DataBuffer-2
|
mov si, offset DataBuffer-2
|
lodsw
|
lodsw
|
or ax, [si-4]
|
or ax, [si-4]
|
jz short nocall
|
jz short nocall
|
sti
|
sti
|
push es
|
push es
|
mov ah, 0
|
mov ah, 0
|
lodsb
|
lodsb
|
push ax
|
push ax
|
lodsb
|
lodsb
|
push ax
|
push ax
|
lodsb
|
lodsb
|
push ax
|
push ax
|
push bx
|
push bx
|
call far ptr [si-7]
|
call far ptr [si-7]
|
add sp, 8
|
add sp, 8
|
pop es
|
pop es
|
nocall:
|
nocall:
|
pop ds
|
pop ds
|
popa
|
popa
|
iret
|
iret
|
int74 endp
|
int74 endp
|
|
|
|
|
; ---------------- serial receive byte 115200 bps --------------
|
; ---------------- serial receive byte 115200 bps --------------
|
srecb: mov ah, 80h
|
srecb: mov ah, 80h
|
mov dx, 3dah
|
mov dx, 3dah
|
mov cx, -5aeh ; (half start bit)
|
mov cx, -5aeh ; (half start bit)
|
srstb: in al, dx
|
srstb: in al, dx
|
shr al, 2
|
shr al, 2
|
jc short srstb
|
jc short srstb
|
in al, 42h ; lo counter
|
in al, 42h ; lo counter
|
add ch, al
|
add ch, al
|
in al, 42h ; hi counter, ignore
|
in al, 42h ; hi counter, ignore
|
l1:
|
l1:
|
call dlybit
|
call dlybit
|
in al, dx
|
in al, dx
|
shr al, 2
|
shr al, 2
|
rcr ah, 1
|
rcr ah, 1
|
jnc short l1
|
jnc short l1
|
dlybit:
|
dlybit:
|
sub cx, 0a5bh ; (full bit)
|
sub cx, 0a5bh ; (full bit)
|
dly1:
|
dly1:
|
in al, 42h
|
in al, 42h
|
cmp al, ch
|
cmp al, ch
|
in al, 42h
|
in al, 42h
|
jnz short dly1
|
jnz short dly1
|
ret
|
ret
|
|
|
; -------------------- KB/Mouse access ----------------
|
; -------------------- KB/Mouse access ----------------
|
sendps2byte proc near ; ah=data, bl!=0 for mouse, 0 for kb. returns cf=1 if timeout (al = 8)
|
sendps2byte proc near ; ah=data, bl!=0 for mouse, 0 for kb. returns cf=1 if timeout (al = 8)
|
; changes BH, AL
|
; changes BH, AL
|
push dx
|
push dx
|
mov dx, 3dah
|
mov dx, 3dah
|
mov bh, 8*5
|
mov bh, 8*5
|
sps2b2:
|
sps2b2:
|
in al, 64h
|
in al, 64h
|
test al, 2
|
test al, 2
|
jz short sps2b1; buffer empty
|
jz short sps2b1; buffer empty
|
in al, dx ; get vblank
|
in al, dx ; get vblank
|
xor al, bh
|
xor al, bh
|
and al, 8h
|
and al, 8h
|
sub bh, al
|
sub bh, al
|
jnc short sps2b2; IBF - buffer full, no timeout
|
jnc short sps2b2; IBF - buffer full, no timeout
|
jmp short exit ; timeout, CF=1
|
jmp short exit ; timeout, CF=1
|
sps2b1:
|
sps2b1:
|
test bl, bl ; CF=0
|
test bl, bl ; CF=0
|
jz short sps2_kb
|
jz short sps2_kb
|
mov al, 0d4h ; next mouse
|
mov al, 0d4h ; next mouse
|
out 64h, al
|
out 64h, al
|
sps2_kb:
|
sps2_kb:
|
mov al, ah
|
mov al, ah
|
out 60h, al ; send byte
|
out 60h, al ; send byte
|
exit:
|
exit:
|
pop dx
|
pop dx
|
ret
|
ret
|
sendps2byte endp
|
sendps2byte endp
|
|
|
getps2byte proc near ; returns al=data, zf=0 for mouse, 1 for kb, cf=1 if timeout (al=8)
|
getps2byte proc near ; returns al=data, zf=0 for mouse, 1 for kb, cf=1 if timeout (al=8)
|
; changes BH, DX, AL
|
; changes BH, DX, AL
|
mov dx, 3dah
|
mov dx, 3dah
|
mov bh, 8*5
|
mov bh, 8*5
|
gps2b2:
|
gps2b2:
|
in al, 64h
|
in al, 64h
|
test al, 1
|
test al, 1
|
jnz short gps2b1 ; OBF (buffer full), continue
|
jnz short gps2b1 ; OBF (buffer full), continue
|
in al, dx ; get vblank
|
in al, dx ; get vblank
|
xor al, bh
|
xor al, bh
|
and al, 8
|
and al, 8
|
sub bh, al
|
sub bh, al
|
jnc short gps2b2 ; buffer empty, no timeout
|
jnc short gps2b2 ; buffer empty, no timeout
|
ret ; timeout, CF=1
|
ret ; timeout, CF=1
|
gps2b1:
|
gps2b1:
|
test al, 20h ; CF=0, ZF <- !MOBF
|
test al, 20h ; CF=0, ZF <- !MOBF
|
in al, 60h ; read byte (if IF=1, this data may be invalid)
|
in al, 60h ; read byte (if IF=1, this data may be invalid)
|
ret
|
ret
|
getps2byte endp
|
getps2byte endp
|
|
|
sendcmd proc near ; ah = command, CF=1 for mouse, CF=0 for kb. returns CF=1 on error
|
sendcmd proc near ; ah = command, CF=1 for mouse, CF=0 for kb. returns CF=1 on error
|
sbb bl, bl ; bl <- CF
|
sbb bl, bl ; bl <- CF
|
call sendps2byte
|
call sendps2byte
|
jc short exit
|
jc short exit
|
retry:
|
retry:
|
call getps2byte
|
call getps2byte
|
jc short exit
|
jc short exit
|
cmp al, 0fah ; ack (returns CF=1 on error, when al=8)
|
cmp al, 0fah ; ack (returns CF=1 on error, when al=8)
|
jne short retry
|
jne short retry
|
exit:
|
exit:
|
ret
|
ret
|
sendcmd endp
|
sendcmd endp
|
|
|
enableKbIfPresent proc near ; input DS = 40h
|
enableKbIfPresent proc near ; input DS = 40h
|
; modify AL, flags
|
; modify AL, flags
|
test byte ptr KbdFlags3, 10h
|
test byte ptr KbdFlags3, 10h
|
jz short noenablekb
|
jz short noenablekb
|
mov al, 0aeh
|
mov al, 0aeh
|
out 64h, al ; enable kb interface
|
out 64h, al ; enable kb interface
|
noenablekb:
|
noenablekb:
|
ret
|
ret
|
enableKbIfPresent endp
|
enableKbIfPresent endp
|
|
|
; ----------------------- default interrupt handler ---------------
|
; ----------------------- default interrupt handler ---------------
|
defint proc near
|
defint proc near
|
iret
|
iret
|
defint endp
|
defint endp
|
|
|
; ------------------------------- flush --------------------------
|
; ------------------------------- flush --------------------------
|
flush:
|
flush:
|
pop cs:flushret
|
pop cs:flushret
|
flush_nostack:
|
flush_nostack:
|
mov cs:flushbh, bh
|
mov cs:flushbh, bh
|
mov bh, 7 ; flush all 7 cache lines (the 8th one is CS:IP)
|
mov bh, 7 ; flush all 7 cache lines (the 8th one is CS:IP)
|
flush1:
|
flush1:
|
test bl, cs:[bx + 0e000h]
|
test bl, cs:[bx + 0e000h]
|
dec bh
|
dec bh
|
jnz short flush1
|
jnz short flush1
|
mov bh, cs:flushbh
|
mov bh, cs:flushbh
|
jmp word ptr cs:flushret
|
jmp word ptr cs:flushret
|
flushret dw 0
|
flushret dw 0
|
flushbh db 0
|
flushbh db 0
|
|
|
; ------------------------------- misc --------------------------
|
; ------------------------------- misc --------------------------
|
dispAX:
|
dispAX:
|
push dx
|
push dx
|
xor dx, dx
|
xor dx, dx
|
div word ptr cs:ten
|
div word ptr cs:ten
|
test ax, ax
|
test ax, ax
|
jz dispAX1
|
jz dispAX1
|
call dispAX
|
call dispAX
|
dispAX1:
|
dispAX1:
|
xchg ax, dx
|
xchg ax, dx
|
add ax, 0e00h + '0'
|
add ax, 0e00h + '0'
|
int 10h
|
int 10h
|
pop dx
|
pop dx
|
ret
|
ret
|
ten dw 10
|
ten dw 10
|
|
|
prts: ; es:si = string
|
prts: ; es:si = string
|
mov ah, 0eh
|
mov ah, 0eh
|
lodsb es:[si]
|
lodsb es:[si]
|
or al, al
|
or al, al
|
jz short prtse
|
jz short prtse
|
int 10h
|
int 10h
|
jmp short prts
|
jmp short prts
|
prtse:
|
prtse:
|
ret
|
ret
|
|
|
|
|
|
|
;--------------------- read/write byte ----------------------
|
;--------------------- read/write byte ----------------------
|
sdrb: mov al,0ffh
|
sdrb: mov al,0ffh
|
sdsb: ; in AL=byte, DX = 03dah, out AX=result
|
sdsb: ; in AL=byte, DX = 03dah, out AX=result
|
out dx, al
|
out dx, al
|
add ax, ax
|
add ax, ax
|
out dx, al
|
out dx, al
|
add ax, ax
|
add ax, ax
|
out dx, al
|
out dx, al
|
add ax, ax
|
add ax, ax
|
out dx, al
|
out dx, al
|
add ax, ax
|
add ax, ax
|
out dx, al
|
out dx, al
|
add ax, ax
|
add ax, ax
|
out dx, al
|
out dx, al
|
add ax, ax
|
add ax, ax
|
out dx, al
|
out dx, al
|
add ax, ax
|
add ax, ax
|
out dx, al
|
out dx, al
|
in ax, dx
|
in ax, dx
|
ret
|
ret
|
|
|
;--------------------- write block ----------------------
|
;--------------------- write block ----------------------
|
sdwblk proc near ; in SI=data ptr, DX=03dah, CX=size
|
sdwblk proc near ; in SI=data ptr, DX=03dah, CX=size
|
shr cx, 1
|
shr cx, 1
|
sdwblk1:
|
sdwblk1:
|
lodsb
|
lodsb
|
out dx, al
|
out dx, al
|
add ax, ax
|
add ax, ax
|
out dx, al
|
out dx, al
|
add ax, ax
|
add ax, ax
|
out dx, al
|
out dx, al
|
add ax, ax
|
add ax, ax
|
out dx, al
|
out dx, al
|
add ax, ax
|
add ax, ax
|
out dx, al
|
out dx, al
|
add ax, ax
|
add ax, ax
|
out dx, al
|
out dx, al
|
add ax, ax
|
add ax, ax
|
out dx, al
|
out dx, al
|
add ax, ax
|
add ax, ax
|
out dx, al
|
out dx, al
|
lodsb
|
lodsb
|
out dx, al
|
out dx, al
|
add ax, ax
|
add ax, ax
|
out dx, al
|
out dx, al
|
add ax, ax
|
add ax, ax
|
out dx, al
|
out dx, al
|
add ax, ax
|
add ax, ax
|
out dx, al
|
out dx, al
|
add ax, ax
|
add ax, ax
|
out dx, al
|
out dx, al
|
add ax, ax
|
add ax, ax
|
out dx, al
|
out dx, al
|
add ax, ax
|
add ax, ax
|
out dx, al
|
out dx, al
|
add ax, ax
|
add ax, ax
|
out dx, al
|
out dx, al
|
loop short sdwblk1
|
loop short sdwblk1
|
ret
|
ret
|
sdwblk endp
|
sdwblk endp
|
|
|
;--------------------- read block ----------------------
|
;--------------------- read block ----------------------
|
sdrblk proc near ; in DI=data ptr, DX=03dah, CX=size. Returns CF = 0
|
sdrblk proc near ; in DI=data ptr, DX=03dah, CX=size. Returns CF = 0
|
mov al, 0ffh
|
mov al, 0ffh
|
out dx, al
|
out dx, al
|
shr cx, 1 ; CF = 0
|
shr cx, 1 ; CF = 0
|
out dx, al
|
out dx, al
|
jmp short sdrblk2
|
jmp short sdrblk2
|
sdrblk1:
|
sdrblk1:
|
out dx, al
|
out dx, al
|
mov [di], ah
|
mov [di], ah
|
out dx, al
|
out dx, al
|
inc di
|
inc di
|
sdrblk2:
|
sdrblk2:
|
out dx, al
|
out dx, al
|
nop
|
nop
|
out dx, al
|
out dx, al
|
nop
|
nop
|
out dx, al
|
out dx, al
|
nop
|
nop
|
out dx, al
|
out dx, al
|
nop
|
nop
|
out dx, al
|
out dx, al
|
nop
|
nop
|
out dx, al
|
out dx, al
|
in ax, dx
|
in ax, dx
|
out dx, al
|
out dx, al
|
mov [di], ah
|
mov [di], ah
|
out dx, al
|
out dx, al
|
inc di
|
inc di
|
out dx, al
|
out dx, al
|
nop
|
nop
|
out dx, al
|
out dx, al
|
nop
|
nop
|
out dx, al
|
out dx, al
|
nop
|
nop
|
out dx, al
|
out dx, al
|
nop
|
nop
|
out dx, al
|
out dx, al
|
nop
|
nop
|
out dx, al
|
out dx, al
|
in ax, dx
|
in ax, dx
|
loop short sdrblk1
|
loop short sdrblk1
|
mov [di], ah
|
mov [di], ah
|
inc di
|
inc di
|
ret
|
ret
|
sdrblk endp
|
sdrblk endp
|
|
|
;--------------------- verify block ----------------------
|
;--------------------- verify block ----------------------
|
sdvblk: ; in DI=data ptr, DX=03dah, CX=size. Returns CF=1 on error
|
sdvblk: ; in DI=data ptr, DX=03dah, CX=size. Returns CF=1 on error
|
push bx
|
push bx
|
xor bl, bl
|
xor bl, bl
|
sdvblk1:
|
sdvblk1:
|
call sdrb
|
call sdrb
|
sub ah, [di]
|
sub ah, [di]
|
or bl, ah
|
or bl, ah
|
inc di
|
inc di
|
loop short sdvblk1
|
loop short sdvblk1
|
neg bl ; CF=1 if BL != 0
|
neg bl ; CF=1 if BL != 0
|
pop bx
|
pop bx
|
ret
|
ret
|
|
|
;--------------------- write command ----------------------
|
;--------------------- write command ----------------------
|
sdcmd8T:
|
sdcmd8T:
|
call sdrb
|
call sdrb
|
sdcmd: ; in SI=6 bytes cmd buffer, DX=03dah, out AH = 0ffh on error
|
sdcmd: ; in SI=6 bytes cmd buffer, DX=03dah, out AH = 0ffh on error
|
mov cx, 6
|
mov cx, 6
|
call sdwblk
|
call sdwblk
|
sdresp:
|
sdresp:
|
xor si, si
|
xor si, si
|
sdresp1:
|
sdresp1:
|
call sdrb
|
call sdrb
|
inc si
|
inc si
|
jz short sdcmd1
|
jz short sdcmd1
|
cmp ah, 0ffh
|
cmp ah, 0ffh
|
je short sdresp1
|
je short sdresp1
|
sdcmd1: ret
|
sdcmd1: ret
|
|
|
;--------------------- read ----------------------
|
;--------------------- read ----------------------
|
sdverify:
|
sdverify:
|
push sdvblk
|
push sdvblk
|
jmp short sdread1
|
jmp short sdread1
|
sdread: ; DX:AX sector, ES:BX buffer, CX=sectors. returns AX=read sectors
|
sdread: ; DX:AX sector, ES:BX buffer, CX=sectors. returns AX=read sectors
|
push sdrblk ; push proc address (read or verify) on stack
|
push sdrblk ; push proc address (read or verify) on stack
|
sdread1:
|
sdread1:
|
push ax
|
push ax
|
mov al, dl
|
mov al, dl
|
push ax
|
push ax
|
mov dl, 51h ; CMD17
|
mov dl, 51h ; CMD17
|
cmp cx, 1
|
cmp cx, 1
|
je short sdr1s
|
je short sdr1s
|
inc dx ; CMD18 - multiple sectors
|
inc dx ; CMD18 - multiple sectors
|
sdr1s:
|
sdr1s:
|
push dx
|
push dx
|
mov si, sp
|
mov si, sp
|
|
|
mov dx, 3dah
|
mov dx, 3dah
|
mov ah, 1
|
mov ah, 1
|
out dx, ax ; CS on
|
out dx, ax ; CS on
|
mov di, bx
|
mov di, bx
|
mov bx, cx
|
mov bx, cx
|
mov bp, cx ; save sectors number
|
mov bp, cx ; save sectors number
|
push ss
|
push ss
|
pop ds
|
pop ds
|
call sdcmd
|
call sdcmd
|
add sp, 6
|
add sp, 6
|
or ah, ah
|
or ah, ah
|
jnz short sdr11 ; error
|
jnz short sdr11 ; error
|
push es
|
push es
|
pop ds
|
pop ds
|
sdrms:
|
sdrms:
|
mov ax, di
|
mov ax, di
|
shr ax, 4
|
shr ax, 4
|
mov si, ds
|
mov si, ds
|
add ax, si
|
add ax, si
|
mov ds, ax
|
mov ds, ax
|
and di, 15
|
and di, 15
|
call sdresp ; wait for 0feh token
|
call sdresp ; wait for 0feh token
|
cmp ah, 0feh
|
cmp ah, 0feh
|
jne short sdr11; read token error
|
jne short sdr11; read token error
|
mov ch, 2 ; 512 byte sector
|
mov ch, 2 ; 512 byte sector
|
pop si
|
pop si
|
call si ; sdrblk or sdvblk
|
call si ; sdrblk or sdvblk
|
push si
|
push si
|
pushf
|
pushf
|
call sdrb ; ignore CRC
|
call sdrb ; ignore CRC
|
call sdrb ; ignore CRC
|
call sdrb ; ignore CRC
|
popf
|
popf
|
jc short sdr3 ; verify error
|
jc short sdr3 ; verify error
|
dec bx
|
dec bx
|
jnz short sdrms; multiple sectors
|
jnz short sdrms; multiple sectors
|
sdr3:
|
sdr3:
|
cmp bp, 1
|
cmp bp, 1
|
je short sdr11; single sector
|
je short sdr11; single sector
|
mov si, offset SD_CMD12 ; stop transfer
|
mov si, offset SD_CMD12 ; stop transfer
|
push cs
|
push cs
|
pop ds
|
pop ds
|
call sdcmd
|
call sdcmd
|
sdr2:
|
sdr2:
|
shr ah, 1
|
shr ah, 1
|
jnc short sdr11
|
jnc short sdr11
|
call sdrb
|
call sdrb
|
jmp short sdr2
|
jmp short sdr2
|
sdr11:
|
sdr11:
|
pop ax ; remove proc address from stack
|
pop ax ; remove proc address from stack
|
sdr1:
|
sdr1:
|
xor ax, ax
|
xor ax, ax
|
out dx, ax
|
out dx, ax
|
call sdrb ; 8T
|
call sdrb ; 8T
|
mov ax, bp
|
mov ax, bp
|
sub ax, bx
|
sub ax, bx
|
ret
|
ret
|
|
|
;--------------------- write ----------------------
|
;--------------------- write ----------------------
|
sdwrite: ; DX:AX sector, ES:BX buffer, CX=sectors, returns AX=wrote sectors
|
sdwrite: ; DX:AX sector, ES:BX buffer, CX=sectors, returns AX=wrote sectors
|
push ax
|
push ax
|
mov al, dl
|
mov al, dl
|
push ax
|
push ax
|
mov dl, 58h ; CMD24
|
mov dl, 58h ; CMD24
|
cmp cx, 1
|
cmp cx, 1
|
je short sdw1s
|
je short sdw1s
|
inc dx ; CMD25 - multiple sectors
|
inc dx ; CMD25 - multiple sectors
|
sdw1s:
|
sdw1s:
|
push dx
|
push dx
|
mov si, sp
|
mov si, sp
|
|
|
mov dx, 3dah
|
mov dx, 3dah
|
mov ah, 1
|
mov ah, 1
|
out dx, ax ; CS on
|
out dx, ax ; CS on
|
mov bp, cx ; save sectors number
|
mov bp, cx ; save sectors number
|
push ss
|
push ss
|
pop ds
|
pop ds
|
call sdcmd
|
call sdcmd
|
add sp, 6
|
add sp, 6
|
mov si, bx
|
mov si, bx
|
mov bx, bp
|
mov bx, bp
|
or ah, ah
|
or ah, ah
|
jnz short sdr1 ; error
|
jnz short sdr1 ; error
|
push es
|
push es
|
pop ds
|
pop ds
|
sdwms:
|
sdwms:
|
mov ax, si
|
mov ax, si
|
shr ax, 4
|
shr ax, 4
|
mov di, ds
|
mov di, ds
|
add ax, di
|
add ax, di
|
mov ds, ax
|
mov ds, ax
|
and si, 15
|
and si, 15
|
mov al, 0feh ; start token
|
mov al, 0feh ; start token
|
cmp bp, 1
|
cmp bp, 1
|
je short sdw1s1
|
je short sdw1s1
|
mov al, 0fch ; multiple sectors
|
mov al, 0fch ; multiple sectors
|
sdw1s1:
|
sdw1s1:
|
call sdsb
|
call sdsb
|
mov ch, 2 ; 512 byte sector
|
mov ch, 2 ; 512 byte sector
|
call sdwblk
|
call sdwblk
|
call sdrb ; ignore CRC
|
call sdrb ; ignore CRC
|
call sdrb ; ignore CRC
|
call sdrb ; ignore CRC
|
call sdrb ; read response byte xxx00101
|
call sdrb ; read response byte xxx00101
|
and ah, 0eh
|
and ah, 0eh
|
cmp ah, 4
|
cmp ah, 4
|
jne short sdr1 ; write error
|
jne short sdr1 ; write error
|
sdwwait:
|
sdwwait:
|
call sdrb
|
call sdrb
|
shr ah, 1
|
shr ah, 1
|
jnc short sdwwait ; wait write completion
|
jnc short sdwwait ; wait write completion
|
dec bx
|
dec bx
|
jnz short sdwms ; multiple sectors
|
jnz short sdwms ; multiple sectors
|
|
|
cmp bp, 1
|
cmp bp, 1
|
je short sdr1
|
je short sdr1
|
mov al, 0fdh ; multiple end transfer
|
mov al, 0fdh ; multiple end transfer
|
call sdsb
|
call sdsb
|
sdwwait1:
|
sdwwait1:
|
call sdrb
|
call sdrb
|
shr ah, 1
|
shr ah, 1
|
jnc short sdwwait1 ; wait write completion
|
jnc short sdwwait1 ; wait write completion
|
jmp sdr1
|
jmp sdr1
|
|
|
;--------------------- init SD ----------------------
|
;--------------------- init SD ----------------------
|
sdinit proc near ; returns AX = num kilosectors
|
sdinit proc near ; returns AX = num kilosectors
|
push ds
|
push ds
|
push cx
|
push cx
|
push dx
|
push dx
|
push si
|
push si
|
push di
|
push di
|
mov dx, 3dah
|
mov dx, 3dah
|
mov cx, 10
|
mov cx, 10
|
sdinit1: ; send 80T
|
sdinit1: ; send 80T
|
call sdrb
|
call sdrb
|
loop short sdinit1
|
loop short sdinit1
|
|
|
mov ah, 1
|
mov ah, 1
|
out dx, ax ; select SD
|
out dx, ax ; select SD
|
|
|
mov si, offset SD_CMD0
|
mov si, offset SD_CMD0
|
push cs
|
push cs
|
pop ds
|
pop ds
|
call sdcmd
|
call sdcmd
|
dec ah
|
dec ah
|
jnz short sdexit ; error
|
jnz short sdexit ; error
|
|
|
mov si, offset SD_CMD8
|
mov si, offset SD_CMD8
|
call sdcmd8T
|
call sdcmd8T
|
dec ah
|
dec ah
|
jnz short sdexit ; error
|
jnz short sdexit ; error
|
mov cl, 4
|
mov cl, 4
|
sub sp, cx
|
sub sp, cx
|
mov di, sp
|
mov di, sp
|
push ss
|
push ss
|
pop ds
|
pop ds
|
call sdrblk
|
call sdrblk
|
pop ax
|
pop ax
|
pop ax
|
pop ax
|
cmp ah, 0aah
|
cmp ah, 0aah
|
jne short sdexit ; CMD8 error
|
jne short sdexit ; CMD8 error
|
repinit:
|
repinit:
|
mov si, offset SD_CMD55
|
mov si, offset SD_CMD55
|
push cs
|
push cs
|
pop ds
|
pop ds
|
call sdcmd8T
|
call sdcmd8T
|
call sdrb
|
call sdrb
|
mov si, offset SD_CMD41
|
mov si, offset SD_CMD41
|
call sdcmd
|
call sdcmd
|
dec ah
|
dec ah
|
jz short repinit
|
jz short repinit
|
|
|
mov si, offset SD_CMD58
|
mov si, offset SD_CMD58
|
call sdcmd8T
|
call sdcmd8T
|
mov cl, 4
|
mov cl, 4
|
sub sp, cx
|
sub sp, cx
|
mov di, sp
|
mov di, sp
|
push ss
|
push ss
|
pop ds
|
pop ds
|
call sdrblk
|
call sdrblk
|
pop ax
|
pop ax
|
test al, 40h ; test OCR bit 30 (CCS)
|
test al, 40h ; test OCR bit 30 (CCS)
|
pop ax
|
pop ax
|
jz short sdexit; no SDHC
|
jz short sdexit; no SDHC
|
|
|
mov si, offset SD_CMD9 ; get size info
|
mov si, offset SD_CMD9 ; get size info
|
push cs
|
push cs
|
pop ds
|
pop ds
|
call sdcmd8T
|
call sdcmd8T
|
or ah, ah
|
or ah, ah
|
jnz short sdexit
|
jnz short sdexit
|
call sdresp ; wait for 0feh token
|
call sdresp ; wait for 0feh token
|
cmp ah, 0feh
|
cmp ah, 0feh
|
jne short sdexit
|
jne short sdexit
|
mov cl, 18 ; 16bytes + 2bytes CRC
|
mov cl, 18 ; 16bytes + 2bytes CRC
|
sub sp, cx
|
sub sp, cx
|
mov di, sp
|
mov di, sp
|
push ss
|
push ss
|
pop ds
|
pop ds
|
call sdrblk
|
call sdrblk
|
mov cx, [di-10]
|
mov cx, [di-10]
|
rol cx, 8
|
rol cx, 8
|
inc cx
|
inc cx
|
mov sp, di
|
mov sp, di
|
sdexit:
|
sdexit:
|
xor ax, ax ; raise CS
|
xor ax, ax ; raise CS
|
out dx, ax
|
out dx, ax
|
call sdrb
|
call sdrb
|
pop di
|
pop di
|
pop si
|
pop si
|
pop dx
|
pop dx
|
mov ax, cx
|
mov ax, cx
|
pop cx
|
pop cx
|
pop ds
|
pop ds
|
ret
|
ret
|
sdinit endp
|
sdinit endp
|
|
|
SD_CMD0 db 40h, 0, 0, 0, 0, 95h
|
SD_CMD0 db 40h, 0, 0, 0, 0, 95h
|
SD_CMD8 db 48h, 0, 0, 1, 0aah, 087h
|
SD_CMD8 db 48h, 0, 0, 1, 0aah, 087h
|
SD_CMD9 db 49h, 0, 0, 0, 0, 0ffh
|
SD_CMD9 db 49h, 0, 0, 0, 0, 0ffh
|
SD_CMD12 db 4ch, 0, 0, 0, 0, 0ffh
|
SD_CMD12 db 4ch, 0, 0, 0, 0, 0ffh
|
SD_CMD41 db 69h, 40h, 0, 0, 0, 0ffh
|
SD_CMD41 db 69h, 40h, 0, 0, 0, 0ffh
|
SD_CMD55 db 77h, 0, 0, 0, 0, 0ffh
|
SD_CMD55 db 77h, 0, 0, 0, 0, 0ffh
|
SD_CMD58 db 7ah, 0, 0, 0, 0, 0ffh
|
SD_CMD58 db 7ah, 0, 0, 0, 0, 0ffh
|
|
|
|
|
default_pal:
|
default_pal:
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
|
|
IFDEF SCANCODE1 ; use SCANCODE1
|
IFDEF SCANCODE1 ; use SCANCODE1
|
KeyIndex:
|
KeyIndex:
|
db 0, 82, 49, 50, 52, 51, 54, 55 ;0-7
|
db 0, 82, 49, 50, 52, 51, 54, 55 ;0-7
|
db 56, 57, 60, 59, 65, 68, 72, 47 ;8-f
|
db 56, 57, 60, 59, 65, 68, 72, 47 ;8-f
|
db 1, 5, 9, 13, 12, 18, 21, 23 ;10-17
|
db 1, 5, 9, 13, 12, 18, 21, 23 ;10-17
|
db 24, 26, 67, 70, 69, 0, 4, 3 ;18-1f
|
db 24, 26, 67, 70, 69, 0, 4, 3 ;18-1f
|
db 8, 11, 17, 16, 20, 22, 25, 64 ;20-27
|
db 8, 11, 17, 16, 20, 22, 25, 64 ;20-27
|
db 66, 48, 0, 71, 2, 7, 6, 10 ;28-2f
|
db 66, 48, 0, 71, 2, 7, 6, 10 ;28-2f
|
db 15, 14, 19, 58, 61, 62, 0, 87 ;30-37
|
db 15, 14, 19, 58, 61, 62, 0, 87 ;30-37
|
db 0, 53, 0, 40, 41, 39, 46, 38 ;38-3f
|
db 0, 53, 0, 40, 41, 39, 46, 38 ;38-3f
|
db 45, 90, 44, 79, 43, 0, 89, 29 ;40-47
|
db 45, 90, 44, 79, 43, 0, 89, 29 ;40-47
|
db 34, 36, 86, 28, 37, 33, 84, 27 ;48-4f
|
db 34, 36, 86, 28, 37, 33, 84, 27 ;48-4f
|
db 32, 35, 30, 31, 0, 0, 0, 83 ;50-57
|
db 32, 35, 30, 31, 0, 0, 0, 83 ;50-57
|
db 42
|
db 42
|
E0KeyList:
|
E0KeyList:
|
db 35h, 1ch, 4fh, 4bh, 47h, 52h, 53h, 50h, 4dh, 48h, 51h, 49h
|
db 35h, 1ch, 4fh, 4bh, 47h, 52h, 53h, 50h, 4dh, 48h, 51h, 49h
|
|
|
ELSE ; use SCANCODE2
|
ELSE ; use SCANCODE2
|
|
|
KeyIndex:
|
KeyIndex:
|
db 0, 79, 0, 38, 39, 40, 41, 42
|
db 0, 79, 0, 38, 39, 40, 41, 42
|
db 0, 43, 44, 45, 46, 47, 48, 0
|
db 0, 43, 44, 45, 46, 47, 48, 0
|
db 0, 0, 0, 0, 0, 1, 49, 0
|
db 0, 0, 0, 0, 0, 1, 49, 0
|
db 0, 0, 2, 3, 4, 5, 50, 0
|
db 0, 0, 2, 3, 4, 5, 50, 0
|
db 0, 6, 7, 8, 9, 51, 52, 0
|
db 0, 6, 7, 8, 9, 51, 52, 0
|
db 0, 53, 10, 11, 12, 13, 54, 0
|
db 0, 53, 10, 11, 12, 13, 54, 0
|
db 0, 14, 15, 16, 17, 18, 55, 0
|
db 0, 14, 15, 16, 17, 18, 55, 0
|
db 0, 0, 19, 20, 21, 56, 57, 0
|
db 0, 0, 19, 20, 21, 56, 57, 0
|
db 0, 58, 22, 23, 24, 59, 60, 0
|
db 0, 58, 22, 23, 24, 59, 60, 0
|
db 0, 61, 62, 25, 64, 26, 65, 0
|
db 0, 61, 62, 25, 64, 26, 65, 0
|
db 0, 0, 66, 0, 67, 68, 0, 0
|
db 0, 0, 66, 0, 67, 68, 0, 0
|
db 0, 0, 69, 70, 0, 71, 0, 0
|
db 0, 0, 69, 70, 0, 71, 0, 0
|
db 0, 0, 0, 0, 0, 0, 72, 0
|
db 0, 0, 0, 0, 0, 0, 72, 0
|
db 0, 27, 0, 28, 29, 0, 0, 0
|
db 0, 27, 0, 28, 29, 0, 0, 0
|
db 30, 31, 32, 37, 33, 34, 82, 0
|
db 30, 31, 32, 37, 33, 34, 82, 0
|
db 83, 84, 35, 86, 87, 36, 89, 0
|
db 83, 84, 35, 86, 87, 36, 89, 0
|
db 0, 0, 0, 90
|
db 0, 0, 0, 90
|
E0KeyList:
|
E0KeyList:
|
db 4ah, 5ah, 69h, 6bh, 6ch, 70h, 71h, 72h, 74h, 75h, 7ah, 7dh
|
db 4ah, 5ah, 69h, 6bh, 6ch, 70h, 71h, 72h, 74h, 75h, 7ah, 7dh
|
|
|
ENDIF
|
ENDIF
|
|
|
E0KeyIndex:
|
E0KeyIndex:
|
db 63, 69, 73, 74, 75, 76, 77, 78, 80, 81, 85, 88
|
db 63, 69, 73, 74, 75, 76, 77, 78, 80, 81, 85, 88
|
|
|
KeyCode:
|
KeyCode:
|
; Keys affected by CapsLock
|
; Keys affected by CapsLock
|
; norm shft ctrl alt
|
; norm shft ctrl alt
|
dw 0000h, 0000h, 0000h, 0000h ;17 - <0>
|
dw 0000h, 0000h, 0000h, 0000h ;17 - <0>
|
dw 1071h, 1051h, 1011h, 1000h ;15 - Q, (E0)PrevTrack <1>
|
dw 1071h, 1051h, 1011h, 1000h ;15 - Q, (E0)PrevTrack <1>
|
dw 2c7ah, 2c5ah, 2c1ah, 2c00h ;1a - Z <2>
|
dw 2c7ah, 2c5ah, 2c1ah, 2c00h ;1a - Z <2>
|
dw 1f73h, 1f53h, 1f13h, 1f00h ;1b - S <3>
|
dw 1f73h, 1f53h, 1f13h, 1f00h ;1b - S <3>
|
dw 1e61h, 1e41h, 1e01h, 1e00h ;1c - A <4>
|
dw 1e61h, 1e41h, 1e01h, 1e00h ;1c - A <4>
|
dw 1177h, 1157h, 1117h, 1100h ;1d - W <5>
|
dw 1177h, 1157h, 1117h, 1100h ;1d - W <5>
|
dw 2e63h, 2e43h, 2e03h, 2e00h ;21 - C, (E0)Volume Down <6>
|
dw 2e63h, 2e43h, 2e03h, 2e00h ;21 - C, (E0)Volume Down <6>
|
dw 2d78h, 2d58h, 2d18h, 2d00h ;22 - X <7>
|
dw 2d78h, 2d58h, 2d18h, 2d00h ;22 - X <7>
|
dw 2064h, 2044h, 2004h, 2000h ;23 - D, (E0)Mute <8>
|
dw 2064h, 2044h, 2004h, 2000h ;23 - D, (E0)Mute <8>
|
dw 1265h, 1245h, 1205h, 1200h ;24 - E <9>
|
dw 1265h, 1245h, 1205h, 1200h ;24 - E <9>
|
dw 2f76h, 2f56h, 2f16h, 2f00h ;2a - V <10>
|
dw 2f76h, 2f56h, 2f16h, 2f00h ;2a - V <10>
|
dw 2166h, 2146h, 2106h, 2100h ;2b - F, (E0)Calculator <11>
|
dw 2166h, 2146h, 2106h, 2100h ;2b - F, (E0)Calculator <11>
|
dw 1474h, 1454h, 1414h, 1400h ;2c - T <12>
|
dw 1474h, 1454h, 1414h, 1400h ;2c - T <12>
|
dw 1372h, 1352h, 1312h, 1300h ;2d - R <13>
|
dw 1372h, 1352h, 1312h, 1300h ;2d - R <13>
|
dw 316eh, 314eh, 310eh, 3100h ;31 - N <14>
|
dw 316eh, 314eh, 310eh, 3100h ;31 - N <14>
|
dw 3062h, 3042h, 3002h, 3000h ;32 - B, (E0)Volume Up <15>
|
dw 3062h, 3042h, 3002h, 3000h ;32 - B, (E0)Volume Up <15>
|
dw 2368h, 2348h, 2308h, 2300h ;33 - H <16>
|
dw 2368h, 2348h, 2308h, 2300h ;33 - H <16>
|
dw 2267h, 2247h, 2207h, 2200h ;34 - G, (E0)Play/Pause <17>
|
dw 2267h, 2247h, 2207h, 2200h ;34 - G, (E0)Play/Pause <17>
|
dw 1579h, 1559h, 1519h, 1500h ;35 - Y <18>
|
dw 1579h, 1559h, 1519h, 1500h ;35 - Y <18>
|
dw 326dh, 324dh, 320dh, 3200h ;3a - M, (E0)WWW Home <19>
|
dw 326dh, 324dh, 320dh, 3200h ;3a - M, (E0)WWW Home <19>
|
dw 246ah, 244ah, 240ah, 2400h ;3b - J, (E0)Stop <20>
|
dw 246ah, 244ah, 240ah, 2400h ;3b - J, (E0)Stop <20>
|
dw 1675h, 1655h, 1615h, 1600h ;3c - U <21>
|
dw 1675h, 1655h, 1615h, 1600h ;3c - U <21>
|
dw 256bh, 254bh, 250bh, 2500h ;42 - K <22>
|
dw 256bh, 254bh, 250bh, 2500h ;42 - K <22>
|
dw 1769h, 1749h, 1709h, 1700h ;43 - I <23>
|
dw 1769h, 1749h, 1709h, 1700h ;43 - I <23>
|
dw 186fh, 184fh, 180fh, 1800h ;44 - O <24>
|
dw 186fh, 184fh, 180fh, 1800h ;44 - O <24>
|
dw 266ch, 264ch, 260ch, 2600h ;4b - L <25>
|
dw 266ch, 264ch, 260ch, 2600h ;4b - L <25>
|
dw 1970h, 1950h, 1910h, 1900h ;4d - P, (E0)Next Track <26>
|
dw 1970h, 1950h, 1910h, 1900h ;4d - P, (E0)Next Track <26>
|
; keys affected by NumLock
|
; keys affected by NumLock
|
dw 4f00h, 4f31h, 7500h, 0002h ;69 - KP1 <27>
|
dw 4f00h, 4f31h, 7500h, 0002h ;69 - KP1 <27>
|
dw 4b00h, 4b34h, 7300h, 0005h ;6b - KP4 <28>
|
dw 4b00h, 4b34h, 7300h, 0005h ;6b - KP4 <28>
|
dw 4700h, 4737h, 7700h, 0008h ;6c - KP7 <29>
|
dw 4700h, 4737h, 7700h, 0008h ;6c - KP7 <29>
|
dw 5200h, 5230h, 9200h, 0001h ;70 - KP0 <30>
|
dw 5200h, 5230h, 9200h, 0001h ;70 - KP0 <30>
|
dw 5300h, 532eh, 9300h, 0000h ;71 - KP. <31>
|
dw 5300h, 532eh, 9300h, 0000h ;71 - KP. <31>
|
dw 5000h, 5032h, 9100h, 0003h ;72 - KP2 <32>
|
dw 5000h, 5032h, 9100h, 0003h ;72 - KP2 <32>
|
dw 4d00h, 4d36h, 7400h, 0007h ;74 - KP6 <33>
|
dw 4d00h, 4d36h, 7400h, 0007h ;74 - KP6 <33>
|
dw 4800h, 4838h, 8d00h, 0009h ;75 - KP8 <34>
|
dw 4800h, 4838h, 8d00h, 0009h ;75 - KP8 <34>
|
dw 5100h, 5133h, 7600h, 0004h ;7a - KP3 <35>
|
dw 5100h, 5133h, 7600h, 0004h ;7a - KP3 <35>
|
dw 4900h, 4939h, 8400h, 000ah ;7d - KP9 <36>
|
dw 4900h, 4939h, 8400h, 000ah ;7d - KP9 <36>
|
dw 4c00h, 4c35h, 8f00h, 0006h ;73 - KP5 --- on VMWare, it does not send 4c00 <37>
|
dw 4c00h, 4c35h, 8f00h, 0006h ;73 - KP5 --- on VMWare, it does not send 4c00 <37>
|
; keys unaffected by CapsLock or N
|
; keys unaffected by CapsLock or N
|
dw 3f00h, 5800h, 6200h, 6c00h ;03 - F5 <38>
|
dw 3f00h, 5800h, 6200h, 6c00h ;03 - F5 <38>
|
dw 3d00h, 5600h, 6000h, 6a00h ;04 - F3 <39>
|
dw 3d00h, 5600h, 6000h, 6a00h ;04 - F3 <39>
|
dw 3b00h, 5400h, 5e00h, 6800h ;05 - F1 <40>
|
dw 3b00h, 5400h, 5e00h, 6800h ;05 - F1 <40>
|
dw 3c00h, 5500h, 5f00h, 6900h ;06 - F2 <41>
|
dw 3c00h, 5500h, 5f00h, 6900h ;06 - F2 <41>
|
dw 8600h, 8800h, 8a00h, 8c00h ;07 - F12 <42>
|
dw 8600h, 8800h, 8a00h, 8c00h ;07 - F12 <42>
|
dw 4400h, 5d00h, 6700h, 7100h ;09 - F10 <43>
|
dw 4400h, 5d00h, 6700h, 7100h ;09 - F10 <43>
|
dw 4200h, 5b00h, 6500h, 6f00h ;0a - F8 <44>
|
dw 4200h, 5b00h, 6500h, 6f00h ;0a - F8 <44>
|
dw 4000h, 5900h, 6300h, 6d00h ;0b - F6 <45>
|
dw 4000h, 5900h, 6300h, 6d00h ;0b - F6 <45>
|
dw 3e00h, 5700h, 6100h, 6b00h ;0c - F4 <46>
|
dw 3e00h, 5700h, 6100h, 6b00h ;0c - F4 <46>
|
dw 0f09h, 0f00h, 9400h, 0000h ;0d - TAB <47>
|
dw 0f09h, 0f00h, 9400h, 0000h ;0d - TAB <47>
|
dw 2960h, 297eh, 0000h, 2900h ;0e - ` ~ <48>
|
dw 2960h, 297eh, 0000h, 2900h ;0e - ` ~ <48>
|
dw 0231h, 0221h, 0000h, 7800h ;16 - 1 ! <49>
|
dw 0231h, 0221h, 0000h, 7800h ;16 - 1 ! <49>
|
dw 0332h, 0340h, 0300h, 7900h ;1e - 2 @ <50>
|
dw 0332h, 0340h, 0300h, 7900h ;1e - 2 @ <50>
|
dw 0534h, 0524h, 0000h, 7b00h ;25 - 4 $ <51>
|
dw 0534h, 0524h, 0000h, 7b00h ;25 - 4 $ <51>
|
dw 0433h, 0423h, 0000h, 7a00h ;26 - 3 # <52>
|
dw 0433h, 0423h, 0000h, 7a00h ;26 - 3 # <52>
|
dw 3920h, 3920h, 3920h, 3920h ;29 - SPC <53>
|
dw 3920h, 3920h, 3920h, 3920h ;29 - SPC <53>
|
dw 0635h, 0625h, 0000h, 7c00h ;2e - 5 % <54>
|
dw 0635h, 0625h, 0000h, 7c00h ;2e - 5 % <54>
|
dw 0736h, 075eh, 071eh, 7d00h ;36 - 6 ^ <55>
|
dw 0736h, 075eh, 071eh, 7d00h ;36 - 6 ^ <55>
|
dw 0837h, 0826h, 0000h, 7e00h ;3d - 7 & <56>
|
dw 0837h, 0826h, 0000h, 7e00h ;3d - 7 & <56>
|
dw 0938h, 092ah, 0000h, 7f00h ;3e - 8 * <57>
|
dw 0938h, 092ah, 0000h, 7f00h ;3e - 8 * <57>
|
dw 332ch, 333ch, 0000h, 3300h ;41 - , < <58>
|
dw 332ch, 333ch, 0000h, 3300h ;41 - , < <58>
|
dw 0b30h, 0b29h, 0000h, 8100h ;45 - 0 ) <59>
|
dw 0b30h, 0b29h, 0000h, 8100h ;45 - 0 ) <59>
|
dw 0a39h, 0a28h, 0000h, 8000h ;46 - 9 ( <60>
|
dw 0a39h, 0a28h, 0000h, 8000h ;46 - 9 ( <60>
|
dw 342eh, 343eh, 0000h, 3400h ;49 - . > <61>
|
dw 342eh, 343eh, 0000h, 3400h ;49 - . > <61>
|
dw 352fh, 353fh, 0000h, 3500h ;4a - / ? <62>
|
dw 352fh, 353fh, 0000h, 3500h ;4a - / ? <62>
|
dw 0e02fh, 0e02fh, 9500h, 0a400h ;4a - (e0)KP/ <63>
|
dw 0e02fh, 0e02fh, 9500h, 0a400h ;4a - (e0)KP/ <63>
|
dw 273bh, 273ah, 0000h, 2700h ;4c - ; : <64>
|
dw 273bh, 273ah, 0000h, 2700h ;4c - ; : <64>
|
dw 0c2dh, 0c5fh, 0c1fh, 8200h ;4e - - _ <65>
|
dw 0c2dh, 0c5fh, 0c1fh, 8200h ;4e - - _ <65>
|
dw 2827h, 2822h, 0000h, 2800h ;52 - ’ “ <66>
|
dw 2827h, 2822h, 0000h, 2800h ;52 - ’ “ <66>
|
dw 1a5bh, 1a7bh, 1a1bh, 1a00h ;54 - [ { <67>
|
dw 1a5bh, 1a7bh, 1a1bh, 1a00h ;54 - [ { <67>
|
dw 0d3dh, 0d2bh, 0000h, 8300h ;55 - = + <68>
|
dw 0d3dh, 0d2bh, 0000h, 8300h ;55 - = + <68>
|
dw 1c0dh, 1c0dh, 1c0ah, 1c00h ;5a - Enter, (E0)KPEnter <69>
|
dw 1c0dh, 1c0dh, 1c0ah, 1c00h ;5a - Enter, (E0)KPEnter <69>
|
dw 1b5dh, 1b7dh, 1b1dh, 1b00h ;5b - ] } <70>
|
dw 1b5dh, 1b7dh, 1b1dh, 1b00h ;5b - ] } <70>
|
dw 2b5ch, 2b7ch, 2b1ch, 2b00h ;5d - \ | <71>
|
dw 2b5ch, 2b7ch, 2b1ch, 2b00h ;5d - \ | <71>
|
dw 0e08h, 0e08h, 0e7fh, 0e00h ;66 - BKSP <72>
|
dw 0e08h, 0e08h, 0e7fh, 0e00h ;66 - BKSP <72>
|
dw 4f00h, 4f00h, 7500h, 9f00h ;69 - (E0)END <73>
|
dw 4f00h, 4f00h, 7500h, 9f00h ;69 - (E0)END <73>
|
dw 4b00h, 4b00h, 7300h, 9b00h ;6b - (E0)LEFT <74>
|
dw 4b00h, 4b00h, 7300h, 9b00h ;6b - (E0)LEFT <74>
|
dw 4700h, 4700h, 7700h, 9700h ;6c - (E0)HOME <75>
|
dw 4700h, 4700h, 7700h, 9700h ;6c - (E0)HOME <75>
|
dw 5200h, 5200h, 9200h, 0a200h ;70 - (E0)INS <76>
|
dw 5200h, 5200h, 9200h, 0a200h ;70 - (E0)INS <76>
|
dw 5300h, 5300h, 9300h, 0a300h ;71 - (E0)DEL <77>
|
dw 5300h, 5300h, 9300h, 0a300h ;71 - (E0)DEL <77>
|
dw 5000h, 5000h, 9100h, 0a000h ;72 - (E0)DOWN <78>
|
dw 5000h, 5000h, 9100h, 0a000h ;72 - (E0)DOWN <78>
|
dw 4300h, 5c00h, 6600h, 7000h ;01 - F9 <79>
|
dw 4300h, 5c00h, 6600h, 7000h ;01 - F9 <79>
|
dw 4d00h, 4d00h, 7400h, 9d00h ;74 - (E0)RIGHT <80>
|
dw 4d00h, 4d00h, 7400h, 9d00h ;74 - (E0)RIGHT <80>
|
dw 4800h, 4800h, 8d00h, 9800h ;75 - (E0)UP <81>
|
dw 4800h, 4800h, 8d00h, 9800h ;75 - (E0)UP <81>
|
dw 011bh, 011bh, 011bh, 0100h ;76 - ESC <82>
|
dw 011bh, 011bh, 011bh, 0100h ;76 - ESC <82>
|
dw 8500h, 8700h, 8900h, 8b00h ;78 - F11 <83>
|
dw 8500h, 8700h, 8900h, 8b00h ;78 - F11 <83>
|
dw 4e2bh, 4e2bh, 9000h, 4e00h ;79 - KP+ <84>
|
dw 4e2bh, 4e2bh, 9000h, 4e00h ;79 - KP+ <84>
|
dw 5100h, 5100h, 7600h, 0a100h ;7a - (E0)PGDN <85>
|
dw 5100h, 5100h, 7600h, 0a100h ;7a - (E0)PGDN <85>
|
dw 4a2dh, 4a2dh, 8e00h, 4a00h ;7b - KP- <86>
|
dw 4a2dh, 4a2dh, 8e00h, 4a00h ;7b - KP- <86>
|
dw 372ah, 372ah, 9600h, 3700h ;7c - KP* --- on VMWare, it does not send 3710h with CTL <87>
|
dw 372ah, 372ah, 9600h, 3700h ;7c - KP* --- on VMWare, it does not send 3710h with CTL <87>
|
dw 4900h, 4900h, 8400h, 9900h ;7d - (E0)PGUP <88>
|
dw 4900h, 4900h, 8400h, 9900h ;7d - (E0)PGUP <88>
|
dw 4600h, 4600h, 4600h, 4600h ;7e - SCRL <89>
|
dw 4600h, 4600h, 4600h, 4600h ;7e - SCRL <89>
|
dw 4100h, 5a00h, 6400h, 6e00h ;83 - F7 <90>
|
dw 4100h, 5a00h, 6400h, 6e00h ;83 - F7 <90>
|
|
|
; ------------------------- POWER ON RESET -----------------------
|
; ------------------------- POWER ON RESET -----------------------
|
org 0fff0h
|
org 0fff0h
|
|
|
db 0eah
|
db 0eah
|
dw coldboot, 0f000h
|
dw coldboot, 0f000h
|
db '02/05/13'
|
db '02/05/13'
|
db 0ffh, 0ffh, 0
|
db 0ffh, 0ffh, 0
|
|
|