 
*  ED:/LDSAV   40 col         Apr / 26 / 93
*--------------------
*  All Characters
 
*  Purge,Tabrcd
*  Load, Save, Print, LdTemp
*  Open, Close, IO, IORec
 
*  LOAD/SAVE PAB data and defaults
*---------------------------------
*  Note word alignment
 
PABOC  BYTE 0                 Op code
PABST  BYTE 0                 Status
PABBAD DATA PABBUF            Buffer address
PABLRL BYTE 80                Logical recode length
PABCCT BYTE 80                Character count
PABRN  DATA 0                 Record number
PABSO  BYTE 0                 Screen offset
PABNL  BYTE 0                 Name length
SLRL   DATA >5050             Default logical record length
MLRL   DATA >8080             For DF/128
PBFNOM DATA PABBUF
THREE  EQU  $
WRITE  BYTE 3
MASK80 BYTE >80
BFC    BYTE >FC               Euro tab record
CTRLZ  BYTE >1A               MSDOS terminator
LINEFD BYTE >0A
PCCENT BYTE 0                 Prt control flag for entry
PCCEXT BYTE 0                 Exit
 
*  Recognized flag chars
 
CHTAB  EQU  $
C      BYTE 'C'               |
LL     BYTE 'L'               |  Order to
F      BYTE 'F'               |
M      BYTE 'M'               |  match flags
U      BYTE 'U'               |
P      BYTE 'P'               |
Q      BYTE 'Q'               |
A      BYTE 'A'               |
CHTBL  EQU  $-CHTAB
       EVEN
 
*  Keep order of these flags
 
STARTL DATA 0                 |
STOP   DATA 0                 |
LREAD  DATA 0                 |
PFLAG  DATA 0                 | For saving line counts
 
*  User set flags
 
UFTAB  EQU  $
CFLAG  DATA 0       Clean     |
LFLAG  DATA 0       Lines     |
FFLAG  DATA 0       D/F       | Retain block order
MSFLAG DATA 0       MSDos     |
UXFLAG DATA 0       Unix      |
PCFLAG DATA 0       PrtCodes  |
QCFLAG DATA 0       Excodes   |
APFLAG DATA 0       Append DV |
UFTBN  EQU  $
 
*  SD overlay block for temp use
 
SDLMEM EQU  $
 
 
*  Decode TAB record tentatively identified
*------------------------------------------
*  Alters bytes in copy only
 
TABRCD EQU  $
       MOV  R11,R15           Save return
       INCT R15               Presume not tabs
       MOV  R0,R6             Copy for use in indexed addressing
       S    R10,R6            Eu-Wr offset   (SETO)
       LI   R8,SQSBUF         Use this as temp
       MOV  R8,R14            Copy for later use
       MOV  R8,R9             Construct end pointer
       AI   R9,78             2 from end
       MOV  @DSPACE,*R9+      Clean up last byte
 
*  Transfer record
 
TBRC10 MOVB *R6+,*R8          Transfer byte
       SZCB @MASK80,*R8+      Remove high bit anyway
       C    R8,R9             Done
       JL   TBRC10
 
*  Search for record length
 
       LI   R6,LLL                Line length
TBRC20 CB   @SQSBUF-2(R6),@DSPACE  Blanks ?
       JNE  TBRC30                No - stop search at INDENT
 
       DECT R6                Previous word
       JGT  TBRC20            Line not all blanks here
 
*  Check record length
 
TBRC30 CLR  R8                Clear MSW of dividend
       MOV  R6,R9             Count as LSW
       DIV  @D22,R8           Is it a multiple of 22 ?
       MOV  R9,R9             Check remainder
       JNE  TABNOT            Yes - not legit
 
*  Check line details
 
TBRC40 DEC  R8                R8 has count
       JOC  TBRC60
 
       MOV  R14,R11           Copy starter
       AI   R11,20            Point to INDENT in this block
       LI   R12,6             Low limit
       LI   R13,85            High limit
       C    *R14,R12          LMRG low ?
       JL   TABNOT
       C    *R14+,R13         LMRG high ?
       JH   TABNOT
       C    *R14,R12          RMRG low ?
       JL   TABNOT
       C    *R14+,R13         RMRG high ?
       JH   TABNOT
       C    *R11,R12          INDENT low ?
       JL   TABNOT
       C    *R11,R13          INDENT high ?
       JH   TABNOT
 
       SWPB R12               Byte values now  6
       SWPB R13                                85
