Created
July 12, 2022 15:51
-
-
Save tschak909/81561b47866ac0b7c01888aa5011ed37 to your computer and use it in GitHub Desktop.
IBM PASCAL Entry/Exit extrinsic code.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
NAME ENTX | |
; IBM Personal Computer Pascal runtime system control | |
; Version 1.00 (C) Copyright 1981 by IBM 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 512 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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment