* 06/17/76 -- 12:00
* MODULE NAME: PRNTSAV
* NUMBER: 42
* PURPOSE: SAVE EACH PRINTOUT PAGE IN COMMON DYNAMIC STORAGE
*          AND RETRIEVE IT FOR ACTUAL PRINTING
*
*
* ENTRY POINTS:
*
         DEF      S42TOP            INITIALIZATION FOR EACH PRINTOUT PAGE
         DEF      S42WRPRN          SAVE NEXT PRINTOUT LINE IN DYNAMIC STORAGE
         DEF      S42GETPG          GET COMMON DYNAMIC MEMORY PAGE
         DEF      S42NEWPG          INITIALIZE MEMORY PAGE
         DEF      S42RDPRN          READ NEXT PRINTOUT LINE IN DYNAMIC STORAGE
         DEF      S42FRPGS          FREE DYNAMIC MEMORY PAGES AFTER PRINTOUT
         DEF      C42COL,E42COL     SET MULTIPLE COLUMN MODE
*
*
         REF      S37OUTLN          PRINT ONE PRINTOUT LINE
         REF      S36M:GCP          ROUTINE TO GET COMMON MEMORY PAGES
         REF      S36M:FCP          ROUTINE TO FREE COMMON MEMORY PAGES
         REF      S27PRINT          PRINT ERROR MESSAGES
*
*
         REF      BOXFLG
         REF      FIGVFCFG          FIGURE VFC FLAG
         PAGE
*
*
         SYSTEM   TEXTDEF
*
*
         DEF      42P,42D           ADDR OF PROCEDURE AND DATA AREAS
42P      EQU      %
         DATA     X'42'             MODULE NUMBER
         DATA     X'061774'         DATE
         DATA     X'1200'           TIME
*
*
         TITLE    '** PRNTSAV(42) **'
*
* S42TOP -- INITIALIZATION FOR EACH NEW PRINTOUT PAGE.
*           GET NEW MEMORY PAGES IF REQUIRED.
*
S42TOP   EQU      %
         SAVRTN
*
         MTW,0    NPAGES            TEST FOR EXISTING MEMORY PAGES
         BGZ      INITLNS              YES, GO INITIALIZE THEM
         BAL,SRTN S42GETPG             NO, GET ONE MEMORY PAGE
         STW,BUF1 FSTADDR           SAVE ADDR OF FIRST PAGE
*
INITLNS  EQU      %                 INITIALIZE FOR NEW PRINTOUT PAGE
         LW,BUF1  FSTADDR           GET ADDR OF FIRST MEMORY PAGE
         BAL,SRTN S42NEWPG          INITIALIZE MEMORY PAGE
         LI,AC1   0                 SET NUMBER OF PRINTOUT LINES TO ZERO
         STW,AC1  NLINES
*
         RETURN                     RETURN TO CALLING PROGRAM
*
*
         PAGE
*
* S42WRPRN -- SAVE PRINTOUT LINE IN DYNAMIC MEMORY.
*             GET MORE DYNAMIC MEMORY IF REQUIRED.
*
* ENTRY PARAMETERS: BUF3 = BYTE ADDR OF PRINTOUT LINE
*                   AC1  = NUMBER OF CHARACTERS IN PRINTOUT LINE
*                   D1   = CURRENT FORMATTING MODE, WHERE:
*                                   D1 = 0  FORMATTED MODE
*                                      = 1  UNFORMATTED MODE
*                                      = 2  CENTERED MODE
*
S42WRPRN EQU      %
         SAVRTN
*
         AI,AC1   2                 ADD TWO BYTES FOR CONTROL CHARACTERS
         STW,AC1  LNSIZE            SAVE SIZE OF PRINTOUT LINE
         LI,X1    +0
         MTW,0    FIGVFCFG          IS FIGURE INSERT VFC REQUIRED
         STW,X1   FIGVFCFG          RESET FIGURE VFC FLAG
         BLEZ     WRPRN30           NO
         LI,D1    X'04'             SET FORMAT CODE FOR FIGURE VFC
WRPRN30  RES      0
         MTW,0    BOXFLG            SEE IF BOX-DRAWING SHOULD BE CANCELED.
         STB,X1   BOXFLG            CLEAR CANCELLATION FLAG .
         BGEZ     %+2               B IF NO CANCEL .
         AI,D1    X'40'             PUT FLAG IN 'FORMAT' BYTE .
         MTW,0    BOXFLG            SEE IF BOX CONTROL OVERSTRIKES SHOULD
         BEZ      %+2               BE HONORED.  BRANCH IF NOT .
         AI,D1    X'80'             PUT THAT INFO IN FORMAT BYTE .
         STW,D1   CFMCTRL           SAVE CURRENT FORMATTING MODE CONTROL
         STW,BUF3 LNADDR            SAVE BYTE ADDR OF PRINTOUT LINE