TBRC50 CB   *R14,R12          Tab entry byte
       JL   TABNOT            Too low
       CB   *R14+,R13
       JH   TABNOT            Too high
       C    R14,R11           16 worth
       JL   TBRC50            Not yet
 
       INCT R14               Over INDENT to next block
       JMP  TBRC40            Check if more
 
*  Assume a tab record now
 
TBRC60 ABS  @PFLAG            Has it been purged ?
TABINC JNE  TBRC70            Ignore tab record  (no purge)
 
*  Write in as tab data 1-3
 
       LI   R9,TABBUV         Write to format storage
       BLWP @SETVDW
       LI   R8,SQSBUF         Tab buffer pointer
       MOV  R6,R9             Copy length
       BL   @VMBW10           Do the transfer
       BL   @MOVE             Write to format table
       DATA TABBUV            VDP storage
       DATA FORMO,22          Work with first block
TBRC70 DECT R15               No step over - tab
TABNOT B    *R15              Direct exit - tabs taken care of
 
 
*----------------------------------------
*  LOAD entry from Command line processor
*----------------------------------------
 
LDTP01 EQU  $
       BL   @VMBWD            Save temp filename back
       DATA TFLBUV
       DATA CTEXT,LLL
       JMP  LOADT1
 
LOAD01 EQU  $
       BL   @SAVFIL           Save new file-name
LOADT1 SETO @PFLAG            No tab read unless CLR by purge
       BL   @PARSLD           CNT = line number, String -> name
       CLR  @LINENO           Merge line number.(from source)
       LI   R0,STARTL         Byte saver
       CLR  *R0+              Start line number (from destination)
       SETO *R0               Stop line number (from destination)
       DEC  *R0               @STOP
       DECT R0                Back to STARTL
 
 
*  Open file as Dis/Var 80
*--------------------------
 
       BL   @OPEN             Check file pathname before purge
       DATA >0014             Open it as DV
       JMP  LOADDF            Not found
       JMP  LOAD10            Successful - proceed
 
*  Try again as Dis/Fix 80
 
LOADDF BL   @OPEN
       DATA >0004             Open as DF
       JMP  ERROR
 
 
*  Distinguish Loading modes
*-------------------------------------
*  Assume NUM1-3,NUMCHK stored in order
 
LOAD10 LI   R11,NUM1          Byte saver
       MOV  *R11,*R11         Any line numbers entered?
       JLT  LDPURG            No, purge and use defaults.
 
       INC  *R11+             NUM1
       MOV  R11,R15           Save pointer at NUM2
       INC  *R11+             NUM2
       INC  *R11+             NUM3
       MOV  *R11,*R11         NUMCHK - how many numbers entered?
       JGT  LD1NUM            One - load and insert
*      JEQ  LD2NUM            Two - load piece of file.
       JLT  LD3NUM            Three - load piece and insert
 
 
*  Load part of external file to purged buffer
*---------------------------------------------
 
LD2NUM EQU  $
       DECT R15               Back off pointer to NUM1
 
*  Merge part of external file
*-----------------------------
 
LD3NUM MOV  *R15+,*R0+        NUM1or2 -> STARTL
       MOV  *R15,*R0          NUM2or3 -> STOPL - load all of file.
       C    @-2(R15),*R15     NUM1or2 <> NUM2or3
       JH   ERROR             Can't do that
 
       DECT R0                Back to STARTL
       CI   R15,NUM3          Was it 3 number entry ?
       JEQ  LD1NUM            No - do not purge buffer
 
LDPURG BL   @PURGE            Purge buffer
       JMP  LDEXTL            Go load it
 
 
*  Merge external file after line #
*----------------------------------
 
LD1NUM LI   R11,LINENO        Byte saver
       MOV  @NUM1,*R11        File merge
       MOV  @SAVER0,R15       Line number 0?
       JNE  LOAD05            No
 
       DEC  *R11              Yes - back up LINENO by 1
LOAD05 C    *R11,@EOF         Past end of file ?
       JLE  LDEXTL            No - OK
       MOV  @EOF,*R11         Replace by EoF then
 
 
*  LOAD FROM external source
*---------------------------
 
LDEXTL EQU  $
       S    *R0+,*R0          STARTL > STOPL known
       INC  *R0+              STOPL
       CLR  *R0               LREAD -> #lines read from file.
 
