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