*
         CW,AC1   REMCHARS          TEST LINE SIZE AGAINST REMAINING SPACE
         BLE      WRLINE               OK, GO SAVE PRINTOUT LINE
         LI,X1    1                 GET INDEX FOR 2ND WORD ON PAGE
         LW,BUF1  *LSTADDR,X1       GET POINTER TO NEXT MEMORY PAGE
         BNEZ     SETNEWPG             SET, GO INITIALIZE PAGE
         BAL,SRTN S42GETPG             NO ROOM, GET NEW MEMORY PAGE
         CI,AC1   0                 TEST FOR NUMBER OF PAGES
         BGZ      SETLPTR              OK, GO SET LAST POINTER
         LI,BUF1  BA(NOPGMSG)+1        NO, GET ADDR OF ERROR MSG
         LB,AC1   NOPGMSG           GET SIZE OF MESSAGE
         BAL,SRTN S27PRINT          GO PRINT ERROR MESSAGE
         B        RTNWRPRN          RETURN TO CALLING PROGRAM
*
SETLPTR  EQU      %
         LI,X1    1                 SET INDEX TO 2ND WORD
         STW,BUF1 *LSTADDR,X1       SAVE NEW PAGE ADDR IN LAST PAGE POINTER
SETNEWPG EQU      %
         BAL,SRTN S42NEWPG          INITIALIZE NEW PAGE
*
WRLINE   EQU      %                 NOW SAVE PRINTOUT LINE IN DYNAMIC MEMORY
         LW,AC1   REMCHARS          GET NUMBER OF REMAINING CHARS IN MEMORY PAGE
         SW,AC1   LNSIZE            SUBTRACT SIZE OF PRINTOUT LINE
         STW,AC1  REMCHARS          SAVE NEW REMAINING SIZE
*
         LW,X1    LNADDR            GET BYTE ADDR OF PRINTOUT LINE
         LW,X2    NXTADDR           GET NEXT AVAILABLE ADDR IN MEMORY PAGE
         LW,AC1   LNSIZE            GET SIZE OF PRINTOUT LINE
         STB,AC1  0,X2              STORE SIZE AS FIRST CONTROL BYTE
         AI,X2    1                 INCR MEMORY PAGE POINTER
         LW,AC2   CFMCTRL           GET CURRENT FORMATTING MODE BYTE
         STB,AC2  0,X2              STORE CURRENT FORMATTING MODE AS 2ND BYTE
         AI,X2    1                 INCR MEMORY PAGE POINTER
*
         AI,AC1   -2                COUNT FOR MOVE IS TWO LESS
         STB,AC1  X2                SET UP COUNT FOR MBS INSTRUCTION
         MBS,X1   0                 MOVE PRINTOUT LINE TO MEMORY PAGE
         STW,X2   NXTADDR           STORE MEMORY PAGE POINTER IN NEXT ADDR
         MTW,1    *LSTADDR          INCR LINE COUNT FOR THIS MEMORY PAGE
         MTW,1    NLINES            INCR TOTAL LINE COUNT FOR THIS PRINTOUT PAGE
*
RTNWRPRN EQU      %
         RETURN                     RETURN TO CALLING PROGRAM
*
*
NOPGMSG  MESSAGE  '** NOT ENOUGH MEMORY -- PRINT LINE LOST'
         PAGE
*
* S42RDPRN -- READ SAVED PRINT LINES AND CALL PRINT
*             ROUTINE (S37OUTLN) TO PRINT IT.
*
S42RDPRN EQU      %
         SAVRTN
*
         LW,AC1   FSTADDR           GET WORD ADDR OF FIRST MEMORY PAGE
         STW,AC1  LSTADDR           SET CURRENT MEMORY PAGE ADDR
         AI,AC1   2                 INCR PAST MEMORY PAGE CONTROL WORDS
         SLS,AC1  2                 CONVERT TO BYTE ADDR
         STW,AC1  NXTADDR           SET NEXT PRINTOUT LINE ADDR
*
NXTPRNLN EQU      %                 GET NEXT PRINTOUT LINE
         MTW,-1   NLINES            TEST NUMBER OF LINES
         BLZ      RTNRDPRN             NONE LEFT, RETURN
         MTW,-1   *LSTADDR          TEST LINE ON THIS MEMORY PAGE
         BGEZ     GETLINE              SOME LEFT, GO GET LINE
*
         LI,X1    1                 SET INDEX TO NEXT MEMORY PAGE ADDR
         LW,AC1   *LSTADDR,X1       GET WORD ADDR OF NEXT PAGE
         STW,AC1  LSTADDR           SET NEW CURRENT PAGE ADDR
         MTW,-1   *LSTADDR          DECR LINE COUNT FOR THIS PAGE
         AI,AC1   2                 INCR ADDR PAST PAGE CONTROL WORDS
         SLS,AC1  2                 CONVERT TO BYTE ADDR
         STW,AC1  NXTADDR           SET POINTER TO NEXT OUTPUT LINE
