MS-DOS/v2.0/source/MSINIT.ASM

408 lines
13 KiB
NASM
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

; TITLE MSINIT.ASM -- MS-DOS INITIALIZATION CODE
ORG 0 ; reset to beginning of data segment
; Init code below overlaps with data area
INITBLOCK DB 110H DUP(0) ; Allow for segment round up
INITSP DW ?
INITSS DW ?
BUFFSTRT DW ?
ASSUME CS:DOSGROUP,DS:DOSGROUP,ES:DOSGROUP,SS:NOTHING
EXTRN QUIT:NEAR,IRET:NEAR,ABSDRD:FAR,ABSDWRT:FAR
EXTRN COMMAND:NEAR,CALL_ENTRY:NEAR
IF NOT IBM
EXTRN HEADER:BYTE
ENDIF
MOVDPB:
; This section of code is safe from being overwritten by block move
MOV SP,CS:[INITSP]
MOV SS,CS:[INITSS]
REP MOVS BYTE PTR [DI],[SI]
CLD
MOV WORD PTR ES:[DMAADD+2],DX
MOV SI,WORD PTR [DPBHEAD] ; Address of first DPB
MOV WORD PTR ES:[DPBHEAD+2],ES
MOV WORD PTR ES:[sft_addr+2],ES
MOV CL,[NUMIO] ; Number of DPBs
XOR CH,CH
SETFINDPB:
MOV WORD PTR ES:[SI.dpb_next_dpb+2],ES
MOV ES:[SI.dpb_first_access],-1 ; Never accessed before
ADD SI,DPBSIZ ; Point to next DPB
LOOP SETFINDPB
SUB SI,DPBSIZ
MOV WORD PTR ES:[SI.dpb_next_dpb+2],-1
MOV DI,[BUFFSTRT] ; Set up one default buffer
MOV WORD PTR ES:[BUFFHEAD+2],ES
MOV WORD PTR ES:[BUFFHEAD],DI
MOV WORD PTR ES:[DI.BUFDRV],00FFH
MOV ES:[DI.BUFPRI],FREEPRI
MOV WORD PTR ES:[DI.NEXTBUF],-1
MOV WORD PTR ES:[DI.NEXTBUF+2],-1
PUSH ES
INC DX ; Leave enough room for the ARENA
MOV BYTE PTR [CreatePDB],0FFh ; create jfns and set CurrentPDB
invoke $CREATE_PROCESS_DATA_BLOCK ; Set up segment
ASSUME DS:NOTHING,ES:NOTHING
POP ES
ASSUME ES:DOSGROUP
;
; set up memory arena
;SPECIAL NOTE FOR HIGHMEM VERSION
; At this point a process header has been built where the start of the
; CONSTANTS segment as refed by CS is. From this point until the return
; below be careful about references off of CS.
;
PUSH AX
MOV AX,[CurrentPDB]
MOV ES:[CurrentPDB],AX ; Put it in the REAL location
MOV BYTE PTR ES:[CreatePDB],0h ; reset flag in REAL location
DEC AX
MOV ES:[arena_head],AX
PUSH DS
MOV DS,AX
MOV DS:[arena_signature],arena_signature_end
MOV DS:[arena_owner],arena_owner_system
SUB AX,ES:[ENDMEM]
NEG AX
DEC AX
MOV DS:[arena_size],AX
POP DS
POP AX
MOV DI,OFFSET DOSGROUP:sftabl + sft_table ; Point to sft 0
MOV AL,3
STOSB ; Adjust Refcount
MOV DI,OFFSET DOSGROUP:SYSINITVAR
XXX PROC FAR
RET
XXX ENDP
DATA ENDS
; the next segment defines a new class that MUST appear last in the link map.
; This defines several important locations for the initialization process that
; must be the first available locations of free memory.
LAST SEGMENT BYTE PUBLIC 'LAST'
PUBLIC SYSBUF
PUBLIC MEMSTRT
SYSBUF LABEL WORD
ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING
DOSINIT:
CLI
CLD
MOV [ENDMEM],DX
MOV [INITSP],SP
MOV [INITSS],SS
MOV SP,OFFSET DOSGROUP:INITSTACK
MOV AX,CS
MOV SS,AX
ASSUME SS:DOSGROUP
MOV WORD PTR [DEVHEAD+2],DS
MOV WORD PTR [DEVHEAD],SI ; DS:SI Points to CONSOLE Device
CALL CHARINIT
PUSH SI
ADD SI,SDEVNAME ; Point to name
PUSH CS
POP ES
ASSUME ES:DOSGROUP
MOV DI,OFFSET DOSGROUP:sftabl + sft_table ; Point to sft 0
MOV AL,3
STOSB ; Refcount
DEC AL
STOSB ; Access rd/wr
XOR AL,AL
STOSB ; Drive byte
STOSB ; attribute
MOV CX,4
REP MOVSW ; Name
MOV CL,3
MOV AL," "
REP STOSB ; Extension
ADD DI,12 ; Skip
MOV AL,0C0H OR ISCIN OR ISCOUT
STOSB
POP SI
MOV AX,SI
STOSW ; Device pointer in FIRCLUS
MOV AX,DS
STOSW
OR BYTE PTR [SI.SDEVATT],ISCIN OR ISCOUT
MOV WORD PTR [BCON],SI
MOV WORD PTR [BCON+2],DS
CHAR_INIT_LOOP:
LDS SI,DWORD PTR [SI] ; AUX device
CALL CHARINIT
TEST BYTE PTR [SI.SDEVATT],ISCLOCK
JZ CHAR_INIT_LOOP
MOV WORD PTR [BCLOCK],SI
MOV WORD PTR [BCLOCK+2],DS
MOV BP,OFFSET DOSGROUP:MEMSTRT ; ES:BP points to DPB
PERDRV:
LDS SI,DWORD PTR [SI] ; Next device
CMP SI,-1
JZ CONTINIT
CALL CHARINIT
TEST [SI.SDEVATT],DEVTYP
JNZ PERDRV ; Skip any other character devs
MOV CL,[CALLUNIT]
XOR CH,CH
MOV [SI.SDEVNAME],CL ; Number of units in name field
MOV DL,[NUMIO]
XOR DH,DH
ADD [NUMIO],CL
PUSH DS
PUSH SI
LDS BX,[CALLBPB]
PERUNIT:
MOV SI,[BX] ; DS:SI Points to BPB
INC BX
INC BX ; On to next BPB
MOV ES:[BP.dpb_drive],DL
MOV ES:[BP.dpb_UNIT],DH
PUSH BX
PUSH CX
PUSH DX
invoke $SETDPB
MOV AX,ES:[BP.dpb_sector_size]
CMP AX,[MAXSEC]
JBE NOTMAX
MOV [MAXSEC],AX
NOTMAX:
POP DX
POP CX
POP BX
MOV AX,DS ; Save DS
POP SI
POP DS
MOV WORD PTR ES:[BP.dpb_driver_addr],SI
MOV WORD PTR ES:[BP.dpb_driver_addr+2],DS
PUSH DS
PUSH SI
INC DH
INC DL
MOV DS,AX
ADD BP,DPBSIZ
LOOP PERUNIT
POP SI
POP DS
JMP PERDRV
CONTINIT:
PUSH CS
POP DS
ASSUME DS:DOSGROUP
; Calculate true address of buffers, FATs, free space
MOV DI,BP ; First byte after current DPBs
MOV BP,[MAXSEC]
MOV AX,OFFSET DOSGROUP:SYSBUF
MOV [BUFFSTRT],AX
ADD AX,BP ; One I/O buffer
ADD AX,BUFINSIZ
MOV WORD PTR [DPBHEAD],AX ; True start of DPBs
MOV DX,AX
SUB DX,OFFSET DOSGROUP:SYSBUF
MOV BP,DX
ADD BP,DI ; Allocate buffer space
SUB BP,ADJFAC ; True address of free memory
PUSH BP
MOV DI,OFFSET DOSGROUP:MEMSTRT ; Current start of DPBs
ADD DI,dpb_next_dpb ; Point at dpb_next_dpb field
MOV CL,[NUMIO]
XOR CH,CH
TRUEDPBAD:
ADD AX,DPBSIZ ; Compute address of next DPB
STOSW ; Set the link to next DPB
ADD DI,DPBSIZ-2 ; Point at next address
LOOP TRUEDPBAD
SUB DI,DPBSIZ ; Point at last dpb_next_dpb field
MOV AX,-1
STOSW ; End of list
ADD BP,15 ;True start of free space (round up to segment)
MOV CL,4
SHR BP,CL ; Number of segments for DOS resources
MOV DX,CS
ADD DX,BP ; First free segment
MOV BX,0FH
MOV CX,[ENDMEM]
IF HIGHMEM
SUB CX,BP
MOV BP,CX ; Segment of DOS
MOV DX,CS ; Program segment
ENDIF
IF NOT HIGHMEM
MOV BP,CS
ENDIF
; BP has segment of DOS (whether to load high or run in place)
; DX has program segment (whether after DOS or overlaying DOS)
; CX has size of memory in paragraphs (reduced by DOS size if HIGHMEM)
MOV [ENDMEM],CX
MOV ES,BP
ASSUME ES:DOSGROUP
IF HIGHMEM
XOR SI,SI
MOV DI,SI
MOV CX,OFFSET DOSGROUP:SYSBUF ;# bytes to move
SHR CX,1 ;# words to move (carry set if odd)
REP MOVSW ; Move DOS to high memory
JNC NOTODD
MOVSB
NOTODD:
ENDIF
MOV WORD PTR ES:[DSKCHRET+3],ES
XOR AX,AX
MOV DS,AX
MOV ES,AX
ASSUME DS:NOTHING,ES:NOTHING
MOV DI,INTBASE+2
MOV AX,BP
MOV BYTE PTR DS:[ENTRYPOINT],mi_Long_JMP
MOV WORD PTR DS:[ENTRYPOINT+1],OFFSET DOSGROUP:CALL_ENTRY
MOV WORD PTR DS:[ENTRYPOINT+3],AX
EXTRN DIVOV:near
MOV WORD PTR DS:[0],OFFSET DOSGROUP:DIVOV ; Set default divide
; trap address
MOV DS:[2],AX
MOV CX,17
REP STOSW ; Set 9 segments (skip 2 between each)
IF ALTVECT
MOV DI,ALTBASE+2
MOV CX,15
REP STOSW ; Set 8 segments (skip 2 between each)
ENDIF
MOV WORD PTR DS:[addr_int_abort],OFFSET DOSGROUP:QUIT
MOV WORD PTR DS:[addr_int_command],OFFSET DOSGROUP:COMMAND
MOV WORD PTR DS:[addr_int_terminate],100H
MOV WORD PTR DS:[addr_int_terminate+2],DX
MOV WORD PTR DS:[addr_int_ctrl_c],OFFSET DOSGROUP:IRET
; Ctrl-C exit
MOV WORD PTR DS:[addr_int_fatal_abort],OFFSET DOSGROUP:IRET
; Fatal error exit
MOV WORD PTR DS:[addr_int_disk_read],OFFSET DOSGROUP:ABSDRD
; INT 25
MOV WORD PTR DS:[addr_int_disk_write],OFFSET DOSGROUP:ABSDWRT
; INT 26
EXTRN Stay_resident:NEAR
MOV WORD PTR DS:[addr_int_keep_process],OFFSET DOSGROUP:Stay_resident
MOV WORD PTR DS:[addr_int_spooler],OFFSET DOSGROUP:IRET ; Spooler
IF NOT ALTVECT
MOV CX,12
XOR AX,AX
MOV DI,2AH*4
REP STOSW ;Zero interrupt locs for ints 2AH-2FH
ENDIF
PUSH CS
POP DS
PUSH CS
POP ES
ASSUME DS:DOSGROUP,ES:DOSGROUP
MOV AX,OFFSET DOSGROUP:INITBLOCK
ADD AX,0Fh ; round to a paragraph
MOV CL,4
SHR AX,CL
MOV DI,DS
ADD DI,AX
INC DI
MOV [CurrentPDB],DI
PUSH BP
PUSH DX ; Save COMMAND address
MOV AX,[ENDMEM]
MOV DX,DI
invoke SETMEM ; Basic Header
ASSUME DS:NOTHING,ES:NOTHING
PUSH CS
POP DS
ASSUME DS:DOSGROUP
MOV DI,PDB_JFN_Table
XOR AX,AX
STOSW
STOSB ; 0,1 and 2 are CON device
MOV AL,0FFH
MOV CX,FilPerProc - 3
REP STOSB ; Rest are unused
PUSH CS
POP ES
ASSUME ES:DOSGROUP
MOV WORD PTR [sft_addr+2],DS ; Must be set to print messages
; After this points the char device functions for CON will work for
; printing messages
IF NOT IBM
IF NOT ALTVECT
MOV SI,OFFSET DOSGROUP:HEADER
invoke OUTMES
PUSH CS ; Outmes stomps on segments
POP DS
PUSH CS
POP ES
ENDIF
ENDIF
; Move the FATs into position
POP DX ; Restore COMMAND address
POP BP
POP CX ; True address of free memory
MOV SI,OFFSET DOSGROUP:MEMSTRT ; Place to move DPBs from
MOV DI,WORD PTR [DPBHEAD] ; Place to move DPBs to
SUB CX,DI ; Total length of DPBs
CMP DI,SI
JBE MOVJMP ; Are we moving to higher or
; lower memory?
DEC CX ; Move backwards to higher memory
ADD DI,CX
ADD SI,CX
INC CX
STD
MOVJMP:
MOV ES,BP
ASSUME ES:DOSGROUP
JMP MOVDPB
CHARINIT:
ASSUME DS:NOTHING,ES:NOTHING
; DS:SI Points to device header
MOV [DEVCALL.REQLEN],DINITHL
MOV [DEVCALL.REQUNIT],0
MOV [DEVCALL.REQFUNC],DEVINIT
MOV [DEVCALL.REQSTAT],0
PUSH ES
PUSH BX
PUSH AX
MOV BX,OFFSET DOSGROUP:DEVCALL
PUSH CS
POP ES
invoke DEVIOCALL2
POP AX
POP BX
POP ES
RET
DB 80H DUP(?)
INITSTACK LABEL BYTE
DW ?
MEMSTRT LABEL WORD
ADJFAC EQU MEMSTRT-SYSBUF
do_ext
LAST ENDS