X-Git-Url: http://gitweb.hachti.de/?a=blobdiff_plain;ds=inline;f=sw%2Fkermit%2Fhachti%2FK12ENB.PA;fp=sw%2Fkermit%2Fhachti%2FK12ENB.PA;h=7a1fb57cf7ba795b52d33c0347f2ea071941d55c;hb=81e70d488b71bf995c459ca3a02c025993460ffa;hp=0000000000000000000000000000000000000000;hpb=07ec0278333ed187ac242dedcff13c56cf1b0b91;p=pdp8.git
diff --git a/sw/kermit/hachti/K12ENB.PA b/sw/kermit/hachti/K12ENB.PA
new file mode 100644
index 0000000..7a1fb57
--- /dev/null
+++ b/sw/kermit/hachti/K12ENB.PA
@@ -0,0 +1,708 @@
+/ OS/8 BOO ENCODING PROGRAM
+
+/ LAST EDIT: 01-OCT-1991 15:00:00 CJL
+
+/ MAY BE ASSEMBLED WITH '/F' SWITCH SET.
+
+/ PROGRAM TO ENCODE ANY TYPE OF OS/8 FILE INTO "PRINTABLE" ASCII (".BOO")
+/ FORMAT. THIS IS A COMMON DISTRIBUTION FORMAT FOR MANY COLUMBIA KERMIT FILES
+/ AND IS AN ALTERNATIVE TO ENCODE FORMAT FOR PDP-8 AND DECMATE USERS.
+
+/ DISTRIBUTED BY CUCCA AS "K12ENB.PAL" AS PART OF THE CUCCA KERMIT-12 PACKAGE.
+
+/ WRITTEN BY:
+
+/ CHARLES LASNER (CJL)
+/ CLA SYSTEMS
+/ 72-55 METROPOLITAN AVENUE
+/ MIDDLE VILLAGE, NEW YORK 11379-2107
+/ (718) 894-6499
+
+/ USAGE:
+
+/ .RUN DEV ENBOO INVOKE PROGRAM
+/ *OUTPUT)
+/ *OUTPUT)
+/ . PROGRAM EXITS NORMALLY
+
+/ INPUT FILE ASSUMES .SV EXTENSION; THERE IS NO ASSUMED OUTPUT EXTENSION.
+
+/ PROGRAM EXIT IS THE NORMAL OS/8 METHOD OF EITHER PRESSING <^C> ON THE CONSOLE
+/ KEYBOARD DURING THE COMMAND, OR ENDING THE COMMAND INPUT LINE WITH AN
+/ CHARACTER.
+
+/ THIS PROGRAM SUPPORTS THE .BOO FORMAT FOR FILE ENCODING WHICH IS POPULAR IN
+/ OTHER SYSTEMS. THIS VERSION IMPLEMENTS THE FILE LENGTH PROTECTION SCHEME
+/ DEVELOPED BY CHARLES LASNER TO ENSURE PRECISE FILE LENGTH.
+
+/ MANY .BOO PROGRAMS HAVE PROBLEMS MAINTAINING PRECISE FILE LENGTH. THE ACTUAL
+/ LENGTH MAY BE IMPRECISELY STATED BY ONE OR TWO BYTES DUE TO AN INHERENT
+/ WEAKNESS IN THE ORIGINAL .BOO ENCODING FORMAT DESIGN. THIS IMPLEMENTATION
+/ APPENDS CORRECTION BYTES AS NECESSARY TO THE BASIC .BOO FILE TO ENSURE PROPER
+/ DECODING BY PROGRAMS COMPATIBLE WITH THIS EXTENSION.
+
+/ FILES CREATED BY THIS PROGRAM MAY BE USED WITH EARLIER .BOO DECODERS; THE
+/ RESULTANT FILES MAY INACCURATELY RECREATE THE ORIGINAL FILES BY AS MUCH AS TWO
+/ EXTRANEOUS TRAILING BYTES. THERE WILL BE NO PROBLEMS (BEYOND THE LENGTH
+/ ANOMALY) AS LONG AS THE DECODERS IMPLEMENT ZERO-LENGTH COMPRESSION FIELDS AS
+/ NO OPERATION. IT IS POSSIBLE THAT CERTAIN DECODERS COULD ERRONEOUSLY APPEND
+/ MASSIVE QUANTITIES OF ZEROES ONTO THE END OF THE DECODED FILES, BUT THIS
+/ ACTION WOULD CERTAINLY BE CAUSED BY DEFECTIVE PROGRAM CODE WITHIN THE DECODER.
+/ (ALTHOUGH NOT LIKELY SEEN BEFORE ENCOUNTERING FILES WITH LENGTH CORRECTION
+/ BYTES, THIS WOULD BE A LATENT BUG IN THESE DECODING PROGRAMS. UPDATED
+/ VERSIONS SHOULD BE SOUGHT IF THIS PROBLEM SURFACES.)
+/ ERROR MESSAGES.
+
+/ ERROR MESSAGES ARE ONE OF TWO VARIETIES: COMMAND DECODER MESSAGES AND USER
+/ (PROGRAM-SIGNALLED) MESSAGES.
+
+/ COMMAND DECODER MESSAGES ARE NON-FATAL AND MERELY REQUIRE RETYPING THE
+/ COMMAND. ATTEMPTING TO USE MORE THAN ONE OUTPUT FILE WILL YIELD THE COMMAND
+/ DECODER MESSAGE "TOO MANY FILES" AND CAUSE A REPEAT OF THE COMMAND DECODER
+/ PROMPT REQUIRING USER INPUT. THE USER IS DIRECTED TO OTHER DOCUMENTATION OF
+/ THE "SPECIAL" MODE OF THE COMMAND DECODER, AS THAT IS THE ONLY MODE USED BY
+/ THIS UTILITY PROGRAM.
+
+/ ANY USER MESSAGE PRINTED IS A FATAL ERROR MESSAGE CAUSED BY A PROBLEM BEYOND
+/ THE SCOPE OF THE COMMAND DECODER. ALL USER MESSAGES ARE THE STANDARD OS/8
+/ "USER" ERROR MESSAGES OF THE FORM: "USER ERROR X AT AAAAA", WHERE X IS THE
+/ ERROR NUMBER AND AAAAA IS THE PROGRAM ADDRESS WHERE THE ERROR WAS DETECTED.
+/ THE FOLLOWING USER ERRORS ARE DEFINED:
+
+/ ERROR NUMBER PROBABLE CAUSE
+
+/ 0 NO OUTPUT FILE.
+
+/ 1 INPUT FILE ERROR (CAN'T FIND INPUT FILE) OR NO INPUT
+/ FILE SPECIFIED OR TOO MANY INPUT FILES SPECIFIED.
+/ 2 ILLEGAL OUTPUT FILE NAME (WILD CARDS NOT ALLOWED).
+
+/ 3 NO OUTPUT FILE NAME (DEVICE ONLY IS NOT ALLOWED).
+
+/ 4 ERROR WHILE FETCHING FILE HANDLER.
+
+/ 5 ERROR WHILE ATTEMPTING TO ENTER OUTPUT FILE.
+
+/ 6 OUTPUT FILE LARGER THAN AVAILABLE FILE SPACE.
+
+/ 7 ERROR WHILE CLOSING THE OUTPUT FILE.
+
+/ 8 I/O ERROR WHILE ENCODING FILE DATA.
+
+/ 9 OUTPUT ERROR WHILE ENCODING FILE DATA.
+
+/ ASSEMBLY INSTRUCTIONS.
+
+/ IT IS ASSUMED THE SOURCE FILE K12ENB.PAL HAS BEEN MOVED AND RENAMED TO
+/ DSK:ENBOO.PA.
+
+/ .PAL ENBOO TERMINATED THE LINE
+ DCA EXITZAP /ELSE CAUSE EXIT LATER
+ TAD I (OUTFILE) /GET OUTPUT FILE DEVICE WORD
+ SNA /SKIP IF FIRST OUTPUT FILE PRESENT
+ JMP TSTMORE /JUMP IF NOT THERE
+ AND [17] /JUST DEVICE BITS
+ DCA ODNUMBER /SAVE OUTPUT DEVICE NUMBER
+ TAD I (INFILE) /GET FIRST INPUT FILE DEVICE WORD
+ SNA /SKIP IF PRESENT
+ JMP INERR /JUMP IF NOT
+ AND [17] /JUST DEVICE BITS
+ DCA IDNUMBER /SAVE INPUT DEVICE NUMBER
+ TAD I (INFILE+5) /GET SECOND INPUT FILE DEVICE WORD
+ SZA CLA /SKIP IF ONLY ONE INPUT FILE
+ JMP INERR /ELSE COMPLAIN
+ JMS I (MIFNAME) /MOVE INPUT FILENAME WITH ADJUSTED EXTENSION
+ TAD I [OUTFILE+1] /GET FIRST OUTPUT FILENAME WORD
+ SNA CLA /SKIP IF NAME PRESENT
+ JMP NONAME /JUMP IF DEVICE ONLY
+ JMS I (MOFNAME) /MOVE OUTPUT FILENAME
+ CDF PRGFLD /BACK TO OUR FIELD
+ CIF USRFLD /GOTO USR FIELD
+ JMS I [USR] /CALL USR ROUTINE
+ RESET /RESET SYSTEM TABLES
+ TAD (OHNDBUFFER+1) /GET BUFFER POINTER+TWO-PAGE BIT
+ DCA OHPTR /STORE IN-LINE
+ TAD ODNUMBER /GET OUTPUT DEVICE NUMBER
+ CIF USRFLD /GOTO USR FIELD
+ JMS I [USR] /CALL USR ROUTINE
+ FETCH /FETCH HANDLER
+OHPTR, .-. /WILL BE BUFFER POINTER+TWO-PAGE BIT
+ JMP FERROR /FETCH ERROR
+ TAD OHPTR /GET RETURNED ADDRESS
+ DCA OUTPUT /STORE AS OUTPUT HANDLER ADDRESS
+ TAD (IHNDBUFFER+1) /GET INPUT BUFFER POINTER+TWO-PAGE BIT
+ DCA IHPTR /STORE IN-LINE
+ TAD IDNUMBER /GET INPUT DEVICE NUMBER
+ CIF USRFLD /GOTO USR FIELD
+ JMS I [USR] /CALL USR ROUTINE
+ FETCH /FETCH HANDLER
+IHPTR, .-. /WILL BE BUFFER POINTER+TWO-PAGE BIT
+ JMP FERROR /FETCH ERROR
+ TAD IHPTR /GET RETURNED ADDRESS
+ DCA INPUT /STORE AS INPUT HANDLER ADDRESS
+ JMS I (GEIFILE) /GO LOOKUP INPUT FILE
+ TAD (FNAME) /POINT TO
+ DCA ENTAR1 /STORED FILENAME
+ DCA ENTAR2 /CLEAR SECOND ARGUMENT
+ TAD ODNUMBER /GET OUTPUT DEVICE NUMBER
+ CIF USRFLD /GOTO USR FIELD
+ JMS I [USR] /CALL USR ROUTINE
+ ENTER /ENTER TENTATIVE FILENAME
+ENTAR1, .-. /WILL POINT TO FILENAME
+ENTAR2, .-. /WILL BE ZERO
+ JMP ENTERR /ENTER ERROR
+ TAD ENTAR1 /GET RETURNED FIRST RECORD
+ DCA OUTRECORD /STORE IT
+ TAD ENTAR2 /GET RETURNED EMPTY LENGTH
+ IAC /ADD 2-1 FOR OS/278 CRAZINESS
+ DCA DANGCNT /STORE AS DANGER COUNT
+ JMS I (ENCODIT) /GO DO THE ACTUAL ENCODING
+ JMP PROCERR /ERROR WHILE ENCODING
+ TAD ODNUMBER /GET OUTPUT DEVICE NUMBER
+ CIF USRFLD /GOTO USR FIELD
+ JMS I [USR] /CALL USR ROUTINE
+ CLOSE /CLOSE OUTPUT FILE
+ FNAME /POINTER TO FILENAME
+OUTCNT, .-. /WILL BE ACTUAL COUNT
+ JMP CLSERR /CLOSE ERROR
+EXITZAP,JMP START /**** TERMINATION **** 0000
+ JMP I (SBOOT) /EXIT TO MONITOR
+/ OUTPUT FILE ERROR WHILE PROCESSING.
+
+ENCERRO,TAD [3] /SET INCREMENT
+ SKP /DON'T USE NEXT
+
+/ ERROR WHILE PROCESSING INPUT FILE.
+
+PROCERR,NL0002 /SET INCREMENT
+ SKP /DON'T USE NEXT
+
+/ ERROR WHILE CLOSING THE OUTPUT FILE.
+
+CLSERR, NL0001 /SET INCREMENT
+ SKP /DON'T CLEAR IT
+
+/ OUTPUT FILE TOO LARGE ERROR.
+
+SIZERR, CLA /CLEAN UP
+ TAD [3] /SET INCREMENT
+ SKP /DON'T USE NEXT
+
+/ ENTER ERROR.
+
+ENTERR, NL0002 /SET INCREMENT
+ SKP /DON'T USE NEXT
+
+/ HANDLER FETCH ERROR.
+
+FERROR, NL0001 /SET INCREMENT
+
+/ NO OUTPUT FILENAME ERROR.
+
+NONAME, IAC /SET INCREMENT
+
+/ ILLEGAL OUTPUT FILE NAME ERROR.
+
+BADNAME,IAC /SET INCREMENT
+
+/ INPUT FILESPEC ERROR.
+
+INERR, IAC /SET INCREMENT
+
+/ OUTPUT FILESPEC ERROR.
+
+OUTERR, DCA ERRNUMBER /STORE ERROR NUMBER
+ CDF PRGFLD /ENSURE OUR FIELD
+ CIF USRFLD /GOTO USR FIELD
+ JMS I [USR] /CALL USR ROUTINE
+ USERROR /USER ERROR
+ERRNUMB,.-. /WILL BE PASSED ERROR NUMBER
+/ COMES HERE TO TEST FOR NULL LINE.
+
+TSTMORE,TAD I (INFILE) /GET FIRST INPUT FILE DEVICE WORD
+ SZA CLA /SKIP NO INPUT OR OUTPUT GIVEN
+ JMP OUTERR /ELSE COMPLAIN
+ CDF PRGFLD /BACK TO OUR FIELD
+ JMP EXITZAP /MIGHT BE LAST TIME, SO GO THERE FIRST
+
+ PAGE
+ENCODIT,.-. /ENCODING ROUTINE
+ NL7777 /SETUP INITIALIZE VALUE
+ JMS I [DOBYTE] /INITIALIZE OUTPUT ROUTINE
+ JMS I (PIFNAME) /OUTPUT THE INPUT FILENAME
+ JMS I (PCRLF) /OUTPUT / AND CLEAR COLUMN COUNTER
+ DCA CMPCNT /CLEAR COMPRESSION
+ TAD [CHARS] /SETUP THE
+ DCA CHARPTR /OUTPUT POINTER
+ NL7777 /MAKE IT INITIALIZE
+LOOP, JMS I (GETBYTE) /GET LATEST BYTE
+ JMP ENDCHECK /AREN'T ANY MORE, FINISH THE FILE
+
+/ TEST IF ALREADY WITHIN A DEVELOPING COMPRESSION FIELD.
+
+ TAD CMPCNT /GET COMPRESSION COUNT
+ SNA CLA /SKIP IF COMPRESSION IN PROGRESS
+ JMP NOCOMP /JUMP IF NOT
+
+/ CHECK IF LATEST INPUT BYTE IS ZERO.
+
+ TAD CHAR /GET LATEST
+ SZA CLA /SKIP IF SO
+ JMP ENDCOMPRESS /JUMP IF NOT
+SETCOMP,ISZ CMPCNT /BUMP COMPRESSION COUNT
+ TAD CMPCNT /GET LATEST COUNT
+ TAD (-116) /COMPARE TO MAXIMUM ALLOWED
+ SNA CLA /SKIP IF NOT
+ JMS I (COMPRESSOUT) /OUTPUT MAXIMUM COMPRESSION AND CANCEL COMPRESSION
+ JMP LOOP /GO GET ANOTHER ONE
+
+/ IF LATEST IS NON-ZERO, THEN COMPLETE EXISTING COMPRESSION FIELD.
+
+ENDCOMP,NL7777 /-1
+ TAD CMPCNT /COMPARE TO COMPRESSION COUNT
+ SZA CLA /SKIP IF TRIVIAL CASE
+ JMP OUTCOMPRESS /JUMP IF NOT
+
+/ CANCEL TRIVIAL CASE OF ONE BYTE COMPRESSION.
+
+ DCA CMPCNT /CLEAR COMPRESSION MODE
+ DCA CHARS /FIRST BYTE WAS ZERO
+ TAD (CHARS+1) /SETUP OUTPUT POINTER TO
+ DCA CHARPTR /STORE INTO SECOND BYTE
+ JMP BYTEINSERT /CONTINUE THERE
+/ OUTPUT LATEST COMPRESSION AND PROCESS NEW NON-ZERO BYTE.
+
+OUTCOMP,JMS I (COMPRESSOUT) /OUTPUT COMPRESSION FIELD AND CANCEL COMPRESSION
+
+/ COMES HERE IF NOT WITHIN A COMPRESSION REGION.
+
+NOCOMP, TAD CHARPTR /GET POINTER
+ TAD (-CHARS) /CHECK IF AT BEGINNING
+ SZA CLA /SKIP IF BUFFER EMPTY
+ JMP BYTEINSERT /JUMP IF NOT
+
+/ IF AT BEGINNING OF THREE BYTES, TEST IF LATEST STARTS A COMPRESSION FIELD.
+
+ TAD CHAR /GET LATEST BYTE
+ SNA CLA /SKIP IF NOT ZERO
+ JMP SETCOMPRESSION /JUMP IF SO
+BYTEINS,TAD CHAR /GET LATEST BYTE
+ DCA I CHARPTR /STORE IT
+ ISZ CHARPTR /BUMP TO NEXT
+ TAD CHARPTR /GET THE UPDATED POINTER
+ TAD (-CHARS-2-1) /COMPARE TO UPPER LIMIT
+ SNA CLA /SKIP IF LESS THAN THREE PRESENT
+ JMS I (OUT3) /ELSE OUTPUT THE THREE BYTES AND RESET THE BUFFER
+ JMP LOOP /GO GET ANOTHER ONE
+
+/ COMES HERE AT END OF INPUT.
+
+ENDCHEC,NL7776 /-2
+ TAD CMPCNT /COMPARE TO COMPRESSION COUNT
+ SMA /SKIP IF AT TRIVIAL CASE OR NO COMPRESSION CURRENTLY
+ JMP ENDFCOMPRESS /FINISH WITH A COMPRESSION FIELD
+ IAC /CHECK FURTHER
+ SZA CLA /SKIP IF TRIVIAL COMPRESSION AT END
+ JMP NORMEND /JUMP IF NOT WITHIN COMPRESSION
+
+/ THE TRIVIAL CASE CONVERTS TO AN INCOMPLETE OUTPUT, COMPLETE WITH CORRECTION
+/ BYTES TO INDICATE THE SHORT FIELD.
+
+ DCA CHARS /MOVE ZERO BYTE TO FIRST POSITION
+NORM1, DCA CHARS+1 /CLEAR SECOND POSITION
+ DCA CHARS+2 /CLEAR THIRD POSITION
+ JMS I (OUT3) /OUTPUT THE THREE BYTES
+ DCA CMPCNT /CLEAR COMPRESSION COUNT
+ JMS I (COMPRESSOUT) /OUTPUT NULL COMPRESSION FIELD TO CANCEL THIRD BYTE
+ /NEXT WILL CANCEL SECOND BYTE
+
+/ COMES HERE IF FILE ENDS ON A COMPRESSION FIELD.
+
+ENDFCOM,JMS I (COMPRESSOUT) /OUTPUT COMPRESSION FIELD AND CANCEL COMPRESSION
+ JMP CLOSFILE /FINISH IT THERE
+/ COMES HERE IF FILE ENDS IN SOME FORM OF DATA FIELD.
+
+NORMEND,TAD CHARPTR /GET CHARACTER POINTER
+ TAD (-CHARS-2) /COMPARE TO TWO PRESENT VALUE
+ SNA /SKIP IF NOT THE CASE
+ JMP NORM2 /JUMP IF SO
+ IAC /BUMP TO ONE PRESENT VALUE
+ SNA CLA /SKIP IF NOT THE CASE
+ JMP NORM1 /JUMP IF SO
+CLOSFIL,TAD COLUMN /GET CURRENT COLUMN COUNTER
+ SZA CLA /SKIP IF AT BEGINNING ALREADY
+ JMS I (PCRLF) /ELSE OUTPUT / NOW
+ TAD ("Z&37) /GET <^Z>
+CLOSLUP,JMS I [DOBYTE] /OUTPUT A BYTE (^Z OR NULL)
+ TAD BUFPTR /GET THE OUTPUT BUFFER POINTER
+ TAD (-OUTBUFFER) /COMPARE TO RESET VALUE
+ SZA CLA /SKIP IF IT MATCHES
+ JMP CLOSLUP /ELSE KEEP GOING
+ ISZ ENCODIT /NO ERRORS
+ JMP I ENCODIT /RETURN
+
+/ COMES HERE IF FILE ENDS WITH ONLY TWO DATA CHARACTERS.
+
+NORM2, DCA CHARS+2 /CLEAR THIRD CHARACTER
+ JMS I (OUT3) /OUTPUT THE THREE BYTES
+ JMP ENDFCOMPRESS /FINISH IT THERE
+
+ PAGE
+/ GET AN INPUT BYTE ROUTINE.
+
+GETBYTE,.-. /GET A BYTE ROUTINE
+ SNA CLA /INITIALIZING?
+ JMP I PUTC /NO, GO GET NEXT BYTE
+ TAD INRECORD /GET INPUT FILE STARTING RECORD
+ DCA GETRECORD /STORE IN-LINE
+GETNEWR,JMS I INPUT /CALL INPUT HANDLER
+ 2^100 /READ TWO PAGES
+PINBUFF,INBUFFER /INTO INPUT BUFFER
+GETRECO,.-. /WILL BE LATEST INPUT FILE RECORD
+ JMP I (PROCERR) /INPUT READ ERROR, GO COMPLAIN
+ TAD PINBUFFER/(INBUFFER) /SETUP THE
+ DCA INPTR /BUFFER POINTER
+GETLOOP,DCA THIRD /CLEAR THIRD BYTE NOW
+ JMS PUTONE /OBTAIN AND SEND BACK FIRST BYTE
+ JMS PUTONE /OBTAIN AND SEND BACK SECOND BYTE
+ TAD THIRD /GET THIRD BYTE
+ JMS PUTC /SEND IT BACK
+ TAD INPTR /GET THE POINTER
+ TAD (-2^200-INBUFFER) /COMPARE TO LIMIT
+ SZA CLA /SKIP IF AT END
+ JMP GETLOOP /KEEP GOING
+ ISZ GETRECORD /BUMP TO NEXT RECORD
+ NOP /JUST IN CASE
+ ISZ INLEN /DONE ALL INPUT RECORDS?
+ JMP GETNEWRECORD /NO, KEEP GOING
+
+/ AT END-OF-FILE, SO JUST TAKE IMMEDIATE RETURN.
+
+ JMP I GETBYTE /RETURN TO CALLER
+
+PUTONE, .-. /SEND BACK A BYTE ROUTINE
+ TAD I INPTR /GET LATEST WORD
+ AND [7400] /JUST THIRD-BYTE NYBBLE
+ CLL RAL /MOVE UP
+ TAD THIRD /GET OLD NYBBLE (IF ANY)
+ RTL;RTL /MOVE UP NYBBLE BITS
+ DCA THIRD /SAVE FOR NEXT TIME
+ TAD I INPTR /GET LATEST WORD AGAIN
+ JMS PUTC /SEND BACK CURRENT BYTE
+ ISZ INPTR /BUMP TO NEXT WORD
+ JMP I PUTONE /RETURN
+
+PUTC, .-. /SEND BACK LATEST BYTE ROUTINE
+ AND (377) /KEEP ONLY GOOD BITS
+ DCA CHAR /SAVE AS LATEST BYTE
+ ISZ GETBYTE /BUMP PAST RETURN
+ JMP I GETBYTE /RETURN TO MAIN CALLER
+/ COMPRESSION FIELD OUTPUT ROUTINE.
+
+COMPRES,.-. /COMPRESSION OUTPUT ROUTINE
+ CLA /CLEAN UP
+ TAD COLUMN /GET CURRENT COLUMN COUNTER
+ TAD (-WIDTH+2) /COMPARE TO UPPER LIMIT
+ SMA SZA CLA /SKIP IF NOT ABOVE LIMIT
+ JMS PCRLF /ELSE DO / FIRST
+ TAD (176) /GET TILDE VALUE
+ JMS I [DOBYTE] /OUTPUT IT
+ TAD CMPCNT /GET COMPRESSION COUNT
+ JMS PDIGIT /OUTPUT IT
+ DCA CMPCNT /CLEAR COMPRESSION
+ JMP I COMPRESSOUT /RETURN
+
+/ DATA FIELD OUTPUT ROUTINE.
+
+OUT3, .-. /OUTPUT THREE BYTES ROUTINE
+ TAD COLUMN /GET CURRENT COLUMN COUNTER
+ TAD (-WIDTH+4) /COMPARE TO UPPER LIMIT
+ SMA SZA CLA /SKIP IF NOT ABOVE LIMIT
+ JMS PCRLF /ELSE DO / FIRST
+ TAD CHARS /GET FIRST BYTE
+ RTR /WANT HIGH SIX BITS FIRST
+ JMS PDIGIT /OUTPUT THEM
+ TAD CHARS /GET IT AGAIN
+ AND [3] /JUST TWO LOWEST BITS
+ CLL RTR;RTR;RAR /MOVE UP
+ TAD CHARS+1 /GET SECOND BYTE
+ RTR;RTR /MOVE DOWN
+ JMS PDIGIT /OUTPUT THEM
+ TAD CHARS+2 /GET THIRD BYTE
+ AND (300) /JUST TWO HIGHEST BITS NEEDED
+ CLL RTL;RTL;RAL /MOVE INTO POSITION
+ TAD CHARS+1 /GET SECOND BYTE
+ RTL /MOVE UP
+ AND [77] /JUST DESIRED BITS
+ JMS PDIGIT /OUTPUT THEM
+ TAD CHARS+2 /GET THIRD BYTE
+ AND [77] /JUST SIX BITS
+ JMS PDIGIT /OUTPUT THEM
+ TAD [CHARS] /RESET THE
+ DCA CHARPTR /OUTPUT POINTER
+ JMP I OUT3 /RETURN
+
+PDIGIT, .-. /PRINT AS A DIGIT INTO FILE ROUTINE
+ AND [177] /REMOVE JUNK BITS
+ TAD ("0&177) /TURN PASSED VALUE INTO A DIGIT
+ JMS I [DOBYTE] /OUTPUT IT
+ JMP I PDIGIT /RETURN
+PCRLF, .-. /PRINT / INTO FILE ROUTINE
+ TAD ("M&37) /GET A
+ JMS I [DOBYTE] /OUTPUT IT
+ TAD ("J&37) /GET A
+ JMS I [DOBYTE] /OUTPUT IT
+ DCA COLUMN /CLEAR COLUMN COUNTER
+ JMP I PCRLF /RETURN
+
+ PAGE
+PUTBYTE,.-. /OUTPUT A BYTE ROUTINE
+ SPA /ARE WE INITIALIZING?
+ JMP PUTINITIALIZE /YES
+ AND [177] /JUST IN CASE
+ DCA LATEST /SAVE LATEST CHARACTER
+ TAD LATEST /GET LATEST CHARACTER
+ JMP I PUTNEXT /GO WHERE YOU SHOULD GO
+
+PUTNEXT,.-. /EXIT ROUTINE
+ ISZ PUTBYTE /BUMP TO GOOD RETURN
+PUTERRO,CLA CLL /CLEAN UP
+ JMP I PUTBYTE /RETURN TO MAIN CALLER
+
+PUTINIT,CLA /CLEAN UP
+ TAD OUTRECORD /GET STARTING RECORD OF TENTATIVE FILE
+ DCA PUTRECORD /STORE IN-LINE
+ DCA I (OUTCNT) /CLEAR ACTUAL FILE LENGTH
+PUTNEWR,TAD (OUTBUFFER) /SETUP THE
+ DCA BUFPTR /BUFFER POINTER
+PUTLOOP,JMS PUTNEXT /GET A CHARACTER
+ DCA I BUFPTR /STORE IT
+ TAD BUFPTR /GET POINTER VALUE
+ DCA TEMPTR /SAVE FOR LATER
+ ISZ BUFPTR /BUMP TO NEXT
+ JMS PUTNEXT /GET A CHARACTER
+ DCA I BUFPTR /STORE IT
+ JMS PUTNEXT /GET A CHARACTER
+ RTL;RTL /MOVE UP
+ AND [7400] /ISOLATE HIGH NYBBLE
+ TAD I TEMPTR /ADD ON FIRST BYTE
+ DCA I TEMPTR /STORE COMPOSITE
+ TAD LATEST /GET LATEST CHARACTER
+ RTR;RTR;RAR /MOVE UP AND
+ AND [7400] /ISOLATE LOW NYBBLE
+ TAD I BUFPTR /ADD ON SECOND BYTE
+ DCA I BUFPTR /STORE COMPOSITE
+ ISZ BUFPTR /BUMP TO NEXT
+ TAD BUFPTR /GET LATEST POINTER VALUE
+ TAD (-2^200-OUTBUFF)/COMPARE TO LIMIT
+ SZA CLA /SKIP IF AT END
+ JMP PUTLOOP /KEEP GOING
+ ISZ DANGCNT /TOO MANY RECORDS?
+ SKP /SKIP IF NOT
+ JMP I (SIZERR) /JUMP IF SO
+ JMS I OUTPUT /CALL I/O HANDLER
+ 2^100+WRITE /WRITE SOME PAGES FROM OUTPUT BUFFER
+ OUTBUFFER /BUFFER ADDRESS
+PUTRECO,.-. /WILL BE LATEST RECORD NUMBER
+ JMP PUTERROR /OUTPUT ERROR!
+ ISZ I (OUTCNT) /BUMP ACTUAL LENGTH
+ ISZ PUTRECORD /BUMP TO NEXT RECORD
+ JMP PUTNEWRECORD /KEEP GOING
+/ INPUT FILENAME MOVE ROUTINE; USES DEFAULT EXTENSION IF NONE PROVIDED BY USER.
+
+MIFNAME,.-. /MOVE INPUT FILENAME ROUTINE
+ TAD I (INFILE+1) /GET FIRST INPUT FILENAME WORD
+ DCA IFNAME /STASH IT
+ TAD I (INFILE+2) /GET SECOND INPUT FILENAME WORD
+ DCA IFNAME+1 /STASH IT
+ TAD I (INFILE+3) /GET THIRD INPUT FILENAME WORD
+ DCA IFNAME+2 /STASH IT
+ TAD I [INFILE+4] /GET FOURTH INPUT FILENAME WORD
+ SNA /SKIP IF SOMETHING THERE
+ TAD ("S^100+"V-300) /ELSE USE DEFAULT EXTENSION VALUE
+ DCA IFNAME+3 /STASH IT EITHER WAY
+ JMP I MIFNAME /RETURN
+
+DOBYTE, .-. /OUTPUT A BYTE ROUTINE
+ JMS PUTBYTE /OUTPUT PASSED VALUE
+ JMP I (ENCERROR) /COULDN'T DO IT
+ ISZ COLUMN /BUMP COLUMN COUNTER
+ JMP I DOBYTE /RETURN
+
+ PAGE
+/ INPUT FILE ROUTINE.
+
+GEIFILE,.-. /GET INPUT FILE ROUTINE
+ JMS LUKUP /TRY TO LOOKUP THE FILE
+ SKP /SKIP IF IT WORKED
+ JMP TRYNULL /TRY NULL EXTENSION VERSION
+NULLOK, TAD LARG1 /GET FIRST INPUT RECORD
+ DCA INRECORD /STASH IT
+ TAD LARG2 /GET NEGATED LENGTH
+ DCA INLEN /STASH IT
+ JMP I GEIFILE /RETURN
+
+/ COMES HERE IF LOOKUP FAILED.
+
+TRYNULL,CDF TBLFLD /GOTO TABLE FIELD
+ TAD I [INFILE+4] /GET ORIGINAL FILENAME'S EXTENSION
+ CDF PRGFLD /BACK TO OUR FIELD
+ SZA CLA /SKIP IF IT WAS NULL ORIGINALLY
+ JMP I (INERR) /ELSE COMPLAIN OF EXPLICIT LOOKUP FAILURE
+ DCA IFNAME+3 /NOW TRY NULL VERSION INSTEAD OF DEFAULT VERSION
+ JMS LUKUP /TRY TO LOOK IT UP AGAIN
+ JMP NULLOK /THAT WORKED!
+ JMP I (INERR) /COMPLAIN OF LOOKUP FAILURE
+
+LUKUP, .-. /LOW-LEVEL LOOKUP ROUTINE
+ TAD (IFNAME) /GET OUR FILENAME POINTER
+ DCA LARG1 /STORE IN-LINE
+ DCA LARG2 /CLEAR SECOND ARGUMENT
+ TAD IDNUMBER /GET INPUT DEVICE NUMBER
+ CIF USRFLD /GOTO USR FIELD
+ JMS I [USR] /CALL USR ROUTINE
+ LOOKUP /WANT LOOKUP FUNCTION
+LARG1, .-. /WILL BE POINTER TO OUR FILENAME
+LARG2, .-. /WILL RETURN FILE LENGTH (HOPEFULLY)
+ ISZ LUKUP /LOOKUP FAILED, SO BUMP RETURN ADDRESS
+ JMP I LUKUP /RETURN EITHER WAY
+/ INPUT FILENAME PRINT ROUTINE.
+
+PIFNAME,.-. /PRINT INPUT FILENAME ROUTINE
+ TAD IFNAME /GET FIRST PAIR
+ JMS PIF2 /PRINT IT
+ TAD IFNAME+1 /GET SECOND PAIR
+ JMS PIF2 /PRINT IT
+ TAD IFNAME+2 /GET THIRD PAIR
+ JMS PIF2 /PRINT IT
+ TAD (".&177) /GET SEPARATOR
+ JMS PIFOUT /PRINT IT
+ TAD IFNAME+3 /GET FOURTH PAIR
+ JMS PIF2 /PRINT IT
+ JMP I PIFNAME /RETURN
+
+PIF2, .-. /PRINT A PAIR ROUTINE
+ DCA PIFTEMP /SAVE PASSED PAIR
+ TAD PIFTEMP /GET IT BACK
+ RTR;RTR;RTR /MOVE DOWN
+ JMS PIFOUT /PRINT HIGH-ORDER FIRST
+ TAD PIFTEMP /GET IT AGAIN
+ JMS PIFOUT /PRINT LOW-ORDER
+ JMP I PIF2 /RETURN
+
+PIFOUT, .-. /FILENAME CHARACTER OUTPUT ROUTINE
+ AND [77] /JUST SIXBIT
+ SNA /SKIP IF SOMETHING THERE
+ JMP I PIFOUT /ELSE IGNORE IT
+ TAD [40] /INVERT IT
+ AND [77] /REMOVE EXCESS
+ TAD [40] /INVERT IT AGAIN
+ JMS I [DOBYTE] /OUTPUT IT
+ JMP I PIFOUT /RETURN
+
+MOFNAME,.-. /MOVE OUTPUT FILENAME ROUTINE
+ TAD I [OUTFILE+1] /GET FIRST OUTPUT FILENAME WORD
+ JMS CHKNAME /CHECK IF LEGAL
+ DCA FNAME /STASH IT
+ TAD I (OUTFILE+2) /GET SECOND OUTPUT FILENAME WORD
+ JMS CHKNAME /CHECK IF LEGAL
+ DCA FNAME+1 /STASH IT
+ TAD I (OUTFILE+3) /GET THIRD OUTPUT FILENAME WORD
+ JMS CHKNAME /CHECK IF LEGAL
+ DCA FNAME+2 /STASH IT
+ TAD I (OUTFILE+4) /GET FOURTH OUTPUT FILENAME WORD
+ JMS CHKNAME /CHECK IF LEGAL
+ DCA FNAME+3 /STASH IT
+ JMP I MOFNAME /RETURN
+/ OUTPUT NAME CHECK ROUTINE.
+
+CHKNAME,.-. /OUTPUT NAME CHECK ROUTINE
+ DCA LUKUP /SAVE PASSED VALUE
+ TAD LUKUP /GET IT BACK
+ RTR;RTR;RTR /MOVE DOWN
+ JMS CHKIT /CHECK HIGH-ORDER AND GET IT BACK
+ JMS CHKIT /CHECK LOW-ORDER AND GET IT BACK
+ JMP I CHKNAME /RETURN
+
+CHKIT, .-. /ONE CHARACTER CHECK ROUTINE
+ AND [77] /JUST SIX BITS
+ TAD (-"?!200) /COMPARE TO "?"
+ SZA /SKIP IF ALREADY BAD
+ TAD (-"*+"?) /ELSE COMPARE TO "*"
+ SNA CLA /SKIP IF NEITHER BAD CASE
+ JMP I (BADNAME) /COMPLAIN OF WILD CHARACTER
+ TAD LUKUP /GET THE PAIR BACK FOR NEXT TIME
+ JMP I CHKIT /RETURN
+
+ PAGE
+ $ /THAT'S ALL FOLK!