*  Load file records
 
LOAD20 BL   @VINIT            Clear VBuf
       BL   @IOREAD           Go read a record.
       JMP  ERROR             Load error, code in R9
       BL   @MOVE             Move buffer to CPU
       DATA PABBUF            Standard buffer
       DATA LINBUF,80
 
 
*  Check for MSB -> TAB record
 
       LI   R0,LINBUF         Point to CPU buffer
       MOV  R0,@BUFADR        Use LINBUF as source buffer
       CLR  R10               Flag for if USA tab
       CB   *R0,@MASK80       Check leading byte
       JEQ  CHKTAB            USA tab record possible
       SETO R10               Flag for if Euro tab
       CB   *R0,@BFC          Eurowriter TABs ?
       JNE  LOAD25            No
 
CHKTAB BL   @TABRCD           Check out possible TAB record
       JMP  LOAD20            Yes - it has been noted
 
LOAD25 LI   R11,LREAD         Point to counter
       INC  *R11              Count one used
       C    *R11,@STARTL      Time to insert line yet ?
       JLT  LOAD20            No, just forget it
 
       BLWP @INSTLN           Insert line
       DEC  @STOP             All read in ?
       JNE  LOAD30            Not yet
 
*  All read in now
 
LOADCL BL   @CLOSE            Close the file
       JMP  ERR02             Failure
       JMP  ERR02             Success - all the same
 
*  Check if INSTLN worked
 
LOAD30 MOV  R0,R9             Error flag
       JNE  ERROR             Problems
 
       MOV  *R11,R9           Current LREAD line read
       S    @STARTL,R9        Make actual read in
       BL   @LNDISP           Display on command line
       JMP  LOAD20            No problems
 
*  Buffer full error
 
ERROR  LI   R12,4             For number conversion - 2 digits
       CI   R9,5              End of file error ?
       JNE  ERR05             No - more serious
 
ERR02  CLR  @CRFLAG           Exit on EoF
       B    @CMDXIT
 
 
*  IO error message setup
*------------------------
 
ERR05  LI   R10,IORNM         Convert error code to ASCII
       BL   @NXDIG
       LI   R10,IOERP         Output IOER message.
       MOV  R10,@ERFLAG
       BL   @CLOSE
       NOP
       SETO @CHNGED           In case of failure
ERR10  B    @ERRM10
 
 
*---------------------------------
*  Print file with option decode
*---------------------------------
 
PF01   EQU  $
       SETO @PFLAG            Ban Tab record for PrintFile
       BL   @INIFLA           Clear flag block
       BL   @VMBWD            Save entry
       DATA DEVBUV            To devicename buffer in VDP
       DATA CTEXT,LLL         Don't be fussy - whole line
       LI   R8,CTEXT          Command line start -->> CMLCHK
PF10   BL   @CMLH10           Skip leading blanks
       JMP  ERR02             End of line & nothing to show
       JMP  PF20              Not a number - check as flag
       JMP  PF70              Numeric - parse as line #
 
*  Check for isolated command flag
 
PF20   CB   @1(R8),@DSPACE    Valid separator
       JEQ  PF30
       CB   @1(R8),@COMMA     The other one
       JNE  PF70
 
*  Check for command flags
 
PF30   CLR  R6                Initialize flag search index
PF40   CB   *R8,@CHTAB(R6)    Check single character
       JEQ  PF60              Match found
 
       INC  R6                Advance pointer to next table entry
       CI   R6,CHTBL          All done ?
       JL   PF40              Not yet
 
PF50   INC  R8                Push along command line
       JMP  PF10              Restart search and ignore unrecognized
 
PF60   A    R6,R6             Make word index
       SETO @UFTAB(R6)        Set flag
       JMP  PF50              Now look for next
 
 
*  Parse remainder of command line
 
PF70   EQU  $
       BL   @PARSLE           Parse rest of line.
       JMP  SAVE04            Join Save code
 
 
*------------------------------
*  SAVE file to external device
*------------------------------
 
SAVE01 EQU  $
       BL   @SAVFIL           Note filename
       CLR  @PFLAG            Allow tab record for Save
       BL   @INIFLA
       BL   @PARSLD           String -> filename, COLSTA = first line
 
*  Check line #s
 
