dos_compilers/Microsoft Pascal v1/ENTX6L.ASM
2024-06-30 06:59:54 -07:00

205 lines
8.1 KiB
NASM
Raw Permalink 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.

NAME ENTX
; Microsoft MS-DOS Computer Pascal runtime system control
; Version 1.00 (C) Copyright 1981 by Microsoft Corp
;Memory Layout:
;
; Hi -> COMMAND (may be overlayed)
; CONST segment
; DATA segment
; STACK segment
; MEMORY segment
; HEAP segment
; CODE segments
; Lo -> DOS code and data (fixed)
;
;The linker is told to load low and use DS allocation. Only 512 bytes
;of initial stack are allocated, and no heap at all. BEGXQQ moves all
;data to high memory, creating a gap in which the stack grows downward
;and the heap grows upward. The heap can grow downward over code too.
EXTRN ENTGQQ:FAR ;Main program entry point
EXTRN INIUQQ:FAR,ENDUQQ:FAR ;file system initialize/terminate
EXTRN ENDYQQ:FAR ;file system, close files
EXTRN BEGOQQ:FAR,ENDOQQ:FAR ;user system initialize/terminate
;First dummy code segment tells linker to load code lowest
;
INIXQQ SEGMENT 'CODE'
INIXQQ ENDS
;Heap segment definition (lowest of the data segments)
;
HEAP SEGMENT PUBLIC 'MEMORY'
MEMLO EQU THIS BYTE ;lowest data byte address
HEAP ENDS
;Memory segment definition (special purpose zero length)
;
MEMORY SEGMENT PUBLIC 'MEMORY'
MEMORY ENDS
;Stack segment definition (fixed initial minimal length)
;
STACK SEGMENT STACK 'STACK'
DB 256 DUP (?)
SKTOP EQU THIS BYTE
STACK ENDS
;FIRST resident public data
;
DATA SEGMENT PUBLIC 'DATA'
PUBLIC CSXEQQ ;pointer to sourcef context list
CSXEQQ DW 0
PUBLIC CLNEQQ ;last line number encountered
CLNEQQ DW 0
PUBLIC PNUXQQ ;pointer to unit initialization list
PNUXQQ DW 0
PUBLIC HDRFQQ ;Pascal open file list header
HDRFQQ DW 0
PUBLIC HDRVQQ ;Unit V open file list header
HDRVQQ DW 0
PUBLIC RESEQQ ;machine error context, stack ptr
RESEQQ DW 0
PUBLIC REFEQQ ;machine error context, frame ptr
REFEQQ DW 0
PUBLIC REPEQQ ;machine error context, program offset
REPEQQ DW 0
PUBLIC RECEQQ ;machine error context, program segment
RECEQQ DW 0
PUBLIC BEGHQQ ;first header word in heap
BEGHQQ DW 0
PUBLIC CURHQQ ;pointer to current heap item
CURHQQ DW 0
PUBLIC ENDHQQ ;just past end of the heap
ENDHQQ DW 0
PUBLIC STKBQQ ;stack start, to fix long GOTO
STKBQQ DW 0
PUBLIC STKHQQ ;stack limit, to check overflow
STKHQQ DW 0
PUBLIC CRCXQQ ;value of CX for DOS call
CRCXQQ DW 0
PUBLIC CRDXQQ ;value of DX for DOS call
CRDXQQ DW 0
PUBLIC CESXQQ ;DOS saved ES value (for command line)
DOSOFF DW 0 ;DOS exit offset, 0
CESXQQ DW 0 ;DOS saved ES value
DATA ENDS
;Constant segment definition
;
CONST SEGMENT PUBLIC 'CONST'
CONST ENDS
;Code for this module
;
ENTXQQ SEGMENT 'CODE'
DGROUP GROUP DATA,STACK,CONST,HEAP,MEMORY
ASSUME CS:ENTXQQ,DS:DGROUP,ES:DGROUP,SS:DGROUP
PUBLIC BEGXQQ,ENDXQQ,DOSXQQ ;main entry and exit points
;BEGXQQ: Initialization code
; - move DGROUP up as much as possible to get gap
; - set initial stackpointer, framepointer, STKBQQ
; - clear RESEQQ (machine error context)
; - clear CSXEQQ (sourcef error context)
; - clear PNUXQQ (unit init list header)
; - clear HDRFQQ and HDRVQQ (open file headers)
; - set BEGHQQ, CURHQQ, ENDHQQ, STKHQQ (heap init)
; - call INIUQQ (file initialization)
; - call BEGOQQ (user initialization)
; - call ENTGQQ (main program entry)
;
BEGXQQ PROC FAR
MOV AX,DGROUP ;get assumed data segment value
MOV DS,AX ;only need to address CESXQQ
MOV CESXQQ,ES ;save incomming ES value
MOV DX,OFFSET DGROUP:MEMLO ;DS offset to lowest data
SHR DX,1 ;make into word offset address
MOV CX,32768 ;highest word address possible
SUB CX,DX ;count of words in data segment
SHR DX,1 ;make count
SHR DX,1 ; into paragraph
SHR DX,1 ; (segment) address
INC DX ;round to next paragraph address
ADD DX,AX ;DX is start-of-data paragraph
MOV BX,2 ;[assembler rejects ES:2]
MOV BP,ES:[BX] ;DOS end paragraph
MOV BX,DX ;save to initialize heap later
ADD DX,4096 ;optimal end-of-data paragraph
CMP DX,BP ;enough memory for 64K data ?
JLE MEMA ;yes, can use optimal address
MOV DX,BP ;no, must use highest address
MEMA: SUB DX,4096 ;DX is final DS (may be negative)
STD ;set direction flag
MOV DS,AX ;source segment
MOV SI,65534 ;source offset
MOV ES,DX ;target segment
MOV DI,SI ;target offset
REP MOVSW ;move DS:SI-- to ES:DI-- until CX-=0
MOV DS,DX ;final DS value (may be negative)
CLI ;no interrupts (no stack)
MOV SS,DX ;initialize stack segment
MOV SP,OFFSET DGROUP:SKTOP ;set stackpointer
STI ;interrupts ok (stack ok)
MOV STKBQQ,SP ;to re-init SP after long GOTO
SUB BP,BP ;initial frame pointer zero
MOV RESEQQ,BP ;machine error context zero
MOV CSXEQQ,BP ;sourcef error context NIL
MOV PNUXQQ,BP ;unit init list header NIL
MOV HDRFQQ,BP ;Pascal open file header NIL
MOV HDRVQQ,BP ;Unit V open file header NIL
SUB BX,DX ;para addr of start of heap
SHL BX,1 ;make
SHL BX,1 ;into
SHL BX,1 ;offr
SHL BX,1 ;addr
MOV BEGHQQ,BX ;start of heap address
MOV CURHQQ,BX ;current heap item adr
MOV WORD PTR[BX],1 ;current header; free
ADD BX,2 ;byte after end of heap
MOV ENDHQQ,BX ;address after end of heap
ADD BX,384 ;comfortable boundary
MOV STKHQQ,BX ;stack overflow address
CALL INIUQQ ;initialize file system
CALL BEGOQQ ;initialize user system
CALL ENTGQQ ;call main program
;ENDXQQ: Termination code
; - call ENDOQQ (user termination)
; - call ENDYQQ (close open files)
; - call ENDUQQ (file termination)
; - return to operating system
;
ENDXQQ LABEL FAR ;termination entry point
CALL ENDOQQ ;user system termination
CALL ENDYQQ ;close all open files
CALL ENDUQQ ;file system termination
MOV DOSOFF,0 ;make sure jump offset zero
JMP DWORD PTR DOSOFF ;return to DOS
BEGXQQ ENDP
;DOSXQQ: Call DOS Operating System
;
DOSXQQ PROC FAR
POP SI ;get return ads
POP DI ;get return ads
POP DX ;get address parameter
POP AX ;get function parameter
MOV AH,AL ;must be in high half
MOV CX,CRCXQQ ;need CX for some functions
PUSH DI ;save return ads
PUSH SI ;save return ads
PUSH BP ;have to save this one
INT 33 ;onward to DOS
MOV CRCXQQ,CX ;return CX value
MOV CRDXQQ,DX ;return DX value
POP BP ;restore frame pointer
RET ;return (DOS ret in AX)
DOSXQQ ENDP
ENTXQQ ENDS
END BEGXQQ