*
GETLINE  EQU      %                 GET NEXT PRINTOUT LINE
         LW,BUF2  NXTADDR           GET BYTE ADDR OF NEXT PRINTOUT LINE
         LB,AC1   0,BUF2            GET NUMBER OF CHARACTERS
         AI,BUF2  1                 INCR POINTER TO CFM CONTROL BYTE
         LB,AC3   0,BUF2            GET CURRENT FORMATTING MODE CONTROL BYTE
         AI,BUF2  1                 INCR POINTER TO SKIP COUNT CHARACTER
         AWM,AC1  NXTADDR           INCR NEXT LINE ADDR
         AI,AC1   -2                DECR LINE SIZE FOR TWO CONTROL BYTES
         BAL,SRTN S37OUTLN          GO PRINT OUTPUT LINE
         B        NXTPRNLN
*
RTNRDPRN EQU      %
         RETURN                     RETURN TO CALLING PROGRAM
*
*
         PAGE
*
* S42FRPGS -- FREE COMMON DYNAMIC PAGES THAT HAVE BEEN
*             ACQUIRED TO SAVE PRINTOUT LINES
*
S42FRPGS EQU      %
         SAVRTN
*
         LW,AC1   NPAGES            GET NUMBER OF PAGES ACQUIRED
         BLEZ     RTNFRPGS          IF NONE, RETURN
         BAL,SRTN S36M:FCP          GO FREE COMMON DYNAMIC PAGES
         LI,AC1   0                 SET MEMORY PAGE COUNT TO ZERO
         STW,AC1  NPAGES
*
RTNFRPGS EQU      %
         RETURN
*
*
         PAGE
*
* S42GETPG -- GET NEW MEMORY PAGE
*
* EXIT PARAMETER: BUF1 = WORD ADDR OF NEW MEMORY PAGE
*
S42GETPG EQU      %
         SAVRTN
*
         LI,AC1   1                 SET PARAMETER TO GET ONE PAGE
         BAL,SRTN S36M:GCP          GO GET COMMON DYNAMIC MEMORY PAGE
         MTW,1    NPAGES            INCR PAGE COUNT
         LI,AC2   0                 INITIALIZE POINTER TO NEXT MEMORY PAGE
         STW,AC2  1,BUF1               (POINTER IS 2ND WORD IN PAGE)
*
         RETURN
*
*
         PAGE
*
* S42NEWPG -- INITIALIZE MEMORY PAGE FOR PRINTOUT LINES
*
* ENTRY PARAMETER: BUF1 = BYTE ADDR OF NEW MEMORY PAGE
*
S42NEWPG EQU      %
         SAVRTN
*
         STW,BUF1 LSTADDR           SAVE ADDR OF MOST RECENT PAGE
         LI,AC1   0                 INITIALIZE LINE COUNT FOR THIS
         STW,AC1  *LSTADDR             MEMORY PAGE
         AI,BUF1  2                 INCR ADDR PAST CONTROL WORDS
         SLS,BUF1 2                 CONVERT TO A BYTE ADDRESS
         STW,BUF1 NXTADDR           SET POINTER FOR NEXT PRINTOUT LINE
         LI,AC1   2040              INITIALIZE REMAINING CHARS FOR THIS PAGE
         STW,AC1  REMCHARS
*
         RETURN                     RETURN TO CALLING PROGRAM
*
*
         PAGE
*
*
* C42COL -- VALIDATE COLUMN COMMAND
*
C42COL   RES      0
         SAVRTN
         RETURN
         PAGE
*
*
* E42COL -- SET MULTIPLE COLUMN MODE
*
E42COL   RES      0
         SAVRTN
         RETURN
         PAGE
*
* LOCAL VARIABLES FOR PRINTOUT SAVE ROUTINE
*
*
42D      CSECT    0                 STARTING ADDR OF PRNTSAV LOCALS
*
NPAGES   DATA     0                 NUMBER OF MEMORY PAGES ACQUIRED
NLINES   DATA     0                 NUMBER OF LINES FOR THIS PRINTOUT
*
FSTADDR  RES      1                 WORD ADDR OF FIRST MEMORY PAGE USED
LSTADDR  RES      1                 WORD ADDR OF MOST RECENT MEMORY PAGE
*
NXTADDR  RES      1                 BYTE ADDR OF NEXT PRINTOUT LINE
REMCHARS RES      1                 REMAINING SIZE OF CURRENT MEMORY PAGE
*
LNADDR   RES      1                 BYTE ADDR OF PRINTOUT LINE
LNSIZE   RES      1                 NUMBER OF CHARS IN PRINTOUT LINE
CFMCTRL  RES      1                 FORMATTING MODE OF PRINTOUT LINE
*
*
         USECT    #PLOC
         END