SAVE04 CLR  R9                Show line error as 00
       MOV  @NUM1,R8          Check user entry of first line
       JLT  SAV10             Still initialized - no #s
 
       ABS  @NUMCHK           Either 2 or no numbers entered
       JNE  ERROR             Error - 1 or 3 #s
       C    R8,@NUM2          First line > last line?
       JH   ERROR             No can do
       JMP  SAVE20            Continue then
 
*  Set line #s when none specified
 
SAV10  CLR  @NUM1             Set up for whole file
       MOV  @EOF,@NUM2        To the bitter end
       CLR  @CHNGED           For whole file save
 
*  Open the file for write
*-------------------------
 
SAVE20 EQU  $
       MOV  @SLRL,@PABLRL     Initialize at 80/80
       ABS  @MSFLAG           MSdos DF/128 output ?
       JNE  OPB128
       ABS  @UXFLAG           Unix compatible ?
       JNE  OPA128
       ABS  @FFLAG            Fixed 80 flag set?
       JNE  OPENDF            Yes - use record length aet
       ABS  @APFLAG           Append mode ?
       JEQ  OPWRIT            No
 
*  Open DV/80 in Append mode
 
       BL   @OPEN10           Open as DV/80 Append
       DATA >0016
       JMP  ERROR
       JMP  SAVE24
 
*  Open DV/80 file for write
 
OPWRIT BL   @OPEN10           Open file for output, variable 80.
       DATA >0012             Open DV write
JLSER2 JMP  ERROR             Error return.
       JMP  SAVE24
 
*  DF/ 80 or 128 file open for write
 
OPA128 SETO @MSFLAG           Set as generic DF/128 flag anyway
OPB128 CLR  @LFLAG            Cancel Line # mode
       MOV  @MLRL,@PABLRL     Set for 128/128
OPENDF BL   @OPEN10           Open as DF/80 or DF/128
       DATA >0002             Open/write
       JMP  ERROR             Error in DSR
 
 
*  Fetch and write out the records for DV & DF/80
 
SAVE24 MOV  @NUM1,@LINENO     Start line # either way
       ABS  @MSFLAG           Special DF/128 ?
       JNE  MSDREC            Yes
 
       ABS  @PCFLAG           Printer control codes on entry ?
       JEQ  SAVE30            No
       MOVB @PCCENT,R14       Any entered ?
       JEQ  SAVE30
 
       BL   @MOVE             Fetch codes from VDP storage
       DATA PCEBUV
       DATA LINBUF,24
       JMP  SAVE35            Go write it & then continue
 
*  Normal D/80 records to device
 
SAVE30 BL   @TRECRD           Treat 80 col line to order
       JMP  SAVE40            End of S/P or EoF
SAVE35 BL   @WRECD            Write record out to device
       JMP  JLSER2            Error exit
       JMP  SAVE30            Loop on it till done
 
SAVE40 ABS  @QCFLAG           Printer codes on exit flagged ?
       JEQ  SAVE97            No
       MOVB @PCCEXT,R14
       JEQ  SAVE97
 
       BL   @MOVE             Prepare record
       DATA PCXBUV            From VDP storage
       DATA LINBUF,24
       BL   @WRECD            Write it out
       JMP  JLSER2            Device error
 
*  Add a tab record at the end
 
SAVE97 ABS  @PFLAG            Check print flag
NOTABS JNE  SAVE99            Changed to JMP for Pr/Ed
 
       BL   @CONWTB           Construct and write out TAB record
       JMP  JLSER2
SAVE99 BL   @CLOSE            Close file now
       NOP                    IGNORE any close error
EXITLS B    @CMDXIT           Go quit command mode
 
 
*--------------------------------------
*  MSDOS/UNIX text file write as DF/128
*--------------------------------------
*  MSFLAG acts as generic DF/128 flag
*  Extra chrs spill into SQSBUF
 
*  Write to output device
 
MSDWRI MOVB @WRITE,@PABOC     Set for write
       BL   @IOREC            Go do it
       JMP  JLSER2            Error return
       MOV  R0,R0             Set by TRECD for EoF
       JNE  SAVE99            All done
MSDREC LI   R7,PABBUF         Enter or restart output pointer
MSDW10 MOV  R7,R9             Copy where needed
CTRLD  BLWP @SETVDW           Reset for writing record
 
*  Output/Input loop checks
 
MSDC10 CI   R7,PABBUF+>80     A DF/128 complete ?
       JHE  MSDWRI            Yes - write out record
