* TO PROVIDE A SPECIAL-PURPOSE STACK MECHANISM FOR RECURSIVE
* PROGRAM CALLS
*
-* WHAT:
+* THEORY OF OPERATION:
*
-* THIS VARIANT OF THE STACK ROUTINE USES A FIXED SIZE MEMORY
-* BUFFER FOR THE THE STACK. THE STACK USAGE IS MONITORED.
-* ON OVERFLOW, THE COMPUTER TYPES OUT AN ERROR MESSAGE AND HALTS.
+* THE STACK ROUTINES MAINTAIN AN UPWARDS GROWING STACK.
+* EVERY USAGE CONTEXT OF THE STACK NEEDS TO RESERVE THE SPACE FOR
+* ITS STACK'S DATA. THIS ENABLES THE PROGRAMMER TO CHOOSE THE STACK
+* SIZE AND USE MULTIPLE STACKS IN MULTIPLE PLACES INDEPENDENTLY.
+* ALL STACK RELATED ROUTINES TAKE A POINTER TO THE STACK'S INTERNAL
+* DATA AS FIRST ARGUMENT.
*
+* THE DATA LAYOUT OF THE STACK DATA IS AS FOLLOWING:
+*
+* SIZE OCT '1000 SIZE OF THE STACK IN MACHINE WORDS
+* PTR DAC ** THE STACK POINTER
+* FILL DAC ** THE FILL COUNTER
+* OVER DAC OFL OPTIONAL POINTER TO OVERFLOW ERROR ROUTINE
+* UNDR DAC UFL OPTIONAL POINTER TO UNDERFLOW ERROR ROUTINE
+* STCK BSS '1000 THE STACK DATA
+*
+* IF CUSTOM ERROR HANDLING ROUTINES ARE NOT TO BE USED, SET THE TWO
+* POINTER LOCATIONS TO ZERO. THEN, INTERNAL ERROR ROUTINES WILL BE
+* USED. SIZE AND THE FUNCTION POINTERS HAVE TO BE INITIALISED. THE
+* OTHER LOCATIONS ARE INITIALISED BY THE STACK ROUTINES.
*
* USAGE:
*
* INITIALISING STACK POINTER:
*
-* CALL S$INIT
+* CALL S$INIT
+* DAC SDATA STACK DATA
+* OCT SSIZ DATA SIZE (NOT STACK DEPTH!!!)
*
* PUSHING AND POPPING THE A-REGISTER FROM AND TO THE STACK:
*
* CALL S$PUSH VALUE IN A REGISTER IS PUSHED.
-* CALL $$PUSH VALUE FROM STACK IS POPPED INTO A-REGISTER.
+* DAC SDATA
+*
+* CALL $$POP VALUE FROM STACK IS POPPED INTO A-REGISTER.
+* DAC SDATA
*
* PUSHING AND POPPING ARBITRARY DATA FROM AND TO THE STACK:
*
* CALL S$PUSM
+* DAC SDATA
* DAC ADDRESS
* OCT SIZE
*
* CALL S$POPM
+* DAC SDATA
* DAC ADDRESS
* OCT SIZE
+*
+*
+* MAKING A RECURSIVE CALL FROM FORTRAN IV TO A FORTRAN IV OR OTHER ROUTINE:
*
+* THE ROUTINE S$CALL SAVES A SET OF LOCAL VARIABLES ONTO THE STACK.
+* IT ALSO SAVES THE RETURN ADDRESS AND ITS OWN PARAMETERS.
+* S$LLAC DOES EVERYTHING IN REVERSE ORDER.
+*
+* HERE IS AN EXAMPLE HOW TO USE THE TWO ROUTINES IN FORTRAN IV:
+*
+* C LOCAL VARIABLES I(3),A,Z TO SAVE
+*
+* CALL S$CALL(3,I,3,A,2,Z,2)
+* RETURN <-- FOR THE RETURN ADDRESS OF THE CURRENT ROUTINE
+* CALL MYROUTINE(...)
+* CALL S$LLAC
+*
+* ASSEMBLER CALLING SEQUENCE:
+*
+* JST S$CALL
+* DAC VARNO NO OF LOCAL VARIABLES TO SAVE ON THE STACK
+* DAC VAR1 POINTER TO FIRST VARIABLE
+* DAC SIZE1 WORD SIZE OF VARIABLE
+* ...
+* DAC VARN POINTER TO LAST VARIABLE
+* DAC SIZEN WORD SIZE OF LAST VARIABLE
+* DAC 0 FORTRAN IV COMPILER GENERATED
*
+* JMP* PROC RETURN JUMP, GENERATED BY THE "RETURN" STATEMENT
+*
+* JST MYROUTINE
+* ...
+*
+* JST S$LLAC
+*
+*
********************************************************************************
*
*
SUBR S$PUSM,PUSM MEMORY RANGE PUSH
SUBR S$POPM,POPM MEMORY RANGE POP
SUBR S$PTR,SPTR STACK POINTER ACCESS
+ SUBR S$CALL,CALL
+ SUBR S$LLAC,LLAC
*
*
********************************************************************************
*
-*
-SSIZ EQU '1000 512 WORDS DEFAULT STACK BUFFER SIZE
*
REL RELOCATEABLE OBJECT
- ORG '0
*
*
********************************************************************************
-*
-*
-**** PUSH MEMORY RANGE TO STACK
+*
+* *** PUSH MEMORY RANGE TO STACK
*
PUSM DAC ** ENTRY POINT TO PUSH ROUTINE
STA ATM1 SAVE A-REGISTER
+*
+ LDA* PUSM LOAD DATA BASE
+ IRS PUSM
+ STA DPT SAVE FOR LATER USE
*
LDA* PUSM LOAD POINTER
STA PTR STORE TO TRANSFER POINTER
*
PULP LDA* PTR GET DATA
JST PUSH PUSH IT!
+DPT DAC **
+*
IRS PTR INCREMENT POINTER
IRS CNT INCREMENT BYTE COUNTER
JMP PULP DO IT AGAIN!
*
LDA ATM1 RESTORE A-REG
- JMP* PUSM
+ JMP* PUSM RETURN
*
*
********************************************************************************
POPM DAC ** ENTRY POINT TO PUSH ROUTINE
STA ATM1 SAVE A-REGISTER
*
+ LDA* POPM GET DATA POINTER
+ IRS POPM
+ STA DPTR STORE FOR LATER USE
+*
LDA* POPM LOAD POINTER
IRS POPM GO TO NEXT ARGUMENT
ADD* POPM ADD TRANSFER SIZE
STA CNT STORE TO COUNTER
*
POLP JST POP POP DATA FROM THE STACK
+DPTR DAC **
+*
STA* PTR STORE IT.
LDA PTR
SUB =1 DECREMENT
IRS CNT INCREMENT BYTE COUNTER
JMP POLP DO IT AGAIN!
*
- LDA ATM1
- JMP* POPM
+ LDA ATM1 RESTORE A-REG
+ JMP* POPM RETURN
*
*
********************************************************************************
*
**** PUSH SINGLE WORD ONTO STACK
*
+ SUBR PUSH
PUSH DAC ** REAL PUSH ROUTINE - PUSH AC TO STACK.
-*
+*
+ STX XTM SAVE X REGISTER
STA ATM2 SAVE A REGISTER
*
- LDA SPTR LOAD STACK POINTER
- SUB MAX TEST IF STACK FULL
- SNZ
- JST OFLO OVERFLOW OH! OH! OH!
+ LDX* PUSH LOAD INDEX REGISTER WITH DATA BASE
+ IRS PUSH
*
+ LDA FILL,1 LOAD FILL SIZE
+ CAS SSIZ,1 COMPARE STACK SIZE
+ NOP
+ JST OFLO OVERFLOW!
+*
LDA ATM2
- STA* SPTR NO OVERFLOW, PUT DATA ONTO STACK
- IRS SPTR INCREMENT STACK POINTER
+ STA* SPTR,1 NO OVERFLOW, PUT DATA ONTO STACK
+ IRS SPTR,1 INCREMENT STACK POINTER
+ IRS FILL,1 INCREMENT FILL SIZE
*
+ LDX XTM RESTORE X REGISTER
+ LDA ATM2
JMP* PUSH RETURN WITH A-REG UNALTERED.
*
*
*
POP DAC ** REAL POP ROUTINE - POP AC FROM STACK.
*
- LDA SPTR LOAD STACK POINTER
- SUB MIN TEST IF STACK EMPTY
+ STX XTM SAVE X REGISTER
+ LDX* POP LOAD INDEX REGISTER WITH DATA BASE
+ IRS POP
+*
+ LDA FILL,1 FILL SIZE
SNZ
- JST UFLO UNDERFLOW OH! OH! OH!
+ JST UFLO NOTHING INSIDE? SKIP!
*
- LDA SPTR LOAD STACK POINTER
+ LDA SPTR,1 LOAD STACK POINTER
SUB =1 DECREMENT IT TO LAST USED LOCATION
- STA SPTR SAVE IT BACK
+ STA SPTR,1 SAVE IT BACK
+ LDA FILL,1
+ SUB =1
+ STA FILL,1 DECREMENT FILL SIZE
*
- LDA* SPTR LOAD VALUE FROM THE STACK
+ LDA* SPTR,1 LOAD VALUE FROM THE STACK
+ LDX XTM RESTORE INDEX REGISTER
JMP* POP RETURN.
*
*
*
**** INITIALIZATION
*
-INIT DAC ** INITIALIZE STACK POINTER
- LDA CPTR LOAD INITIAL STACK POINTER
- STA SPTR SET STACK POINTER
+INIT DAC ** INITIALIZE STACK
+ STA ATM1
+ STX XTM
+*
+ LDX* INIT
+*
+ LDA VARS SIZE OF MANAGEMENT VARIABLES
+ ADD* INIT BASE ADDRESS
+ STA SPTR,1 SAVE TO STACK POINTER
+ IRS INIT
+*
+ LDA* INIT LOAD DATA POOL SIZE
+ SUB VARS VARIABLE SIZE
+ STA SSIZ,1 SAVE TO STACK DEPTH
+*
+ CRA
+ STA FILL,1
+*
+ LDA ATM1
+ LDX XTM
+ IRS INIT
JMP* INIT
*
*
*
**** ERROR HANDLING ROUTINES
*
+ SUBR OFLO
OFLO DAC ** STACK OVERFLOW ROUTINE
LDA OMSP LOAD OVERFLOW MESSAGE POINTER
JST TYPE TYPE IT OUT.
****************************************
*
*
+ SUBR UFLO
UFLO DAC ** STACK OVERFLOW ROUTINE
LDA UMSP LOAD OVERFLOW MESSAGE POINTER
JST TYPE TYPE IT OUT.
****************************************
*
*
+ SUBR TYPE
TYPE DAC **
SKS '104 TEST ASR READY
JMP *-1 WAIT TO BECOME READY
*
***** VARIABLES
*
-SBUF BSS SSIZ THE STACK BUFFER
-SPTR DAC SBUF THE STACK POINTER
*
PTR DEC 0 TRANSFER POINTER TO USER BUFFERS
CNT DEC 0 TRANSFER COUNTER
*
ATM1 DEC 0 A-REGISTER BACKUP
ATM2 DEC 0 A-REGISTER BACKUP
+XTM DEC 0 X-REGISTER BACKUP
*
*
***** CONSTANTS
-*
-CPTR DAC SBUF STACK POINTER CONSTANT
-MAX DAC SBUF+SSIZ FIRST ILLEGAL SPTR LOC BEFORE PUSH
-MIN DAC SBUF FIRST ILLEGAL SPTR LOC BEFORE POP
*
+VARS DEC 3 SIZE OF VARIABLES AT BEGINNING OF DATA
+*
+SSIZ EQU 0
+SPTR EQU 1
+FILL EQU 2
+*
OMSP DAC OMSG POINTER TO MESSAGE
UMSP DAC UMSG POINTER TO MESSAGE
OMSG OCT '006412 CR/LF CHARACTERS