Skip to content

Instantly share code, notes, and snippets.

@tschak909
Created July 12, 2022 15:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tschak909/81561b47866ac0b7c01888aa5011ed37 to your computer and use it in GitHub Desktop.
Save tschak909/81561b47866ac0b7c01888aa5011ed37 to your computer and use it in GitHub Desktop.
IBM PASCAL Entry/Exit extrinsic code.
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