INIT.ASM
资源名称:drdossrc.zip [点击查看]
上传用户:xiaogehua
上传日期:2007-01-08
资源大小:1183k
文件大小:26k
源码类别:
操作系统开发
开发平台:
Asm
- ; File : $Workfile$
- ;
- ; Description :
- ;
- ; Original Author : DIGITAL RESEARCH
- ;
- ; Last Edited By : $CALDERA$
- ;
- ;-----------------------------------------------------------------------;
- ; Copyright Work of Caldera, Inc. All Rights Reserved.
- ;
- ; THIS WORK IS A COPYRIGHT WORK AND CONTAINS CONFIDENTIAL,
- ; PROPRIETARY AND TRADE SECRET INFORMATION OF CALDERA, INC.
- ; ACCESS TO THIS WORK IS RESTRICTED TO (I) CALDERA, INC. EMPLOYEES
- ; WHO HAVE A NEED TO KNOW TO PERFORM TASKS WITHIN THE SCOPE OF
- ; THEIR ASSIGNMENTS AND (II) ENTITIES OTHER THAN CALDERA, INC. WHO
- ; HAVE ACCEPTED THE CALDERA OPENDOS SOURCE LICENSE OR OTHER CALDERA LICENSE
- ; AGREEMENTS. EXCEPT UNDER THE EXPRESS TERMS OF THE CALDERA LICENSE
- ; AGREEMENT NO PART OF THIS WORK MAY BE USED, PRACTICED, PERFORMED,
- ; COPIED, DISTRIBUTED, REVISED, MODIFIED, TRANSLATED, ABRIDGED,
- ; CONDENSED, EXPANDED, COLLECTED, COMPILED, LINKED, RECAST,
- ; TRANSFORMED OR ADAPTED WITHOUT THE PRIOR WRITTEN CONSENT OF
- ; CALDERA, INC. ANY USE OR EXPLOITATION OF THIS WORK WITHOUT
- ; AUTHORIZATION COULD SUBJECT THE PERPETRATOR TO CRIMINAL AND
- ; CIVIL LIABILITY.
- ;-----------------------------------------------------------------------;
- ;
- ; *** Current Edit History ***
- ; *** End of Current Edit History ***
- ;
- ; $Log$
- ; INIT.ASM 1.25 93/12/07 15:51:27
- ; Move int13pointer to offset 0B4h as some app expects it there
- ; INIT.ASM 1.24 93/11/18 18:57:20
- ; Increase amount reserved for COMMAND.COM by 256 bytes
- ; INIT.ASM 1.23 93/11/17 19:29:26
- ; Change default DEBLOCK seg to FFFF for performance reasons
- ; INIT.ASM 1.19 93/07/22 19:43:59
- ; switch over to REQUEST.EQU
- ; ENDLOG
- include BIOSGRPS.EQU
- include DRMACROS.EQU
- include IBMROS.EQU
- include MSDOS.EQU
- include REQUEST.EQU ; request header equates
- include BPB.EQU
- include UDSC.EQU
- include DRIVER.EQU
- ; IBM AT Hardware equates
- COMPRESSED equ TRUE ; enables compressed changes.
- ; a little macro to help locate things
- ; it warns us when the ORG get trampled on
- orgabs MACRO address
- local was,is
- was = offset $
- org address
- is = offset $
- if was GT is
- if2
- %OUT ERROR - absolute data overwritten !! moving it
- endif
- org was
- endif
- ENDM
- jmpfar MACRO address, fixup
- db 0EAh ; jmpf opcode
- dw CG:address ; offset of destination
- fixup dw 0EDCh ; segment of destination
- ENDM
- callfar MACRO address, fixup
- db 09Ah ; callf opcode
- dw CG:address ; offset of destination
- fixup dw 0EDCh ; segment of destination
- ENDM
- F5KEY equ 3F00h
- F8KEY equ 4200h
- IVECT segment at 0000h
- org 0000h*4
- i0off dw ?
- i0seg dw ?
- org 0001h*4
- i1off dw ?
- i1seg dw ?
- org 0003h*4
- i3off dw ?
- i3seg dw ?
- org 0004h*4
- i4off dw ?
- i4seg dw ?
- org 0015h*4
- i15off dw ?
- i15seg dw ?
- org 0019h*4
- i19off dw ?
- i19seg dw ?
- org 001Eh*4
- i1Eptr label dword
- i1Eoff dw ?
- i1Eseg dw ?
- org 002Fh*4
- i2Fptr label dword
- i2Foff dw ?
- i2Fseg dw ?
- org 006Ch*4
- i6Cptr label dword
- i6Coff dw ?
- i6Cseg dw ?
- IVECT ends
- CGROUP group CODE, RCODE, ICODE
- CG equ offset CGROUP
- CODE segment 'CODE'
- Assume CS:CGROUP, DS:Nothing, ES:Nothing, SS:Nothing
- public strat
- extrn ConsoleTable:word
- extrn ClockTable:word
- extrn SerParCommonTable:word
- extrn DiskTable:near
- extrn Int13Deblock:near
- extrn Int13Unsure:near
- extrn Int2FHandler:near
- extrn ResumeHandler:near
- extrn biosinit_end:byte ; End of the BIOS Init Code and Data
- extrn biosinit:near
- extrn boot_options:word
- extrn rcode_fixups:word
- extrn rcode_seg:word
- extrn rcode_offset:word
- extrn rcode_len:word
- extrn icode_len:word
- extrn current_dos:word
- extrn device_root:dword
- extrn mem_size:word
- extrn ext_mem_size:word
- extrn init_buf:byte
- extrn init_drv:byte
- extrn init_runit:byte
- extrn comspec_drv:byte
- extrn init_flags:word
- include biosmsgs.def ; Include TFT Header File
- Public A20Enable
- A20Enable proc near
- ;========
- ; This location is fixed up at run time to be a RET
- ; If the BIOS is relocated to the HMA then it is fixed up again to be
- ; CALLF IBMDOS:A20Enable; RET
- ; Calling this location at run time will ensure that the HMA is mapped
- ; in so we can access the HMA code.
- ;
- A20Enable endp
- init proc near ; this is at BIOSCODE:0000h
- ifndef COPYPROT
- jmp init0 ; jump to reusable init space
- else
- extrn protect:near ; Jump to Copy protection code
- jmp protect ; which will return control to
- endif ; INIT0 on completion
- init endp
- compflg label word
- ifdef COPYPROT
- dw ' ' ; stops any compression working
- else
- dw offset CGROUP:INITDATA ; compresses from INITDATA onwards
- endif ; this word set to 0 when compressed
- orgabs 06h
- db 'COMPAQCompatible'
- dw offset CGROUP:RCODE ; lets find offset of RCODE
- MemFixup dw 0 ; and its relocated segment
- Public cleanup
- cleanup PROC far ; BIOSINIT will call here later
- ret
- cleanup endp
- ; Local single character buffer for Ctrl-Break handling
- public serparFlag, serparChar
- serparFlag db 4 dup (FALSE) ; we haven't got any yet
- serparChar db 4 dup (?) ; will store one character
- ; Device driver headers for serial/parallel devices
- con_drvr dw CG:aux_drvr, 0 ; link to next device driver
- dw DA_CHARDEV+DA_SPECIAL+DA_ISCOT+DA_ISCIN+DA_IOCTL
- dw CG:strat, CG:IntCon
- db 'CON '
- aux_drvr dw CG:prn_drvr, 0 ; link to next device driver
- dw DA_CHARDEV
- dw CG:strat, CG:IntCOM1
- db 'AUX '
- prn_drvr dw CG:clock_drvr, 0 ; link to next device driver
- dw DA_CHARDEV
- dw CG:strat, CG:IntLPT1
- db 'PRN '
- clock_drvr dw disk_drvr, 0 ; link to next device driver
- dw DA_CHARDEV+DA_ISCLK
- dw CG:strat, CG:IntClock
- db 'CLOCK$ '
- com1_drvr dw CG:lpt1_drvr, 0 ; link to next device driver
- dw DA_CHARDEV
- dw CG:strat, CG:IntCOM1
- db 'COM1 '
- com2_drvr dw CG:com3_drvr, 0 ; link to next device driver
- dw DA_CHARDEV
- dw CG:strat, CG:IntCOM2
- db 'COM2 '
- com3_drvr dw CG:com4_drvr, 0 ; link to next device driver
- dw DA_CHARDEV
- dw CG:strat, CG:IntCOM3
- db 'COM3 '
- IFDEF EMBEDDED
- extrn rdisk_drvr:near
- com4_drvr dw CG:rdisk_drvr, 0 ; link to next device driver
- ELSE
- com4_drvr dw -1, -1 ; link to next device driver
- ENDIF
- dw DA_CHARDEV
- dw CG:strat, CG:IntCOM4
- db 'COM4 '
- orgabs 0b4h ; save address at fixed location
- ; for dirty apps
- Public i13pointer, i13off_save, i13seg_save
- i13pointer label dword ; address of ROS Int 13h entry
- i13off_save dw ?
- i13seg_save dw ?
- orgabs 0b8h ; REQ_HDR
- public req_ptr, req_off, req_seg
- req_ptr label dword
- req_off dw 0 ;** fixed location **
- req_seg dw 0 ;** fixed location **
- strat proc far
- mov cs:req_off,bx
- mov cs:req_seg,es
- ret
- strat endp
- lpt1_drvr dw CG:lpt2_drvr, 0 ; link to next device driver
- dw DA_CHARDEV
- dw CG:strat, CG:IntLPT1
- db 'LPT1 '
- lpt2_drvr dw CG:lpt3_drvr, 0 ; link to next device driver
- dw DA_CHARDEV
- dw CG:strat, CG:IntLPT2
- db 'LPT2 '
- lpt3_drvr dw CG:com2_drvr, 0 ; link to next device driver
- dw DA_CHARDEV
- dw CG:strat, CG:IntLPT3
- db 'LPT3 '
- orgabs 100h ; save vectors at fixed location
- ; for dirty apps
- Public orgInt13
- NUM_SAVED_VECS equ 5
- vecSave db 10h
- dw 0,0
- db 13h
- orgInt13 dw 0,0
- db 15h
- dw 0,0
- db 19h
- dw 0,0
- db 1Bh
- dw 0,0
- Int19Trap:
- cld
- cli ; be sure...
- push cs
- pop ds
- lea si,vecSave
- mov cx,NUM_SAVED_VECS ; restore this many vectors
- Int19Trap10:
- xor ax,ax ; zero AH for lodsb
- mov es,ax ; ES -> interrupt vectors
- lodsb ; AX = vector to restore
- shl ax,1
- shl ax,1 ; point at address
- xchg ax,di ; ES:DI -> location to restore
- movsw
- movsw ; restore this vector
- loop Int19Trap10 ; go and do another
- int 19h ; and go to original int 19...
- orgabs 16ch ; PRN:/AUX: the device number
- devno db 0,0 ;** fixed location **
- Public NumDiskUnits, DeblockSeg
- disk_drvr dw CG:com1_drvr, 0 ; link to next driver
- dw DA_NONIBM+DA_GETSET+DA_REMOVE+DA_BIGDRV
- dw CG:strat, CG:IntDisk
- NumDiskUnits db 5, 7 dup (?)
- dw 0EDCh ; checked by DRIVER.SYS
- dw 0 ; was allocate UDSC
- DeblockSeg dw 0A000h ; segment we start deblocking
- IntLPT1: ; LPT1
- call DeviceDriver
- dw 0
- IntLPT2: ; LPT2
- call DeviceDriver
- dw 1
- IntLPT3: ; LPT3
- call DeviceDriver
- dw 2
- IntCOM1: ; AUX = COM1
- call DeviceDriver
- dw 3
- IntCOM2: ; COM2
- call DeviceDriver
- dw 4
- IntCOM3: ; COM3
- call DeviceDriver
- dw 5
- IntCOM4: ; COM4
- call DeviceDriver
- dw 6
- IntCon:
- call DeviceDriver
- dw offset CGROUP:ConsoleTable
- IntClock:
- call DeviceDriver
- dw offset CGROUP:ClockTable
- Public IntDiskTable
- IntDisk:
- call DeviceDriver
- IntDiskTable:
- dw offset CGROUP:DiskTable
- DeviceDriver proc near
- call A20Enable ; make sure A20 is on
- jmpfar DriverFunction, DriverFunctionFixup
- DeviceDriver endp
- extrn i13_AX:word
- Public Int13Trap
- Int13Trap proc far
- ;--------
- ; The Int 13 code is in low memory for speed, with unusual conditions
- ; having the overhead of A20Enable calls
- ;
- cmp ah,ROS_FORMAT ; ROS format function?
- je Int13TrapFormat
- Int13Trap10:
- mov cs:i13_AX,ax ; save Op/Count in case of error
- clc
- pushf ; fake an Int
- call cs:i13pointer ; call the ROM BIOS
- jc Int13Trap20 ; check for error
- ret 2 ; none, so return to caller
- Int13Trap20:
- cmp ah,9 ; it it a DMA error ?
- je Int13TrapDMA ; then deblock it
- call Int13TrapUnsure ; else declare floppy drive unsure
- stc ; restore error flag
- ret 2 ; return to user
- Int13TrapFormat:
- call Int13TrapUnsure ; mark media as unsure
- jmps Int13Trap10 ; and resume
- Int13TrapDMA:
- call A20Enable ; make sure A20 is on
- jmpfar Int13Deblock, Int13DeblockFixup
- Int13TrapUnsure proc near
- call A20Enable ; make sure A20 is on
- callfar Int13Unsure, Int13UnsureFixup
- ret
- Int13TrapUnsure endp
- Int13Trap endp
- Public Int2FTrap
- Int2FTrap proc far
- ;--------
- jmpfar Int2FHandler, Int2FFixup
- Int2FTrap endp
- Resume proc far
- ;-----
- call A20Enable ; make sure A20 is on
- jmpfar ResumeHandler, ResumeFixup
- Resume endp
- Int0Trap proc far
- ;-------
- call A20Enable ; make sure A20 is on
- jmpfar Int0Handler, Int0Fixup
- Int0Trap endp
- Public FastConsole
- FastConsole proc far
- ;----------
- ; RAM entry to ensure INT29 vector is below INT20 vector
- ; We keep the normal path low to maxmimise performance, but on backspace we
- ; take the A20Enable hit and call high for greater TPA.
- ;
- pushx <ax, bx, si, di, bp> ; old ROS corrupts these
- cmp al,8 ; back space character
- je Fastcon30 ; special case
- Fastcon10:
- mov ah,0Eh ; use ROS TTY-like output function
- mov bx,7 ; use the normal attribute
- int VIDEO_INT ; output the character in AL
- Fastcon20:
- popx <bp, di, si, bx, ax>
- iret
- Fastcon30:
- call A20Enable ; make sure A20 is on
- jmpfar OutputBS, OutputBSFixup ; call up to the HMA
- FastConsole endp
- Public ControlBreak
- ControlBreak proc far
- ;-----------
- mov cs:word ptr local_char,'C'-40h + (256*TRUE)
- ;; mov local_char,'C'-40h ; force ^C into local buffer
- ;; mov local_flag,TRUE ; indicate buffer not empty
- Int1Trap:
- Int3Trap:
- Int4Trap:
- iret
- ControlBreak endp
- public daycount
- daycount dw 0
- ; More Disk Data
- public local_buffer,local_id,local_pt
- local_buffer db 512 dup (?) ; local deblocking buffer
- SECSIZE equ 512
- IDOFF equ SECSIZE-2 ; last word in boot sector is ID
- PTOFF equ IDOFF-40h ; 4*16 bytes for partition def's
- local_id equ word ptr local_buffer + IDOFF
- local_pt equ word ptr local_buffer + PTOFF
- public bpbs,bpb160,bpb360,bpb720,NBPBS
- ; List of BPBs that we usually support
- bpb160 BPB <512,1,1,2, 64, 40*1*8,0FEh,1, 8,1,0,0>
- bpb180 BPB <512,1,1,2, 64, 40*1*9,0FCh,2, 9,1,0,0>
- bpb320 BPB <512,2,1,2,112, 40*2*8,0FFh,1, 8,2,0,0>
- bpb360 BPB <512,2,1,2,112, 40*2*9,0FDh,2, 9,2,0,0>
- bpb1200 BPB <512,1,1,2,224,80*2*15,0F9h,7,15,2,0,0>
- bpb720 BPB <512,2,1,2,112, 80*2*9,0F9h,3, 9,2,0,0>
- bpb1440 BPB <512,1,1,2,224,80*2*18,0F0h,9,18,2,0,0>
- bpb2880 BPB <512,2,1,2,240,80*2*36,0F0h,9,36,2,0,0>
- NBPBS equ 8
- ; The following is a template, that gets overwritten
- ; with the real parameters and is used while formatting
- public local_parms,parms_spt,parms_gpl
- public layout_table,bpbtbl
- local_parms db 11011111b ; step rate
- db 2 ; DMA mode
- db 37 ; 2*18.2 = 2 second motor off
- db 2 ; 512 bytes per sector
- parms_spt db 18 ; sectors per track
- db 2Ah ; gap length for read/write
- db 0FFh ; data length (128 byte/sector only)
- parms_gpl db 50h ; data length for format
- db 0F6h ; fill byte for format
- db 15 ; head settle time in ms
- db 8 ; motor on delay in 1/8s
- ; The BPB table need not survive config time, so share with layout table
- bpbtbl label word
- MAX_SPT equ 40
- layout_table label word ; current # of sectors/track
- S = 1
- rept MAX_SPT
- ; C H S N
- ; - - - -
- db 0, 0, S, 2
- S = S + 1
- endm
- orgabs 600h ; CON: one character look-ahead buffer
- ; nb. it's at 61B in DOS 4.0
- Public local_char, local_flag
- local_char db 0 ;** fixed location **
- local_flag db 0 ;** fixed location **
- public endbios
- endbios dw offset CGROUP:RESBIOS ; pointer to last resident byte
- CODE ends
- ICODE segment 'ICODE' ; reusable initialization code
- Assume CS:CGROUP, DS:CGROUP, ES:CGROUP, SS:Nothing
- bpbs dw CG:bpb360 ; 0: 320/360 Kb 5.25" floppy
- dw CG:bpb1200 ; 1: 1.2 Mb 5.25" floppy
- dw CG:bpb720 ; 2: 720 Kb 3.5" floppy
- dw CG:bpb360 ; 3: (8" single density)
- dw CG:bpb360 ; 4: (8" double density)
- dw CG:bpb360 ; 5: hard disk
- dw CG:bpb360 ; 6: tape drive
- dw CG:bpb1440 ; 7: 1.44 Mb 3.5" floppy
- dw CG:bpb1440 ; 8: Other
- dw CG:bpb2880 ; 9: 2.88 Mb 3.5" floppy
- Public init0
- init0 proc near
- ;
- ; We now uncompress to > (7C00h (ie. boot stack) - 700h (ie. base of code)
- ; This means our stack collides with our code, very bad news.
- ; To avoid this we switch stacks into a safer area ie. 0C000h
- ; The floppy parameters also live at 7C00, so we have to relocate these
- ; before we expand.
- mov cs:byte ptr A20Enable,0C3h
- ; fixup the RET
- mov sp, 0C000h ; switch to magic stack
- sti
- cld
- push cx ; save entry registers
- push di ; (important in ROM systems)
- xor si,si
- mov ds,si
- mov es,si
- Assume DS:IVECT, ES:IVECT
- mov di,522h ; ES:DI -> save area for parameters
- lds si,i1Eptr ; DS:SI -> FD parameters for ROS
- Assume DS:Nothing
- mov i1Eoff,di
- mov i1Eseg,es ; setup new location
- mov cx,11
- rep movsb
- mov es:byte ptr 0-7[di],36 ; enable read/writing of 36 sectors/track
- pop di
- pop cx
- if COMPRESSED
- mov si, cs ; preserve entry registers
- mov ds, si ; other than si, ds and es
- mov es, si
- xor si, si
- mov si, compflg ; Get Compresed BIOS Flag
- or si, si ; Set to Zero if the BIOS has
- jnz not_compressed ; been compressed
- mov si, CG:INITDATA
- push di ; bios_seg
- push ax ; bdos_seg
- push bx ; initial drives
- push cx ; memory size
- push dx ; initial flags
- lea cx, biosinit_end
- sub cx, si
- inc cx ; length of compressed part plus one
- mov di, cx
- neg di ; furthest offset we can use
- and di, 0fff0h ; on the next para below
- push di
- push si
- shr cx, 1
- rep movsw ; take a copy
- pop di ; di is now -> compressed dest
- pop si ; this is now -> compressed source
- bios_r20:
- lodsw ; get control word
- mov cx,ax ; as a count
- jcxz bios_r40 ; all done
- test cx,8000h ; negative ?
- jnz bios_r30 ; yes do zeros
- rep movsb ; else move in data bytes
- jmp short bios_r20 ; and to the next
- bios_r30:
- and cx,7fffh ; remove sign
- jcxz bios_r20 ; none to do
- xor ax,ax
- rep stosb ; fill with zeros
- jmp short bios_r20
- bios_r40:
- pop dx
- pop cx
- pop bx
- pop ax
- pop di
- not_compressed:
- endif
- mov si,cs
- mov ds,si ; DS -> local data segment
- cmp dl,0ffh ; booting from ROM?
- jz rom_boot
- cmp si,1000h ; test if debugging
- jb disk_boot ; skip if not
- ; When the BIOS is loaded by the DOSLOAD or LOADER utilities under
- ; Concurrent for DEBUGGING or in a ROM system then on entry AX
- ; contains the current location of the BDOS and CX the memory Size.
- ; Bx is the current code segment
- mov rcode_seg,dx ; rom segment of bios
- mov current_dos,ax ; current location of the BDOS
- mov mem_size,cx ; total memory size
- mov init_drv,bl ; initial drive
- mov comspec_drv,bh ;
- mov init_buf,3 ; assume default # of buffers
- mov init_flags,3
- jmp bios_exit
- rom_boot: ; BIOS is copied from ROM:
- ; DL = 0FFh
- ; AX = segment address of DRBDOS
- ; BH = COMSPEC drive
- ; BL = INIT_DRV
- mov rcode_seg,di ; DI = BIOS ROM SEG
- mov current_dos,ax ; current location of the BDOS
- mov init_drv,bl ; initial drive C:
- mov comspec_drv,bh ; commspec drive C:
- mov init_flags,3 ; it is a ROM system, use comspec drive
- jmps rom_boot10 ; common code
- disk_boot:
- mov rcode_seg,cs
- sub ax,ax
- mov current_dos,ax ; current BDOS location to disk load
- xchg ax,dx ; AL = boot drive
- mov init_runit,al ; save the ROS unit
- test al,al ; test the boot drive
- jz floppy_boot ; skip if floppy boot
- mov al,2 ; it's drive C:
- floppy_boot:
- mov init_drv,al ; set boot drive
- rom_boot10:
- pushx <ds, es> ; save registers
- sub bx,bx
- mov ds,bx ; DS:BX -> interrupt vectors
- Assume DS:IVECT
- push cs ; we want to save vectors some
- pop es ; locally
- lea di,vecSave
- mov cx,NUM_SAVED_VECS ; restore this many vectors
- SaveVectors:
- xor ax,ax ; zero AH
- mov al,es:[di] ; AX = vector to save
- inc di ; skip to save position
- shl ax,1
- shl ax,1 ; point at address
- xchg ax,si ; DS:SI -> location to save
- movsw
- movsw ; save this vector
- loop SaveVectors ; go and do another
- mov i0off,CG:Int0Trap
- mov i0seg,cs ; now grab int0 vector
- mov i1off,CG:Int1Trap
- mov i1seg,cs ; now grab int1 vector
- mov i3off,CG:Int1Trap
- mov i3seg,cs ; now grab int3 vector
- mov i4off,CG:Int1Trap
- mov i4seg,cs ; now grab int4 vector
- mov i19off,CG:Int19Trap
- mov i19seg,cs ; now grab int19 vector
- popx <es, ds>
- Assume DS:CGROUP, ES:CGROUP
- call get_boot_options ; look for user keypress
- mov boot_options,ax ; return any options
- mov ah,EXT_MEMORY
- int SYSTEM_INT ; find out how much extended memory
- jnc bios_extmem
- xor ax,ax ; say we have no memory
- bios_extmem:
- mov ext_mem_size,ax ; we have and store for reference
- mov init_buf,3 ; assume default of 3 buffers
- int MEMORY_INT ; get amount of conventional memory
- cmp ax,128
- jbe bios_mem
- mov init_buf,5 ; use 5 buffers if > 128K of memory
- bios_mem: ; get amount of conventional memory
- mov cl,6 ; in kilobytes (AX)
- shl ax,cl ; convert Kb's to paragraphs
- mov mem_size,ax ; set end of TPA
- bios_exit:
- ; The following code performs the fixups necessary for ROM executable
- ; internal device drivers.
- mov ax,cs ; check if we are on a rommed system
- cmp ax,rcode_seg
- jne keep_rcode ; if so no relocation required
- mov ax,CG:RCODE
- mov rcode_offset,ax ; fixup variable need
- mov bx,CG:IDATA
- sub bx,ax
- mov icode_len,bx ; during init we need RCODE and ICODE
- mov bx,CG:RESUMECODE
- sub bx,ax
- mov rcode_header,bx
- mov rcode_len,bx ; afterwards we just need RCODE
- keep_rcode:
- ; If the system ROM BIOS supports RESUME mode then it will call Int 6C
- ; when returning from sleep mode. We take this over and reset the clock
- ; based upon the RTC value. To save space we only relocate the code if
- ; required.
- ;
- mov ax,4100h ; does the BIOS support resume mode
- xor bx,bx
- int 15h ; lets ask it
- jc resume_exit
- push ds
- xor ax,ax
- mov ds,ax ; DS = vectors
- Assume DS:IVECT
- mov i6Coff,CG:Resume
- mov i6Cseg,cs ; point Int 6C at resume code
- Assume DS:CGROUP
- pop ds
- mov ax,cs ; check if we are on a rommed system
- cmp ax,rcode_seg
- jne resume_exit ; if so nothing extra to keep
- mov ax,CG:RESBIOS
- sub ax,CG:RCODE
- mov rcode_header,ax ; keep Resume code as well...
- mov rcode_len,ax ; afterwards we just need RCODE
- resume_exit:
- mov ax,CG:ENDCODE ; discard RCODE (we will relocate it)
- mov endbios,ax
- mov rcode_fixups,CG:bios_fixup_tbl
- mov bx,CG:con_drvr ; get first device driver in chain
- mov word ptr device_root+0,bx
- mov word ptr device_root+2,ds
- init1:
- cmp word ptr [bx],0FFFFh ; last driver in BIOS?
- je init3
- mov 2[bx],ds ; fix up segments in driver chain
- mov bx,[bx]
- jmps init1
- init3:
- jmp biosinit ; jump to BIOS code
- init0 endp
- get_boot_options:
- ;----------------
- ; On Entry:
- ; None
- ; On Exit:
- ; AX = boot options
- mov si,offset CGROUP:starting_dos_msg
- lodsb ; get 1st character (never NULL)
- get_boot_options10:
- mov ah,0Eh
- mov bx,7
- int VIDEO_INT ; TTY write of character
- lodsb ; fetch another character
- test al,al ; end of string ?
- jnz get_boot_options10
- call option_key ; poll keyboard for a while
- jnz get_boot_options20 ; if key available return that
- mov ah,2 ; else ask ROS for shift state
- int 16h
- and ax,3 ; a SHIFT key is the same as F5KEY
- jz get_boot_options20
- mov ax,F5KEY ; ie. bypass everything
- get_boot_options20:
- ret
- option_key:
- ;----------
- ; On Entry:
- ; None
- ; On Exit:
- ; AX = keypress if interesting (F5/F8)
- ; ZF clear if we have an interesting key
- ;
- ; Poll keyboard looking for a key press. We do so for a maximum of 36 ticks
- ; (approx 2 seconds).
- ;
- xor ax,ax
- int 1Ah ; get ticks in DX
- mov cx,dx ; save in CX for later
- option_key10:
- push cx
- mov ah,1
- int 16h ; check keyboard for key
- pop cx
- jnz option_key30 ; stop if key available
- push cx
- xor ax,ax
- int 1Ah ; get ticks in DX
- pop cx
- sub dx,cx ; work out elapsed time
- cmp dx,36 ; more than 2 secs ?
- jb option_key10
- option_key20:
- xor ax,ax ; timeout, set ZF, no key pressed
- ret
- option_key30:
- cmp ax,F5KEY ; if it is a key we want then
- je option_key40 ; read it, else just leave
- cmp ax,F8KEY ; in the type-ahead buffer
- jne option_key20
- option_key40:
- xor ax,ax
- int 16h ; read the key
- test ax,ax ; clear ZF to indicate we have a key
- ret
- ICODE ends
- INITDATA segment 'INITDATA'
- ; This is a zero terminated list of locations to be fixed up with the
- ; segment of the relocated BIOS RCODE
- bios_fixup_tbl dw CG:MemFixup
- dw CG:OutputBSFixup
- dw CG:DriverFunctionFixup
- dw CG:Int0Fixup
- dw CG:Int13DeblockFixup
- dw CG:Int13UnsureFixup
- dw CG:Int2FFixup
- dw CG:ResumeFixup
- IFDEF EMBEDDED
- dw CG:RdiskFixup
- endif
- dw 0
- INITDATA ends
- CODE segment 'CODE'
- IFDEF EMBEDDED
- extrn RdiskFixup:word
- endif
- CODE ends
- RCODE_ALIGN segment public para 'RCODE'
- ifndef ROMSYS
- db 1100h dup(0) ; reserve space for command.com
- endif
- RCODE_ALIGN ends
- RCODE segment public word 'RCODE'
- rcode_header dw 0
- Public DataSegment
- DataSegment dw 0070h ; segment address of low data/code
- ; Called to vector to appropriate sub-function in device driver
- ; The Function table address immediately follows the near call, so we can index
- ; into it using the return address. If the offset is in the range 0-6 it's
- ; actually a device number for the serial/parallel driver
- ;
- ;
- ; On Entry to subfunctions ES:BX -> req_hdr, DX = devno (serial/parallel)
- ;
- FunctionTable struc
- FunctionTableMax db ?
- FunctionTableEntry dw ?
- FunctionTable ends
- Public DriverFunction
- DriverFunction proc far
- cld
- sub sp,(size P_STRUC)-4 ; make space for stack variables
- push bp ; (BP and RET are included)
- mov bp,sp ; set up stack frame
- pushx <ds,es>
- pushx <ax,bx,cx,dx,si,di> ; save all registers
- mov ds,cs:DataSegment
- mov si,(size P_STRUC)-2[bp] ; get return address = command table
- lodsw ; AX = following word
- xchg ax,dx ; DX = device number (0-6)
- mov si,offset CGROUP:SerParCommonTable
- cmp dx,6 ; if not a device number it's a table
- jbe DriverFunction10
- mov si,dx ; DS:SI -> table
- DriverFunction10:
- les bx,req_ptr ; ES:BX -> request header
- mov REQUEST_OFF[bp],bx
- mov REQUEST_SEG[bp],es
- mov al,es:RH_CMD[bx] ; check if legal command
- cmp al,cs:FunctionTableMax[si]
- ja cmderr ; skip if out of range
- cbw ; convert to word
- add ax,ax ; make it a word offset
- add si,ax ; add index to function table
- call cs:FunctionTableEntry[si]
- les bx,REQUEST[bp]
- cmddone:
- or ax,RHS_DONE ; indicate request is "done"
- mov es:RH_STATUS[bx],ax ; update the status for BDOS
- popx <di,si,dx,cx,bx,ax> ; restore all registers
- popx <es,ds>
- pop bp
- add sp,(size P_STRUC)-2 ; discard stack variables
- ret
- cmderr:
- mov ax,RHS_ERROR+3 ; "invalid command" error
- jmps cmddone ; return the error
- DriverFunction endp
- OutputBS proc far
- ;-------
- ; pushx <ax, bx, si, di, bp> ; these are on the stack
- pushx <cx, dx>
- mov ah,3 ; get cursor address
- mov bh,0 ; on page zero
- int VIDEO_INT ; BH = page, DH/DL = cursor row/col
- test dx,dx ; row 0, col 0
- jz OutputBS10 ; ignore if first line
- dec dl ; are we in column 0?
- jns OutputBS10 ; no, normal BS
- dec dh ; else move up one line
- push ds
- xor ax,ax
- mov ds,ax
- mov dl,ds:byte ptr [44ah] ; DL = # of columns
- dec dx ; DL = last column
- pop ds
- mov ah,2 ; set cursor, DH/DL = cursor, BH = page
- int VIDEO_INT ; set cursor address
- jmps OutputBS20
- OutputBS10:
- mov ax,0E08h ; use ROS TTY-like output function
- mov bx,7 ; use the normal attribute
- int VIDEO_INT ; output the character in AL
- OutputBS20:
- popx <dx, cx>
- popx <bp, di, si, bx, ax>
- iret
- OutputBS endp
- Int0Handler proc far
- ;----------
- cld
- push cs
- pop ds
- mov si,CG:div_by_zero_msg ; DS:SI points at ASCIZ message
- mov bx,STDERR ; to STDERR - where else ?
- mov cx,1 ; write one at a time
- int0_loop:
- mov dx,si ; DS:DX points at a char
- lodsb ; lets look at it first
- test al,al ; end of string ?
- je int0_exit
- mov ah,MS_X_WRITE ; write out the error
- int DOS_INT
- jnc int0_loop ; if it went OK do another
- int0_exit:
- mov ax,MS_X_EXIT*256+1 ; time to leave - say we got an error
- int DOS_INT ; go for it!
- Int0Handler endp
- RCODE ends
- end init