MSDC20 C    R13,R15           At end of DV/80 record ?
       JHE  MSDRED            Read a fresh record
 
       MOVB *R13+,@VDPWD      Write to VDP buffer
       INC  R7                Update output pointer
       JMP  MSDC10            Loop on it
 
*  New record from text buffer
 
MSDRED SETO R0                GETLN clears if not EoF
       BL   @TRECRD           Read new record from Text buffer
       JMP  MSDR30            End of range or EoF
       LI   R11,>0D0A         Load with <cr><lf>
       ABS  @UXFLAG           Unix mode ?
       JEQ  MSDR10            No
 
*  Unix line separator
 
       CB   @-1(R15),R11      Last byte a <cr> ?
       JNE  MSDR20            No - write <lf> as following byte
       DEC  R15               Yes - back up
       JMP  MSDR20            Write <lf> over it
 
*  MS-Dos line separator
 
MSDR10 CB   @-1(R15),R11      Last char a <cr> ?
       JEQ  MSDR20            Yes - do not double up
       MOVB R11,*R15+         Write in <cr>
MSDR20 SWPB R11               Bring <lf> to fore
       MOVB R11,*R15+         Write over or after previous
       JMP  MSDR50            Need to reset VDP write pointer
 
*  File terminator
 
MSDR30 ABS  @UXFLAG           Unix
       JEQ  MSDR40            No
       MOVB @CTRLD,*R15+      Write Unix style terminator
       JMP  MSDR50
MSDR40 MOVB @CTRLZ,*R15+      MSDOS text file terminator
MSDR50 LI   R13,LINBUF        Initialize read buffer pointer
       JMP  MSDW10
 
 
 
*---------------------------------
*  Write record to external device
*---------------------------------------------
*  Assumes data at LINBUF & length byte in R14
 
WRECD  EQU  $
       MOV  R11,R15           Save return
WRECE  MOVB R14,@PABCCT       Record length byte
       BL   @C2V              Transfer to VDP
       MOVB @WRITE,@PABOC     Set to write record in opcode
       MOV  R15,R14           Return address for IO
       JMP  IORECW            Write it
 
 
*  Subroutine to do IO
*---------------------
 
IOREAD EQU  $
       MOVB @TWO,@PABOC      Set PAB opcode for read
 
IOREC  EQU  $
       MOV  R11,R14           Write in return
IORECW LI   R6,DSRDIR         DSR entry for opened file
       JMP  IORC10            Go do it
 
CLOSE  MOVB @ONE,@PABOC       Set opcode for Close
 
*  Common IO routine
 
IO     EQU  $
       MOV  R11,R14           Set up return
IO05   LI   R6,TWDSLK         Full DSRLNK
       LI   R8,VDPPAB+9       Set up for DSR link.
       MOV  R8,@SCNAME        Already known for re-entry
IORC10 BL   @VMBWD            PAB to VDP
       DATA VDPPAB            Write the PAB for I/O
       DATA PABOC,10          Length byte for PAB data
       BLWP *R6               T-W DSr LinK or DSR DIRect
       DATA 8
       JNE  IO10              Error ? - no
 
*  Not found error path
 
       LI   R9,>0F            BADNAM
       JMP  IO20              Exit
 
*  Check PAB byte for error
 
IO10   BL   @MOVE             VMBRD as BL
       DATA VDPPAB            Read back the PAB for I/O
       DATA PABOC,10
       MOVB @PABST,R9         Check error code.
       SRL  R9,13
       JNE  IO20              Must have error.
 
       INCT R14               No error, return
IO20   B    *R14
 
 
*  Open file, using String pointers, etc.
*----------------------------------------
 
OPEN   EQU  $
       MOV  @SLRL,@PABLRL     Restore CCT and LRL
OPEN10 MOV  *R11+,@PABOC      Get opcode, and status
       MOV  R11,R14           Save return
       MOV  @PBFNOM,@PABBAD   Set nominal DSR buffer
       MOV  @STRING,R8        String -> file name pointer
       DEC  R8                Point to length byte
       MOVB @STRL1,*R8        Overwrite length
       MOVB *R8,@PABNL        Set up length in CPU PAB
       BL   @VSTRV            Write to VDP
       DATA VDPPAB+10         Where name goes in VDP PAB
       JMP  IO05              Let IO do the work.
 
 
 
*--------------------------------------------------------
 
