*** empty log message ***
[h316.git] / lib / hachti / src / stack.asm
index 84c72b7ac0f0bb56a99bc0a9696f1dd49f653ac8..b54074f0a3ee9272b5e40ee3b54347487aaffc5a 100644 (file)
 *       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
@@ -86,12 +145,14 @@ PUSM       DAC     **      ENTRY POINT TO PUSH ROUTINE
 * 
 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
 * 
 *
 ********************************************************************************
@@ -102,6 +163,10 @@ PULP       LDA*    PTR     GET DATA
 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
@@ -114,6 +179,8 @@ POPM        DAC     **      ENTRY POINT TO PUSH ROUTINE
        STA     CNT     STORE TO COUNTER
 * 
 POLP   JST     POP     POP DATA FROM THE STACK
+DPTR   DAC     **
+* 
        STA*    PTR     STORE IT.
        LDA     PTR
        SUB     =1      DECREMENT
@@ -121,8 +188,8 @@ POLP        JST     POP     POP DATA FROM THE STACK
        IRS     CNT     INCREMENT BYTE COUNTER
        JMP     POLP    DO IT AGAIN!
 * 
-       LDA     ATM1
-       JMP*    POPM    
+       LDA     ATM1    RESTORE A-REG
+       JMP*    POPM    RETURN
 * 
 *
 ********************************************************************************
@@ -130,19 +197,27 @@ POLP      JST     POP     POP DATA FROM THE STACK
 * 
 **** 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.
 * 
 * 
@@ -153,16 +228,23 @@ PUSH      DAC     **      REAL PUSH ROUTINE - PUSH AC TO STACK.
 * 
 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.
 * 
 * 
@@ -171,9 +253,27 @@ POP        DAC     **      REAL POP ROUTINE - POP AC FROM STACK.
 * 
 **** 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
 * 
 *
@@ -182,6 +282,7 @@ INIT        DAC     **      INITIALIZE STACK POINTER
 *  
 **** ERROR HANDLING ROUTINES
 * 
+       SUBR    OFLO
 OFLO   DAC     **      STACK OVERFLOW ROUTINE
        LDA     OMSP    LOAD OVERFLOW MESSAGE POINTER
        JST     TYPE    TYPE IT OUT.
@@ -193,6 +294,7 @@ OFLO        DAC     **      STACK OVERFLOW ROUTINE
 ****************************************
 * 
 * 
+       SUBR    UFLO
 UFLO   DAC     **      STACK OVERFLOW ROUTINE
        LDA     UMSP    LOAD OVERFLOW MESSAGE POINTER
        JST     TYPE    TYPE IT OUT.
@@ -204,6 +306,7 @@ UFLO        DAC     **      STACK OVERFLOW ROUTINE
 ****************************************
 * 
 * 
+       SUBR    TYPE
 TYPE   DAC     **
        SKS     '104    TEST ASR READY
        JMP     *-1     WAIT TO BECOME READY
@@ -231,22 +334,23 @@ TLOP      LDA*    PTR     TYPE LOOP
 * 
 ***** 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