dos_compilers/Mix Power C v1/INIT.ASM
2024-07-01 15:26:34 -07:00

381 lines
11 KiB
NASM

;
; Initialize the runtime environment.
; The block at $$Link$$ contains parameters passed from
; the linker.
;
; Determine memory bounds. Create stack and heap. Initialize
; fundamental parameters.
;
;
BUFSIZ EQU >200
FALSE EQU 0
TRUE EQU ~FALSE
ENVIR EQU >2C
DOS EQU >21
MARGIN EQU >80
OP$EXIT EQU >4C
OP$PMSG EQU >09
OP$VERS EQU >30
OP$TIME EQU >2C
OP$DATE EQU >2A
CMDLINE EQU >80
CMDLENGTH EQU >80
ARGV0LEN EQU 64
LONGNAME EQU >FFFF
SHORTNAM EQU >FFFF
CASE TRUE
;
IDT $_INIT_$
DEF $_INIT_$
DEF $_init_$
DEF $$RETURN
$_init_$ equ $
$_INIT_$ MOV AX,DS
MOV ES,AX
MOV BX,SS
MOV DS,BX
MOV [$$PSP],AX
SEGES
MOV AX,[ENVIR]
MOV [$$ENVIR],AX
MOV AH,OP$VERS ; Dos version number
INT DOS
MOV [_osmajor],AX
CMP AL,3 ; If 3.0 or greater
JB GETTIME
MOV ES,[$$ENVIR] ; scan environment for argv[0]
XOR DI,DI
MOV AL,%0
MOV CX,-1
CLD
ENVNEXT SEGES
CMP %[DI],%0 ; end of table?
JZ ENDENV
REPNZ
SCASB
JMPS ENVNEXT
ENDENV INC DI ; skip terminator
SEGES
CMP [DI],1
JNZ GETTIME ; no argv[0]
ADD DI,%2
MOV SI,$$ARGV0
MOV CX,ARGV0LEN/2
CPYARG0 SEGES
MOV AX,[DI]
MOV [SI],AX
ADD DI,%2
ADD SI,%2
LOOP CPYARG0
GETTIME MOV AH,OP$DATE
INT DOS
MOV [$$CLOCK],CX
MOV [$$CLOCK2],DX
MOV AH,OP$TIME
INT DOS
MOV [$$CLOCK4],CX
MOV [$$CLOCK6],DX
MOV ES,[$$PSP]
SEGES
MOV SI,[2] ; Top of available memory
MOV [$$MAXSEG],SI
MOV DX,DS
SUB SI,DX
CMP SI,>1000 ; More than 64k available?
JAE DS64K
MOV CL,4
SHL SI,CL
DEC SI
JMPS DSSET
DS64K MOV SI,>FFFF
DSSET MOV BX,[DSSIZE] ; Size of initialized data
ADD BX,MARGIN
MOV [$$LIMIT],BX ; Lower limit of stack
MOV AX,[STKSIZE]
TEST AX,AX ; Zero means default
JNZ STACKVAL
MOV AX,[HPSIZE] ; Check heap size
TEST AX,AX
JNZ HPSET
MOV AX,SI
SUB AX,BX
SHR AX,1 ; Half of memory for stack
SUB AX,2
AND AX,>FFFE
MOV [STKSIZE],AX
MOV [HPSIZE],AX
JMPS STACKSET
STACKVAL TEST [HPSIZE],>FFFF
JNZ STACKSET
MOV CX,SI
SUB CX,AX
JB NOMEM1
SUB CX,BX
JB NOMEM1
DEC CX
JB NOMEM1
AND CX,>FFFE
MOV [HPSIZE],CX
JMPS STACKSET
HPSET MOV CX,SI
SUB CX,AX
JB NOMEM1
SUB CX,BX
JB NOMEM1
DEC CX
AND CX,>FFFE
JNB MEMOK
NOMEM1 JMP NOMEM
MEMOK MOV [STKSIZE],CX
MOV AX,CX
STACKSET ADD BX,AX
JB NOMEM1
CMP BX,SI ; Enough memory available
JA NOMEM1
MOV [$$BOTTOM],BX ; Top limit of stack
MOV [$$MAXS],BX ; Maximum stack used
INC BX
AND BX,>FFFE
POP AX ; Copy return address
POP CX ; to new stack
MOV SP,BX ; Set stack location for program
MOV DX,CS
PUSH DX ; Set final return address
MOV [$$RETIS],DX
MOV DX,$$RETURN
PUSH DX
MOV [$$RETI],DX
MOV BP,SP ; Initial frame
PUSH CX ; Save return to program
PUSH AX
MOV AX,DS ; initialize to zero
MOV ES,AX
MOV DI,[$$LIMIT]
MOV CX,SP
SUB CX,256
SUB CX,DI
SHR CX,1
XOR AX,AX
REP
STOSW
;
; Create heap
;
INC BX ; Start heap on word boundary
AND BX,>0FFFE
MOV [$$HMIN],BX
XOR AX,AX
MOV [$$CURH],AX ; No heap used
MOV [$$MAXH],AX
ADD BX,[HPSIZE]
JZ ALLMEM
JB NOMEM1
JMPS MAKEHEAP
ALLMEM MOV BX,>FFFE
MAKEHEAP AND BX,>FFFE ; Make top of heap a word boundary
MOV [$$HMAX],BX ; STORE HEAP LIMIT
MOV AX,BX
DEC AX ; round up with top-16+15
MOV CL,4
SHR AX,CL
INC AX ; add back the 16
MOV DX,DS
ADD AX,DX
MOV [$$TOPSEG],AX ; First unused extra memory
MOV [$$ENDDS],AX ; Segment of end of ds
SUB AX,DX
SHL AX,CL
MOV [$$TOPDS],AX ; Top of data segment
ADD BX,-6 ; RESERVE DUMMY PACKET
MOV CX,BX ; SAVE POINTER TO DUMMY
MOV DX,BX ; SAVE POINTER TO DUMMY
MOV [BX],0 ; LENGTH OF DUMMY PACKET
MOV AX,[$$HMIN] ; AX=ADDRESS OF INITIAL HEAP
MOV [BX][%2],AX ; SET NEXT PACKET PTR
MOV [BX][%4],AX ; SET PREDECESSOR PTR
;
; SET LENGTH OF INITIAL HEAP PACKET
;
SUB CX,AX ; CALCULATE HEAP SIZE
MOV [$$FREE],AX
MOV BX,AX ; POINT TO BIG HEAP PACKET
MOV [BX],CX ; SET HEAP SIZE
MOV [BX][%2],DX ;NEXT IS DUMMY PACKET
MOV [BX][%4],DX ;PREDECESSOR IS DUMMY PACKET
;
; COPY COMMAND LINE TO DATA SEGMENT
;
MOV SI,CMDLINE
MOV ES,[$$PSP]
SEGES
MOV CL,[SI] ; Length of command line
CMP CL,5
JB COPYALL ; Too short for trace
SEGES
CMP %[SI][%1],%>0D
JNZ COPYALL ; Not trace
SEGES
MOV AX,[SI][%2]
MOV [$$XTRC],AX
SEGES
MOV AX,[SI][%4]
MOV [$$XTRC2],AX
PUSH AX
PUSH [$$XTRC]
SUB CL,%5
ADD SI,%5
SEGES
MOV %[SI],CL
COPYALL MOV DI,$$CMDLIN
MOV CX,CMDLENGTH/2
MOV AX,DS
MOV ES,AX
MOV DS,[$$PSP]
COPYCMD REP
MOVSW
MOV AX,ES
MOV DS,AX
MOV ES,[$$PSP]
XOR BX,BX
RETSEG
;
$$RETURN MOV AX,[$$EXSTAT]
TEST AH,AH
JZ STOP
MOV AL,%>FF
STOP CMP [$$XTRC2],0
JZ NOTRC
MOV BX,1
CALLSEG [$$XTRC]
NOTRC MOV AH,OP$EXIT
INT DOS
NOMEM MOV DX,NOMEMMSG
MOV AH,OP$PMSG
INT DOS
MOV AL,%>FE
JMPS STOP
;
; Data areas.
; $$Link$$ contains information supplied by the linker.
; $$PROCES contains control and status information used
; by the program.
;
DORG 0
;
; Process control record. Contains status values, limits and
; runtime flags
;
$$PROCES EQU $
$$EXITPT DW $$RETI ; Exit address
$$BOTTOM DW 0 ; Stack bottom (empty stack)
$$LIMIT DW 0 ; Stack limit (full stack)
$$HMIN DW 0 ; Lower bound of heap
$$HMAX DW 0 ; Upper bound of heap
$$FREE DW 0 ; Free space pointer for heap
$$MAXS DW 0 ; Maximum stack used
$$MAXH DW 0 ; Maximum heap used
$$CURH DW 0 ; Current heap used
$$IOTERM DB 0 ; Terminate on io error
$$HPTERM DB 0 ; Terminate on heap full
$$IOFLG DB 0 ; IO default flags
$$ZFILL DB 0 ; Zero locals & heap packets flag
$$FATAL DW 0 ; Fatal error address
DW 0 ; Fatal error address (segment)
$$CMDPTR DW $$CMDLIN ; Address of command line
$$LIOERR DW 0 ; File for last io error
_psp EQU $
$$PSP DW 0 ; Program segment prefix segment
$$ENVIR DW 0 ; Environment segment
$$XTRC DW 0 ; Address of ctrace
$$XTRC2 DW 0 ; Address of ctrace (segment)
DW 0,0,0
;
errno DW 0 ; Error number
_doserrn DW 0 ; Operating system error code
$$FLERR DW 0 ; Floating point error code
$$BUFSIZ DW BUFSIZ ; Default buffer size for files
$$MAXSEG DW 0 ; First unavailable paragraph
$$TOPSEG DW 0 ; First unused paragraph
$$TOPDS DW 0 ; Top address in data segment
$$ENDDS DW 0 ; Segment of end of data segment
$$EXSTAT DW 0 ; Exit status
$$MACHIN DB 0
$$OPSYS DB >20
$$SHMSG DB 0 ; Display statistics
$$CLFEED DB 1 ; Filter line feeds (default)
$$CCTLZ DB 0 ; Treat ctl/z as end of file (default)
$$STATSV DB 0
$$UBCON DB 0 ; Unbuffered console
$$ARTERM DB 0 ; Terminate on arithmetic errors
$$RETI DW 0 ; Far address of exit routine
$$RETIS DW 0
$$CMDLIN DS >80 ; Copy of command line
_osmajor DB 0
_osminor DB 0
$$CLOCK DW 0
$$CLOCK2 DW 0
$$CLOCK4 DW 0
$$CLOCK6 DW 0
$$ARGV0 DB 0
DS ARGV0LEN
NOMEMMSG DB 'Not enough memory$'
DDEF $$Link$$
DORG 2*(($+1)/2)
$$Link$$ EQU $
STKSIZE DW 0 ; Stack size
HPSIZE DW 0 ; Heap size
DSSIZE DW 0 ; Size of initialized data
DW 0,0,0,0,0 ; Filler for more parameters
DW 0,0,0,0,0,0,0,0
DDEF $$EXITPT
DDEF $$BOTTOM
DDEF $$LIMIT
DDEF $$HMIN
DDEF $$HMAX
DDEF $$FREE
DDEF $$MAXS
DDEF $$MAXH
DDEF $$CURH
DDEF $$IOTERM
DDEF $$HPTERM
DDEF $$IOFLG
DDEF $$ZFILL
DDEF $$FATAL
DDEF $$CMDPTR
DDEF $$LIOERR
DDEF $$PSP
DDEF _psp
DDEF $$ENVIR
DDEF $$XTRC
DDEF $$XTRC2
DDEF errno
IF SHORTNAM
DDEF _doserrn
ENDIF
IF LONGNAME
LDDEF _doserrno
ENDIF
DDEF $$FLERR
DDEF $$BUFSIZ
DDEF $$MAXSEG
DDEF $$TOPSEG
DDEF $$TOPDS
DDEF $$ENDDS
DDEF $$EXSTAT
DDEF $$MACHIN
DDEF $$OPSYS
DDEF $$SHMSG
DDEF $$CLFEED
DDEF $$CCTLZ
DDEF $$STATSV
DDEF $$UBCON
DDEF $$ARTERM
DDEF $$RETI
DDEF $$CMDLIN
DDEF _osmajor
DDEF _osminor
DDEF $$CLOCK
DDEF $$ARGV0
END
;