DEFINITION MODULE Runtime ; (* 8086 runtime library for TP3-compiled programs. The original embeds its runtime in the compiler's own code segment and copies it to the front of the generated code buffer (TPSRC7 "copyrt": "MOV CX,#start / REPZ MOVS.B" with SI=DI=0, then "MOV pc,#$2D7C" so the generated program starts past it; the .COM writer emits the runtime as a block ahead of the program). Same shape here: RT_Build assembles the library into rt[0..RT_Size-1], the compiler copies it to the front of its code buffer and starts pc/dc past it, so the runtime's own data lives at low, link-time-constant addresses and needs no relocation. Entry offsets are *derived* from where the code actually lands, not hardcoded - see RT_Entry. Everything the compiler calls is reached by a relative CALL, and both sides shift by the same runtime size, so the displacement arithmetic in EmCall is unaffected by the runtime being prepended. *) FROM SYSTEM IMPORT BYTE ; CONST (* entry selectors for RT_Entry *) E_InitMem = 0 ; E_ProgEnd = 1 ; E_StackChk = 2 ; E_WrInt = 3 ; E_WrChar = 4 ; E_WrBool = 5 ; E_WrReal = 6 ; E_WrLn = 7 ; E_RdInt = 8 ; E_RdChar = 9 ; E_RdBool = 10 ; E_RdLn = 11 ; E_Halt = 12 ; E_WrInl = 13 ; PROCEDURE RT_Build () ; (* assemble the runtime; idempotent, called once at Compile time *) PROCEDURE RT_Size () : CARDINAL ; (* size of the runtime in bytes - the offset at which the generated program starts inside the image *) PROCEDURE RT_Byte (i : CARDINAL) : BYTE ; (* i-th runtime byte, 0 past the end, for hex dumps *) PROCEDURE RT_Entry (i : CARDINAL) : CARDINAL ; (* offset of entry i (an E_* selector) inside the runtime; 0 if unknown *) PROCEDURE RT_CodeEnd () : CARDINAL ; (* offset where the code stops and the runtime's data block starts. Bytes from here on are strings and scratch, so disassembling them is meaningless; tests use this to sweep the code region only. *) END Runtime.