windows-nt/Source/XPSP1/NT/base/mvdm/softpc.new/roms/bios1.asm

559 lines
10 KiB
NASM
Raw Normal View History

2020-09-26 03:20:57 -05:00
; SCCSID = @(#)uf.bios1.asm 1.16 7/3/95
; Author: J. Box, Jerry Kramskoy
;
; Purpose:
; provides Intel BIOS for the following:
; RTC interrupt
; fixed disk (on dual card)
;
; C-services (through 'bop' instruction)
BIOS_UNEXP_INT = 2
BIOS_RTC_INT = 70h
BIOS_REDIRECT_INT = 71h
BIOS_D11_INT = 72h
BIOS_X287_INT = 75h
BIOS_DISK_IO = 13h
BIOS_MOUSE_INT1 = 0BAh
BIOS_MOUSE_INT2 = 0BBh
BIOS_MOUSE_IO_LANGUAGE = 0BCh
BIOS_MOUSE_IO_INTERRUPT = 0BDh
BIOS_MOUSE_VIDEO_IO = 0BEh
BIOS_CPU_RETURN = 0feh
BIOS_IRET_HOOK = 52h
; ICA registers
ICA_MASTER_CMD = 020h
ICA_MASTER_IMR = 021h
ICA_SLAVE_CMD = 0A0h
ICA_SLAVE_IMR = 0A1h
; and commands
ICA_EOI = 020h
; CMOS registers
CMOS_addr = 070h
CMOS_data = 071h
NMI_DISABLE = 080h
CMOS_StatusA = NMI_DISABLE + 0Ah
CMOS_StatusB = NMI_DISABLE + 0Bh
CMOS_StatusC = NMI_DISABLE + 0Ch
CMOS_Shutdown = 0Fh
; CMOS constants (bits in StatusB or StatusC)
CMOS_PI = 01000000b ; Periodic interrupt
CMOS_AI = 00100000b ; Alarm interrupt
; microseconds at 1024Hz
CMOS_PERIOD_USECS = 976
include bebop.inc
; DUE TO LIMITATIONS IN EXE2BIN, we define
; the region 0 - 0xdfff (segment 0xf000) in this file
; and the region 0xe000 - 0xffff in file 'bios2.asm'
;
; each file should be SEPARATELY put through
; MASM,LINK, and EXE2BIN to produce 2 binary image files
; which get loaded into the appropriate regions during
; SoftPC startup.
;------------------------;
; bios data area ;
;------------------------;
; BIOS variables area
BIOS_VAR_SEGMENT SEGMENT at 40h
ORG 098h
rtc_user_flag DD ? ; 98
rtc_micro_secs DD ? ; 9c
rtc_wait_flag DB ? ; a0
ORG 8eh
hf_int_flag db ? ; 8e
BIOS_VAR_SEGMENT ENDS
code segment
assume cs:code, ds:BIOS_VAR_SEGMENT
;----------------------------------------------------;
; D11 ;
; services unused interrupt vectors ;
; ;
;----------------------------------------------------;
ORG 01BE0h
D11: bop BIOS_D11_INT
iret
;----------------------------------------------------;
; IRET HOOK ;
; Return control to the monitor after an ISR ;
; returns to here. ;
;----------------------------------------------------;
ORG 01C00h
bop BIOS_IRET_HOOK
iret
;----------------------------------------------------;
; re_direct ;
; This routine fields level 9 interrupts ;
; control is passed to Master int level 2 ;
;----------------------------------------------------;
ORG 01C2Fh
re_direct: bop BIOS_REDIRECT_INT
int 0ah
iret
;----------------------------------------------------;
; int_287 ;
; service X287 interrupts ;
; ;
;----------------------------------------------------;
ORG 01C38h
int_287: bop BIOS_X287_INT
int 02
iret
;----------------------------------------------------;
; rtc_int ;
; rtc interrupt handler ;
;----------------------------------------------------;
ORG 04B1Bh
rtc_int: push ax
push ds
mov ax, BIOS_VAR_SEGMENT
mov ds, ax
rtc_test_pending:
;; Check for pending interrupt
mov al, CMOS_StatusC
out CMOS_addr, al
in al, CMOS_data ; reads then clears pending interrupts
;; Mask with enabled interrupts
mov ah, al ; save pending interrupts
mov al, CMOS_StatusB
out CMOS_addr, al
in al, CMOS_data
and ah, al
;; Test pending, enabled interrupts (in ah) for work to do
test ah, (CMOS_PI+CMOS_AI)
jnz rtc_test_enabled
;; Deselecting the cmos
mov al, CMOS_Shutdown
out CMOS_addr, al
;; Send eoi to ICA
mov al, ICA_EOI
out ICA_SLAVE_CMD, al
out ICA_MASTER_CMD, al
;; And return
pop ds
pop ax
iret
rtc_test_enabled:
;; Test for periodic interrupt triggered
test ah, CMOS_PI
jz rtc_test_alarm
;; Decrement the microsecond count
.386
sub ds:[rtc_micro_secs], CMOS_PERIOD_USECS
.286
jnc rtc_test_alarm
;; Disable PI interrupt in CMOS if count expired
mov al, CMOS_StatusB
out CMOS_addr, al
in al, CMOS_data
and al, 10111111b ; Disable PI interrupt
out CMOS_data, al
;; Update the flag byte to say time has expired
push es
push bx
les bx, rtc_user_flag
or byte ptr es:[bx], 080h
pop bx
pop es
;; Mark timer-in-use flag in-active
and rtc_wait_flag, 0feh; Show wait is not active
rtc_test_alarm:
;; Test for alarm interrupt triggered
test ah, CMOS_AI
jz rtc_test_pending
;; Call users alarm function (first deselecting the cmos)
mov al, CMOS_Shutdown
out CMOS_addr, al
int 04Ah
;; Repeat in case a new interrupt occurred
jmp rtc_test_pending
;----------------------------------------------------;
; disk_io
; route to disk/diskette i/o service ;
;----------------------------------------------------;
org 2e86h ;(must match DISKO_OFFSET in diskbios.c)
disk_io proc far
; is this request for fixed disk or diskette?
cmp dl,80h
jae p0
; for diskette.
int 40h
bye:
retf 2
p0:
sti
; reset? (ah = 0). reset diskette also
or ah,ah
jnz p1
int 40h
sub ah,ah
cmp dl,81h
ja bye
p1:
; carry out the disk service requested from 'C'.
; those requests which expect to cause a
; disk interrupt will 'call' wait below,
; which returns back to 'C'. Eventually
; 'C' returns after the bop.
push ds
bop BIOS_DISK_IO
pop ds
retf 2
disk_io endp
;----------------------------------------------------;
; wait ;
; wait for disk interrupt ;
; ('called' from waitint() in diskbios.c ;
;----------------------------------------------------;
org 329fh ;(must match DISKWAIT_OFFSET in diskbios.c)
wate proc
sti
clc
mov ax,9000h
int 15h
push ds
push cx
mov ax, 40h
mov ds, ax
xor cx, cx
not_yet: cmp byte ptr ds:[8eh], 0
loopz not_yet
pop cx
pop ds
bop BIOS_CPU_RETURN
wate endp
;----------------------------------------------------;
; hd_int ;
; field fixed disk controller's interrupt ;
;----------------------------------------------------;
org 33b7h ; (must match DISKISR_OFFSET in diskbios.c)
hd_int proc near
push ds
mov ax,BIOS_VAR_SEGMENT
mov ds,ax
; inform everybody that a fixed disk interrupt
; occurred
mov hf_int_flag,0ffh
; clear down the interrupt with the ica's
mov al, ICA_EOI
out ICA_SLAVE_CMD, al
out ICA_MASTER_CMD, al
sti
mov ax,9100h
int 15h
pop ds
iret
hd_int endp
; read bytes 0 - 3fff in from binary image
; when accessing bios1.rom.
; if need more than this, change value here
; to 'n' and in sas_init(), change read of bios1.rom
; to have transfer count of 'n'+1
org 3fffh
insignia_endmark db 0
ifdef SUN_VA
;
; NB. the following addresses are allocated to SUN for DOS Windows 3.0.
; They are not to be used by anyone else.
; THIS AREA IS SUN PROPERTY - TRESPASSERS WILL BE PROSECUTED
; However please note that only the ranges below are reserved.
;
ORG 04000h
sunroms_2 LABEL FAR
db 512 dup (0) ; reserved
ORG 05000h
sunroms_3 LABEL FAR
db 512 dup (0) ; reserved
endif
ORG 06000h
; this is a fake IFS header to make DOS 4.01
; happy with HFX. Do not move/alter.
hfx_ifs_hdr LABEL FAR
DB 0ffh, 0ffh, 0ffh, 0ffh
DB "HFXREDIR"
DB 00h, 02ch
DB 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h
ifndef GISP_SVGA
ORG 06020h
ifndef SUN_VA
write_teletype proc far
retf
write_teletype endp
else
write_teletype proc far
push ds
push si
mov si, 0f000h
mov ds, si
mov si, 06400h
push ax
mov ah, 0eh
push bp
mov bp, 2
push dx
push bx
mov bx, 0
start_write:
cmp bp, [si]
je finish_write
mov al, ds:[bp+si]
inc bp
int 010h
jmp start_write
finish_write:
mov word ptr [si], 2
pop bx
pop dx
pop bp
pop ax
pop si
pop ds
retf
write_teletype endp
ORG 06200h
; mouse_io_interrupt
mouse_io:
JMP hopover
BOP BIOS_MOUSE_IO_LANGUAGE
RETF 8
hopover:
BOP BIOS_MOUSE_IO_INTERRUPT
IRET
ORG 06220h
; mouse_int1
mouse_int1:
BOP BIOS_MOUSE_INT1
IRET
ORG 06240h
; mouse_video_io
mouse_video_io:
BOP BIOS_MOUSE_VIDEO_IO
IRET
ORG 06260h
; mouse_int2
mouse_int2:
BOP BIOS_MOUSE_INT2
IRET
ORG 06280h
; mouse_version
mouse_version: ; dummy, for compatibility
DB 042h,042h,00h,00h
ORG 062a0h
; mouse_copyright
mouse_copyright: ; dummy, for compatibility
DB "Copyright 1987-91 Insignia Solutions Inc"
ORG 06400h
; scratch pad area - this is where the messages go!
endif
endif ; GISP_SVGA
;; To cope with Helix SoftWare "Netroom 2.20" DOS extender
;; which only maps in pages of the BIOS that have vectors
;; we must ensure that something points at page F6xxx
;; else we end up with the scratch area on top of some
;; DOS program or driver!
ORG 06f00h ; UNEXP_INT_OFFSET
BOP BIOS_UNEXP_INT
IRET
.386
; These are the virtualisation instructions needed for the 386.
ORG 3000h ; BIOS_STI_OFFSET
STI
BOP 0feh
ORG 3010h ; BIOS_CLI_OFFSET
CLI
BOP 0feh
ORG 3020h ; BIOS_INB_OFFSET
IN al,dx
BOP 0feh
ORG 3030h ; BIOS_INW_OFFSET
IN ax,dx
BOP 0feh
ORG 3040h ; BIOS_IND_OFFSET
IN eax,dx
BOP 0feh
ORG 3050h ; BIOS_OUTB_OFFSET
OUT dx,al
BOP 0feh
ORG 3060h ; BIOS_OUTW_OFFSET
OUT dx,ax
BOP 0feh
ORG 3070h ; BIOS_OUTD_OFFSET
OUT dx,eax
BOP 0feh
ORG 3080h ; BIOS_WRTB_OFFSET
MOV [edx],al
BOP 0feh
ORG 3090h ; BIOS_WRTW_OFFSET
MOV [edx],ax
BOP 0feh
ORG 30a0h ; BIOS_WRTD_OFFSET
MOV [edx],eax
BOP 0feh
ORG 30b0h ; BIOS_RDB_OFFSET
MOV al, [edx]
BOP 0feh
ORG 30c0h ; BIOS_RDW_OFFSET
MOV ax, [edx]
BOP 0feh
ORG 30d0h ; BIOS_RDD_OFFSET
MOV eax, [edx]
BOP 0feh
ORG 30e0h ; BIOS_YIELD_VM_OFFSET
MOV AX, 1680h ; Yeild VM time slice
INT 2fh
BOP 0feh
ORG 30f0h ; BIOS_STOSB_OFFSET
push es
push ds
pop es
xchg edx,edi ; dest lin addr
db 67h
db 66h
rep stosb
xchg edx,edi
pop es
BOP 0feh
ORG 3110h ; BIOS_STOSW_OFFSET
push es
push ds
pop es
xchg edx,edi ; dest lin addr
db 67h
rep stosw
xchg edx,edi
pop es
BOP 0feh
ORG 3130h ; BIOS_STOSD_OFFSET
push es
push ds
pop es
xchg edx,edi ; dest lin addr
db 67h
db 66h
rep stosw
xchg edx,edi
pop es
BOP 0feh
ORG 3200h ; BIOS_BAD_OFFSET
db 0c5h
db 0c5h ; illegal instruction
BOP 0feh
;; N.B. DISKWAIT_OFFSET is at "org 329fh"
code ends
end