Trailing-Edge
-
PDP-10 Archives
-
ks10_8080_microcode
-
pblast.mac
There are no other files named pblast.mac in the archive.
;<TAPE-ENG-SYSTEM-FILE-AREA>BLAST.MAC.2, 22-Oct-80 10:32:35, Edit by KINZELMAN
;Fixed missing byte on packed output mode
;<KINZELMAN.TMP>BLAST.MAC.2, 23-Jan-80 16:22:07, Edit by KINZELMAN
TITLE BLAST - PROGRAM TO SEND PROM DATA TO PROM PROGRAMMER
VERSION=1 ;PROGRAM VERSION NUMBER
EDIT=5 ;PROGRAM EDIT NUMBER
SUBTTL DEFINITIONS
SEARCH MONSYM,MACSYM
P=17
T1=5
T2=6
T3=7
T4=10
T5=11
S1=12
S2=13
S3=14
S4=15
S5=16
;A MACRO TO POSITION A VALUE INTO A FIELD SPECIFIED BY A MASK
DEFINE FLD(DATA,MASK),<<MASK>&<<DATA>B<^L<<MASK>^!<<MASK>-1>>>>>
;SOME MESSAGE PRINT MACROS
;PMSG - PRINT MESSAGE
DEFINE PMSG(MSG),<
HRROI 1,[ASCIZ\MSG\]
PSOUT
>
;PMSGC - PRINT MESSAGE AND END WITH A <CR><LF>
DEFINE PMSGC(MSG),<
HRROI 1,[ASCIZ\MSG
\]
PSOUT
>
;PCMSG - PRINT MESSAGE AFTER A <CR><LF>
DEFINE PCMSG(MSG),<
HRROI 1,[ASCIZ\
MSG\]
PSOUT
>
;PCMSGC - PRINT MESSAGE WITH A <CR><LF> BEFORE AND AFTER
DEFINE PCMSGC(MSG),<
HRROI 1,[ASCIZ\
MSG
\]
PSOUT
>
;PVER - PRINT PROGRAM NAME AND VERSION
DEFINE PVER(NAME,VERSION,EDIT),<
PMSGC <NAME V'VERSION(EDIT)>
>
SALL
SUBTTL INITIALIZATION
LOC 137
<VERSION>B12+EDIT ;STORE PROGRAM VERSION
START: RESET
MOVE P,PLIST ;SET UP STACK POINTER
;PRINT PROGRAM NAME AND VERSION
PVER BLAST,\VERSION,\EDIT
;INITIALIZE THE PARAMETERS
SETZM FIRST ;FIRST ADDRESS IS 0
SETZM LAST ;LAST ADDRESS NOT SPECIFIED
SETZM SIZE ;SIZE NOT SPECIFIED
SETZM BYTE ;BYTE POSITION NOT SPECIFIED
SETZM FILL ;NULL CHARACTER IS 000
SETZM FILE ;NO JFN EXISTS
SETZM TYPE ;FILE TYPE NOT SPECIFIED
SETZM INVERT# ;SET NOINVERT MODE
MOVEI ^D10 ;ADDRESS INPUT RADIX IS DECIMAL
MOVEM RADIX
SETZM COMBUF ;CLR OUT OLD COMMENT
SETZM LSTJFN ;CLR OUT LIST JFN KEEPER
SETZM BINMOD# ;CLR OUT BINARY MODE FLG
SUBTTL COMMAND DECODER
;GET A COMMAND
COMAND: MOVE P,PLIST ;SET UP STACK POINTER
MOVEI 1,[ REPARS
.PRIIN,,.PRIOU
POINT 7,[ASCIZ/BLAST>/]
POINT 7,CMDBUF
POINT 7,CMDBUF
CMDBFS*5
0
POINT 7,ATOMBF
ATOMBS*5
JFNBF ]
MOVEI 2,[FLDDB. (.CMINI)] ;INITIALIZE
COMND
TLNE 1,(CM%NOP) ;CHECK IF ERROR
ERJMP EROUT ;ERROR
REPARS: MOVEI 2,[FLDDB. (.CMKEY,,F1)]
COMND
TLNE 1,(CM%NOP)
JRST EROUT ;ERROR
HRRZ @2 ;GET ADDRESS OF REQUESTED ROUTINE
JRST @0 ;GO TO ROUTINE
SUBTTL FILE COMMAND
;FILE ROUTINE
;GET A FILE NAME TO USE
FILENM: MOVEI 2,[FLDDB. (.CMNOI,,<POINT 7,[ASCIZ/to use/]>)]
COMND ;GIVE GUIDE WORDS
TLNE 1,(CM%NOP) ;CHECK FOR ERROR
JRST EROUT
MOVEI 2,[FLDDB. (.CMIFI)]
COMND ;GET A FILE NAME
TLNE 1,(CM%NOP) ;CHECK FOR ERROR
JRST EROUT
MOVEM 2,T1 ;SAVE JFN
MOVEI 2,[FLDDB. (.CMNOI,,<POINT 7,[ASCIZ/of type/]>)]
COMND ;GIVE GUIDE WORDS
TLNE 1,(CM%NOP) ;CHECK FOR ERROR
JRST EROUT
PUSH P,1 ;SAVE COMAND ARG
HRROI 1,TEMPBF ;GET TYPE FIELD FROM FILE NAME
MOVE 2,T1 ;GET JFN
MOVSI 3,(FLD(1,JS%TYP)) ;ASK FOR TYPE FIELD ONLY
JFNS
ERJMP EROUT
MOVEI 1,TYPFLD ;COMPARE WITH RECOGNIZED TYPES
HRROI 2,TEMPBF ;TYPE FIELD IS IN TEMPBF
TBLUK
TLNN 2,(TL%EXM) ;CHECK IF AN EXACT MATCH
JRST FTUNK ;NO
MOVSI (CM%DPP) ;GET DEFAULT STRING EXISTS BIT
ORM TYPCMD ;PUT INTO FUNCTION DESCRIPTOR BLOCK
HRROI TEMPBF ;GET POINTER TO TYPE STRING
MOVEM TYPCMD+.CMDEF ;PLACE IN FUNCTION DESCRIPTOR BLOCK
JRST FTASK
FTUNK: MOVSI (CM%DPP) ;GET DEFAULT STRING EXISTS BIT
ANDCAM TYPCMD ;CLEAR BIT IN FUNCTION DESCRIPTOR BLOCK
FTASK: POP P,1 ;GET BACK COMND ARG
MOVEI 2,TYPCMD ;POINT TO FUNCTION DESCRIPTOR BLOCK
COMND ;ASK FOR TYPE OF FIELD
TLNE 1,(CM%NOP) ;CHECK FOR ERROR
JRST EROUT
HRRZ T2,@2 ;GET POINTER TO TYPE
MOVEI 2,[FLDDB. (.CMCFM)]
COMND ;WAIT FOR CONFIRMATION
TLNE 1,(CM%NOP) ;CHECK FOR ERROR
JRST FILEER
SKIPN FILE ;CHECK IF A JFN ALREADY ASSIGNED
JRST FILEDO ;NO
MOVE 1,FILE ;YES, GET OLD JFN
RLJFN ;RELEASE THE OLD JFN
ERJMP EROUT
FILEDO: MOVEM T1,FILE ;PUT JFN IN PARAMETER TABLE
MOVEM T2,TYPE ;PUT TYPE IN PARAMETER TABLE
JRST COMAND ;GO GET NEXT COMMAND
FILEER: MOVE 1,T1 ;GET NEW JFN
RLJFN ;RELEASE JFN AGAIN
ERJMP EROUT
JRST EROUT
TYPCMD: FLD(.CMKEY)+CM%DPP ;FILE DESCRIPTOR BLOCK
TYPFLD ;TO INPUT FILE TYPE
0
POINT 7,TEMPBF ;DEFAULT IS IN TEMPBF
SUBTTL EXIT COMMAND
;EXIT ROUTINE
EXIT: MOVEI 2,[FLDDB. (.CMNOI,,<POINT 7,[ASCIZ/to monitor/]>)]
COMND ;GIVE GUIDE WORDS
TLNE 1,(CM%NOP) ;CHECK FOR ERROR
JRST EROUT
MOVEI 2,[FLDDB. (.CMCFM)]
COMND ;WAIT FOR CONFIRMATION
TLNE 1,(CM%NOP) ;CHECK FOR ERROR
JRST EROUT
SETO 1, ;RELEASE ALL JFNS
CLOSF
ERJMP EROUT
HALTF ;EXIT TO THE MONITOR
JRST COMAND ;RESTART IF CONTINUED
SUBTTL SEND COMMAND
;SEND ROUTINE
;THIS ROUTINE ACTUALLY TRANSFERS THE DATA TO THE PROM PROGRAMMER
SEND: MOVEM 1,SAVCMD# ;SAVE AC1 FOR LATER
;GET A JFN TO BLASTR:
MOVSI 1,(GJ%FOU+GJ%SHT)
HRROI 2,[ASCIZ/BLASTR:/]
GTJFN ;GET A JFN
ERJMP ERQUIT ;ERROR
HRRZM 1,BLASTR ;SAVE JFN
;OPEN BLASTR: FOR OUTPUT IN BINARY MODE
MOVSI 2,(8B5) ;8 BIT BYTES
HRRI 2,OF%NWT+OF%RTD+OF%WR
OPENF ;OPEN FILE
ERJMP ERQT1 ;ERROR
DVCHR ;READ DEVICE CHARACTERISTICS
ERJMP EROT1
AND 2,[DV%TYP] ;KEEP ONLY DEVICE TYPE FIELD
CAMN 2,[FLD(.DVTTY,DV%TYP)] ;CHECK TYPE WITH TTY CODE
JRST BTTY ;BLASTR: IS A TTY
PMSGC <?Device BLASTR: is not a TTY>
RLJFN ;RELEASE BLASTER
ERJMP EROUT
HALTF ;STOP, ONLY PROCEED IF CONTINUED
JRST COMAND ;THEN GO DIRECTLY TO COMAND
BTTY: SETZ 2, ;SET JFN MODE WORD TO ZEROS
SFMOD ;TO PUT IN BINARY MODE
ERJMP EROT1
STPAR ;AND SET WIDTH TO 0
ERJMP EROT1
MOVEI 2,[FLDDB. (.CMNOI,,<POINT 7,[ASCIZ/data to programmer/]>)]
MOVE 1,SAVCMD ;RESTORE AC1 FOR COMND
COMND ;SEND GUIDE WORDS
TLNE 1,(CM%NOP) ;CHECK FOR ERROR
JRST EROT1
MOVEI 2,[FLDDB. (.CMCFM)]
COMND ;WAIT FOR CONFIRMATION
TLNE 1,(CM%NOP) ;CHECK FOR ERROR
JRST EROT1
PUSHJ P,GENBUF ;GENERATE A BUFFER FULL OF DATA
JRST COMAND ;NO SKIP RTN IF NO DATA
SKIPN INVERT ;SKIP IF INVERT FLAG IS SET
JRST SENDGO ;BYPASS INVERSION OF DATA IF NOT
MOVSI 1,-<PROMSZ/4> ;GET COUNT OF WORDS IN BUFFER
SENDI: SETCMM ROMBUF(1) ;COMPLIMENT THE DATA
AOBJN 1,SENDI ;IN EACH BUFFER LOCATION
SENDGO: PMSG <Sending >
SKIPE INVERT ;SKIP IF NOT IN INVERT DATA MODE
PMSG <INVERTED >
PMSG <data to PROM programmer...>
MOVEI 1,.PRIOU ;WAIT FOR TYPING TO STOP
DOBE
ERJMP EROT1
MOVE 1,BLASTR ;GET JFN OF BLASTER
MOVE 2,[POINT 8,ROMBUF] ;POINT TO ROM BUFFER
MOVN 3,SNDSIZ ;GET NUMBER OF BYTES TO SEND
SOUT ;SEND THE DATA TO THE PROGRAMMER
ERJMP EROT1
MOVE 1,BLASTR ;WAIT FOR OUTPUT BUFFER TO EMPTY
DOBE
ERJMP EROT1
PMSGC <done>
MOVEI 1,.PRIOU ;PRINT ON TTY
MOVE 2,SNDSIZ ;NUMBER OF BYTES SENT
MOVEI 3,^D10 ;IN DECIMAL
NOUT
ERJMP EROT1
PMSGC < bytes sent.>
MOVE 1,BLASTR ;GET BLASTER JFN AGN
CLOSF ;CLOSE OUT THE FILE
ERJMP EROUT ;HERE IF ERROR
JRST COMAND ;GET NEXT COMMAND
EROT1: PUSH P,1 ;SAVE AC1
MOVE 1,BLASTR ;GET THE BLASTER JFN
RLJFN ;AND RELEASE IT
JFCL
POP P,1 ;RESTORE AC1
JRST EROUT
ERQT1: PUSH P,1 ;SAVE AC1
MOVE 1,BLASTR ;GET THE BLASTER JFN
RLJFN ;AND RELEASE IT
JFCL
POP P,1
JRST ERQUIT
SUBTTL GENERATE BUFFER OF DATA FOR PROM
;GENBUF ROUTINE
;THIS ROUTINE CAUSES THE FILE TO BE READ AND THE SPECIFIED RANGE
;OF ADDRESSES TO BE FILLED WITH DATA BYTES IN ROM BUFFER.
;THIS ROUTINE USES THE PARAMETER TABLE ENTRIES TO DETERMINE
;INPUT FILE AND ADDRESS RANGE.
;THE ACTUAL SIZE OF THE ROM BUFFER THAT WAS FILLED IS RETURNED
;IN SNDSIZ. THE ACTUAL LAST ADDRESS IN THE ROM BUFFER IS RETURNED
;IN SNDLST.
;IF ERRORS OCCUR, A MESSAGE IS PRINTED AND CONTROL IS TRANSFERRED
;DIRECTLY TO COMAND.
;IF NO DATA IN WINDOW OF INTEREST, WE DON'T SKIP RTN. IF DATA THERE,
;SKIP RTN
GENBUF: SKIPN FILE ;CHECK IF A FILE WAS SPECIFIED
JRST [PMSGC <?No file was specified.>
JRST COMAND ]
MOVE T1,LAST ;GET LAST ARGUMENT FROM PARAM TABLE
PUSHJ P,COMPS ;COMPUTE SIZE OF PROM
;LAST ADDRESS IS PLACED IN SNDLST
;SIZE IS PLACED IN SNDSIZ
PUSHJ P,FILLBF ;WRITE FILL CHARACTER INTO BUFFER
SETZM TCOUNT# ;CLEAR TOTAL BYTE COUNT OF FILE
SETZM COUNT# ;CLEAR COUNT OF LOCATIONS FULL
SETZM HIGH# ;CLEAR HIGH ADDRESS FULL IN BUFFER
HLRZ T1,@TYPE ;GET ADDRESS OF SELECTED INIT ROUTINE
PUSHJ P,@T1 ;INIT FILE READ ROUTINE
HRRZ T1,@TYPE ;GET ADDRESS OF READ BYTE ROUTINE
GENLOP: PUSHJ P,@T1 ;READ A DATA BYTE
;ROUTINES RETURN DATA BYTE IN T2
;AND ADDRESS OF BYTE IN T3
;ON NORMAL SKIP RETURN
JRST DONE ;NON-SKIP RETURN MEANS END OF FILE
AOS TCOUNT ;COUNT BYTES READ FROM FILE
CAML T3,FIRST ;CHECK IF ADDRESS IS IN RANGE OF PROM
CAMLE T3,SNDLST
JRST GENLOP ;NO, GO GET NEXT BYTE
CAMLE T3,HIGH ;CHECK IF ADDRESS IS HIGHEST SO FAR
MOVEM T3,HIGH ;YES, PUT IN HIGH
AOS COUNT ;COUNT BYTES IN RANGE
MOVE T4,T3 ;COPY ADDRESS TO T4
SUB T4,FIRST ;COMPUTE INDEX INTO ROM BUFFER
IDIVI T4,4 ;T4-WORD INDEX, T5-BYTE INDEX OF WORD
DPB T2,[POINT 8,ROMBUF(T4),7
POINT 8,ROMBUF(T4),15
POINT 8,ROMBUF(T4),23
POINT 8,ROMBUF(T4),31 ](T5) ;DEPOSIT BYTE
JRST GENLOP ;GO BACK FOR NEXT BYTE
DONE: PMSG <File contains >
MOVEI 1,.PRIOU ;OUTPUT TO TERMINAL
MOVE 2,TCOUNT ;COUNT OF BYTES IN FILE
MOVEI 3,^D10 ;IN DECIMAL
NOUT
ERJMP EROUT
PMSG < bytes, >
CAME 2,COUNT ;CHECK IF SAME AS BYTES IN RANGE
JRST DONEP1 ;NO
PMSG <all>
JRST DONEP3
DONEP1: MOVE 2,COUNT ;GET COUNT IN RANGE
JUMPE 2,DONEP2 ;CHECK IF ANY IN RANGE
MOVEI 1,.PRIOU ;OUTPUT TO TERMINAL
NOUT ;NUMBER IN RANGE
ERJMP EROUT
JRST DONEP3
DONEP2: PMSG <none>
DONEP3: PMSGC < of which are in range of PROM addresses.>
JUMPE 2,DONEX ;IF NONE IN RANGE, STOP NOW
MOVE T1,LAST ;GET LAST PARAMETER
OR T1,SIZE ;AND SIZE PARAMETER
JUMPN T1,DONEOK ;IF EITHER ARE SPECIFIED, RETURN NOW
MOVE T1,HIGH ;REDUCE ROM BUFFER TO ACTUAL SIZE OF
CAMGE T1,SNDLST ;DATA FROM FILE
PUSHJ P,COMPS ;COMPUTE SIZE USING ACTUAL HIGH ADDRESS
PMSG <No size was specified, so defaulting to the following (in >
MOVE 3,RADIX ;GET ADDRESS RADIX
CAIN 3,^D8 ;IF OCTAL
HRROI 1,[ASCIZ/octal)/]
CAIN 3,^D10 ;OR IF DECIMAL
HRROI 1,[ASCIZ/decimal)/]
PSOUT ;PRINT RADIX
PCMSG < FIRST address >
MOVEI 1,.PRIOU ;PRINT ON TERMINAL
MOVE 2,FIRST ;THE FIRST ADDRESS
NOUT
ERJMP EROUT
PCMSG < LAST address >
MOVEI 1,.PRIOU ;PRINT ON TERMINAL
MOVE 2,SNDLST ;THE LAST ADDRESS
NOUT
ERJMP EROUT
PMSGC <>
DONEOK: AOS (P) ;INCR THE RTN ADR FOR NO ERROR
DONEX: MOVE 1,FILE ;GET JFN
HRLI 1,(CO%NRJ) ;CLOSE FILE, DON'T RELEASE JFN
CLOSF
ERJMP EROUT
POPJ P, ;RETURN NOW
;COMPUTE SIZE ROUTINE
;THIS ROUTINE TAKES ONE ARGUMENT IN T1 WHICH IT USES AS THE
;LAST ADDRESS SPECIFIED (UNSPECIFIED IF T1 CONTAINS ZERO).
;IF T1 IS POSITIVE, A PROM SIZE IS CALCULATED.
;IF T1 IS ZERO, THE PARAMETER SIZE IS USED TO CALCULATE LAST ADDRESS:
;IF SIZE IS ZERO, MAXIMUM PROM SIZE IS USED.
;IF SIZE IS POSITIVE, THE SIZE PARAMETER IS USED.
COMPS: JUMPE T1,COMPSS ;CHECK IF A LAST PARAM IS SPECIFIED
MOVEI T2,1(T1) ;YES, GET ONE GREATER
SUB T2,FIRST ;COMPUTE SIZE OF BUFFER
JUMPLE T2,[PMSGC <?LAST address is not greater than FIRST address.>
JRST COMAND ]
CAILE T2,PROMSZ ;CHECK IF SIZE IS NOT TOO LARGE
JRST [PMSG <?Size between FIRST and LAST addresses is greater than maximum of >
MOVEI 1,.PRIOU ;OUTPUT TO TERMINAL
MOVEI 2,PROMSZ ;MAXIMUM SIZE OF PROM
MOVEI 3,^D10 ;IN DECIMAL
NOUT
ERJMP EROUT
PMSGC < bytes.>
JRST COMAND ]
JRST COMPSX
COMPSS: SKIPN T2,SIZE ;CHECK IF SIZE WAS SPECIFIED
MOVEI T2,PROMSZ ;NO, GET MAXIMUM
MOVE T1,FIRST ;COMPUTE LAST ADDRESS
ADDI T1,-1(T2) ;USING SIZE AND FIRST
COMPSX: MOVEM T1,SNDLST# ;STORE LAST ADDRESS
MOVEM T2,SNDSIZ# ;STORE SIZE OF PROM
POPJ P, ;RETURN
;FILL BUFFER WITH NULL CHARACTERS
FILLBF: MOVE T1,FILL ;GET FILL CHARACTER
MOVE T2,[POINT 8,ROMBUF] ;POINTER TO BUFFER
MOVE T3,SNDSIZ ;SIZE OF BUFFER IN BYTES
FILLUP: IDPB T1,T2 ;DEPOSIT A BYTE
SOJG T3,FILLUP ;COUNT THE BYTES
POPJ P,
SUBTTL PRINT COMMAND
;PRINT ROM DATA ROUTINE
PRINT: MOVEI 2,[FLDDB.(.CMNOI,,<POINT 7,[ASCIZ/data to/]>)]
COMND ;GIVE GUIDE WORDS
TLNE 1,(CM%NOP) ;CHECK FOR ERROR
JRST EROUT
MOVEI 2,[FLDDB.(.CMOFI,,,,TTY:BLAST.PNT)]
COMND ;GET FILE NAME, DEFAULT TO TTY:
TLNE 1,(CM%NOP) ;CHECK FOR ERROR
JRST EROUT
MOVEM 2,PRJFN# ;SAVE JFN
MOVEI 2,[FLDDB.(.CMCFM)]
COMND ;WAIT FOR CONFIRMATION
TLNE 1,(CM%NOP) ;CHECK FOR ERROR
JRST EROUT
PUSHJ P,GENBUF ;READ FILE AND GET BUFFER OF DATA
JRST COMAND ;NO SKIP RTN IF NO DATA
MOVE 1,PRJFN ;GET OUTPUT FILE JFN
MOVSI 2,(FLD(7,OF%BSZ)) ;7 BIT BYTES
HRRI 2,OF%WR ;OPEN FILE FOR WRITING
OPENF
ERJMP EROUT
SETZM RELFLG ;CLR OUT FLG TO SAY NOT LIST OR OUTPUT
SKIPA ;SKIP OVER OUTPUT OR RELEASE ENTRY
;ENTER HERE FROM OUTPUT OR RELEASE
LISTIT: MOVE 1,LSTJFN ;GET LISTING JFN AGN
HRROI 2,[ASCIZ/
BLAST /]
SETZ 3,
SOUT ;PRINT HEADER
ERJMP EROUT
SETOB 2,3 ;PRINT DATE AND TIME
ODTIM
ERJMP EROUT
HRROI 2,[ASCIZ/
Input File Name /]
SETZ 3,
SOUT ;PRINT HEADER FOR FILE NAME
ERJMP EROUT
MOVE 2,FILE ;GET INPUT JFN
MOVE 3,[111110,,004011] ;SET FLAGS
JFNS ;PRINT FILE NAME
ERJMP EROUT
;NOW LET'S SEE IF WE'RE DOING RELEAS OR OUTPUT
SKIPN RELFLG ;SKIP IF RELEASE OR OUTPUT CMD
JRST NOTRO ;HERE IF NOT, DON'T DO OUTPUT FILE NAME
HRROI 2,[ASCIZ/
Output data file is /]
SETZM 3 ;0 BYTE TERM
SOUT
ERJMP EROUT ;HERE IF ERROR
HRROI 2,OFNAM ;POINT TO OUTPUT FILE NAME
SETZM 3 ;0 BYTE TERM
SOUT
ERJMP EROUT ;HERE IF ERROR
NOTRO: MOVE COMBUF ;GET THE 1ST COMMENT BUFFER WD
TLNN 774000 ;IS THERE ANYTHING THERE? (SKP IF YES)
JRST NOCOM ;JUMP HERE IF NO COMMENT
HRROI 2,[ASCIZ/
Comment is /]
SETZM 3 ;0 BYTE TERMINATOR
SOUT ;OUTPUT IT
ERJMP EROUT ;HERE IF ERROR
HRROI 2,COMBUF ;POINTER TO COMMENT STRING
SETZM 3 ;0 BYTE TERMINATOR
SOUT ;OUTPUT IT
ERJMP EROUT ;HERE IF ERROR
NOCOM: HRROI 2,[ASCIZ/
Author of ROM pattern is /]
SETZM 3 ;0 BYTE TERMINATOR
SOUT ;OUTPUT IT
ERJMP EROUT ;HERE IF ERROR
HRROI 2,AUTHST ;POINTER TO AUTHOR STRING
SETZM 3 ;0 BYTE TERMINATOR
SOUT ;OUTPUT IT
ERJMP EROUT ;HERE IF ERROR
HRROI 2,[ASCIZ/
First address /]
SETZ 3,
SOUT ;PRINT HEADER FOR FIRST ADDRESS
ERJMP EROUT
MOVE 2,FIRST ;PRINT FIRST ADDRESS
MOVE 3,RADIX ;IN ADDRESS RADIX
NOUT
ERJMP EROUT
MOVE RADIX ;GET RADIX
CAIN ^D8 ;IF OCTAL
HRROI 2,[ASCIZ/ (OCTAL)/] ;PRINT OCTAL
CAIN ^D10 ;IF DECIMAL
HRROI 2,[ASCIZ/ (decimal)/] ;PRINT DECIMAL
SETZ 3,
SOUT
ERJMP EROUT
HRROI 2,[ASCIZ/
Last address /]
SETZ 3,
SOUT ;PRINT HEADER FOR LAST ADDRESS
ERJMP EROUT
MOVE 2,SNDLST ;PRINT LAST ADDRESS
MOVE 3,RADIX ;IN CURRENT ADDRESS RADIX
NOUT
ERJMP EROUT
HRROI 2,[ASCIZ/
Size of PROM /]
SETZ 3,
SOUT ;PRINT HEADER FOR SIZE
ERJMP EROUT
MOVE 2,SNDSIZ ;PRINT SIZE
MOVEI 3,^D10 ;IN DECIMAL
NOUT
ERJMP EROUT
HRROI 2,[ASCIZ/ (decimal) bytes/]
SETZ 3,
SOUT
ERJMP EROUT
SKIPN BYTE ;SKIP IF A BYTE POSITION SPECIFIED
JRST PRNB ;JUMP AROUND IF NOT
HRROI 2,[ASCIZ/
Byte position /]
SETZ 3,
SOUT ;PRINT HEADER FOR BYTE POSITION
ERJMP EROUT
MOVE 2,BYTE ;PRINT BYTE
MOVEI 3,^D10 ;IN DECIMAL
NOUT
ERJMP EROUT
SKIPN SIZE ;SKIP IF SIZE HAS BEEN SPECIFIED
JRST PRNB ;NO
MOVE T1,FIRST ;GET FIRST ADDRESS
IDIV T1,SIZE ;CHECK IF A MULTIPLE OF SIZE
JUMPN T2,PRNB ;JUMP IF NOT
HRROI 2,[ASCIZ/
Array position /]
SETZ 3,
SOUT
ERJMP EROUT
MOVE 2,T1 ;GET MULTIPLIER
MOVEI 3,^D10 ;PRINT DECIMAL NUMBER
NOUT
ERJMP EROUT
HRROI 2,[ASCIZ/,/]
SETZ 3,
SOUT
ERJMP EROUT
MOVE 2,BYTE ;PRINT BYTE POSITION IN ARRAY
SOJ 2,
MOVEI 3,^D10 ;PRINT DECIMAL NUMBER
NOUT
ERJMP EROUT
PRNB: HRROI 2,[ASCIZ/
Null character /]
SETZ 3,
SOUT ;PRINT HEADER FOR NULL CHARACTER
ERJMP EROUT
MOVE 2,FILL ;PRINT NULL CHARACTER
MOVE 3,[NO%LFL+NO%ZRO+FLD(3,NO%COL)+8] ;IN OCTAL
NOUT
ERJMP EROUT
SKIPE RELFLG ;SKIP IF NOT RELEASING
HRROI 2,[ASCIZ/
NOTE: In all cases, the first word of the releasable .DAT file will be
the flag word 377. This flag word is not shown on the following data map./]
SETZ 3,
SOUT
ERJMP EROUT
HRROI 2,[ASCIZ/
/]
SETZ 3,
SOUT
ERJMP EROUT
MOVE RADIX ;PRINT RADIX
CAIN ^D8
HRROI 2,[ASCIZ/Octal /]
CAIN ^D10
HRROI 2,[ASCIZ/Decimal/]
SETZ 3,
SOUT
ERJMP EROUT
HRROI 2,[ASCIZ/ Octal data in address
address +0 +1 +2 +3 +4 +5 +6 +7/]
SETZ 3,
SOUT ;PRINT HEADER TO DATA TABLE
ERJMP EROUT
MOVE RADIX ;GET RADIX OF ADDRESSES
CAIE ^D10 ;IF DECIMAL
JRST PROCTU
HRROI 2,[ASCIZ/ +8 +9/] ;MAKE TABLE 10 COLUMNS
SETZ 3,
SOUT
ERJMP EROUT
PROCTU: HRROI 2,[ASCIZ/
------- --- --- --- --- --- --- --- ---/]
SETZ 3,
SOUT
ERJMP EROUT
MOVE RADIX
CAIE ^D10
JRST PROCTN
HRROI 2,[ASCIZ/ --- ---/]
SETZ 3,
SOUT
ERJMP EROUT
PROCTN: SETZM S1 ;CLR OUT 1ST LOC OF THIS ROM
MOVE S2,[POINT 8,ROMBUF] ;GET POINTER TO ROM BUFFER
PRTLOP: HRROI 2,[ASCIZ/
/]
SETZ 3, ;START A NEW LINE
SOUT
ERJMP EROUT
MOVE 2,S1 ;PRINT ADDRESS
MOVE 3,RADIX
HRLI 3,(NO%LFL+FLD(5,NO%COL)) ;IN FIVE DIGIT FIELD
NOUT
ERJMP EROUT
HRROI 2,[ASCIZ\ / \] ;PRINT SLASH
SETZ 3,
SOUT
ERJMP EROUT
MOVE S3,RADIX ;GET COUNT OF COLUMNS TO PRINT
PRTLPD: HRROI 2,[ASCIZ/ /] ;SEPARATE COLUMNS
SETZ 3,
SOUT
ERJMP EROUT
PRTLDO: ILDB 2,S2 ;GET A DATA BYTE
MOVE 3,[NO%LFL+NO%ZRO+FLD(3,NO%COL)+8]
NOUT ;PRINT 3 DIGITS
ERJMP EROUT
PRTLDC: AOS S1 ;INCREMENT TO NEXT ADDRESS
CAML S1,SNDSIZ ;CHECK IF DONE ALL THE DATA
JRST PRTDON ;YES, GET OUT OF LOOP
SOJG S3,PRTLPD ;CONTINUE TO NEXT COLUMN
JRST PRTLOP ;OR START NEXT LINE
PRTDON: HRROI 2,[ASCIZ/
/]
SKIPE RELFLG ;SKIP IF NOT RELEAS OR OUTPUT (IT'S PRINT)
HRROI 2,[15B6!12B13!14B20] ;GET A FORM FEED INSTEAD
SETZ 3,
SOUT ;MAKE ROOM AT END OF TABLE
ERJMP EROUT
SKIPE RELFLG ;SKIP IF PRINT (NOT RELEAS OR OUTPUT)
JRST PNTRTN ;RTN TO OUTPUT OR RELEAS COMMAND
CLOSF ;CLOSE THE FILE AND GET RID OF JFN
ERJMP EROUT ;(DON'T CLOSE FILE ON RELEAS OR OUTPUT)
JRST COMAND ;GO BACK FOR ANOTHER COMMAND
SUBTTL NULL COMMAND
;NULL CHARACTER COMMAND
NULL: MOVEI 2,[FLDDB.(.CMNOI,,<POINT 7,[ASCIZ/character/]>)]
COMND ;GIVE GUIDE WORDS
TLNE 1,(CM%NOP) ;CHECK FOR ERROR
JRST EROUT
MOVEI 2,NUMBER ;INPUT A NUMBER
MOVEI ^D8 ;IN OCTAL
MOVEM NUMBER+.CMDAT ;PUT IN FUNCTION DESCRIPTION BLOCK
COMND
TLNE 1,(CM%NOP) ;CHECK FOR ERROR
JRST EROUT
MOVEM 2,T1 ;SAVE NUMBER
MOVEI 2,[FLDDB.(.CMCFM)]
COMND ;WAIT FOR CONFIRMATION
TLNE 1,(CM%NOP) ;CHECK FOR ERROR
JRST EROUT
ANDI T1,377 ;STRIP CHARACTER TO 8 BITS
MOVEM T1,FILL ;PUT CHARACTER IN PARAMETER TABLE
JRST COMAND ;GO BACK FOR ANOTHER COMMAND
SUBTTL FIRST AND LAST COMMANDS
;FIRST AND LAST ADDRESS ROUTINES
FIRSTC: PUSHJ P,GETADR ;GET ADDRESS FROM COMMAND
MOVEM T1,FIRST ;SAVE FIRST ADDRESS IN PARAM TABLE
JRST COMAND
LASTC: PUSHJ P,GETADR ;GET ADDRESS FROM COMMAND
MOVEM T1,LAST ;SAVE LAST ADDRESS IN PARAM TABLE
SETZM SIZE ;MAKE SIZE AS NOT SPECIFIED
JRST COMAND
GETADR: MOVEI 2,[FLDDB.(.CMNOI,,<POINT 7,[ASCIZ/address to send/]>)]
COMND ;GIVE GUIDE WORDS
TLNE 1,(CM%NOP) ;CHECK FOR ERROR
JRST EROUT
MOVEI 2,NUMBER ;GET ADDRESS OF FUNCTION DESCRIPTOR BLOCK
MOVE RADIX ;GET CURRENT ADDRESS RADIX
MOVEM NUMBER+.CMDAT ;PUT INTO FUNCTION DESC BLOCK
COMND ;INPUT A NUMBER
TLNE 1,(CM%NOP) ;CHECK FOR ERROR
JRST EROUT
MOVEM 2,T1 ;SAVE NUMBER
MOVEI 2,[FLDDB.(.CMCFM)]
COMND ;WAIT FOR CONFIRMATION
TLNE 1,(CM%NOP) ;CHECK FOR ERROR
JRST EROUT
JUMPL T1,FLERR ;DON'T ALLOW NEGATIVE NUMBERS
POPJ P, ;RETURN
FLERR: PMSGC <NEGATIVE ADDRESSES ARE NOT ALLOWED.>
JRST COMAND
NUMBER: FLD(.CMNUM,CM%FNC) ;ACCEPT A NUMBER
0 ;RADIX WILL BE PUT HERE
SUBTTL SIZE COMMAND
;SIZE ROUTINE
SIZEC: MOVEI 2,[FLDDB.(.CMNOI,,<POINT 7,[ASCIZ/of PROM/]>)]
COMND ;GIVE GUIDE WORDS
TLNE 1,(CM%NOP) ;CHECK FOR ERROR
JRST EROUT
MOVEI 2,[FLDDB.(.CMKEY,,KSIZE,,,NUMBER)]
MOVEI ^D10 ;SET DECIMAL RADIX
MOVEM NUMBER+.CMDAT ;PUT IN NUMBER DESC BLOCK
COMND ;INPUT A NUMBER (OR 1K, 2K)
TLNE 1,(CM%NOP) ;CHECK FOR ERROR
JRST EROUT
HRRZS 3 ;LEAVE JUST ADDRESS OF DESC BLOCK IN 3
CAIE 3,NUMBER ;SEE IF A NUMBER WAS INPUT
HRRZ 2,@2 ;NO, GET NUMBER FROM KSIZE TABLE
MOVEM 2,T1 ;SAVE NUMBER
MOVEI 2,[FLDDB.(.CMCFM)]
COMND ;WAIT FOR CONFIRMATION
TLNE 1,(CM%NOP) ;CHECK FOR ERROR
JRST EROUT
JUMPL T1,SIZEBD ;JUMP IF SIZE IS NEGATIVE
CAILE T1,PROMSZ ;CHECK SIZE OF NUMBER
JRST SIZEBD ;JUMP IF SIZE IS TOO LARGE
MOVEM T1,SIZE ;STORE SIZE IN PARAM TABLE
SETZM LAST ;MARK LAST ADDRESS AS NOT SPECIFIED
JRST COMAND
SIZEBD: PMSG <Size out of range. Acceptable size is between 0 and >
MOVEI 1,.PRIOU ;SEND TO TERMINAL
MOVEI 2,PROMSZ ;THE MAXIMUM SIZE OF A PROM
MOVEI 3,^D10 ;IN DECIMAL
NOUT
ERJMP EROUT
PMSGC < BYTES.>
JRST COMAND
SUBTTL DECIMAL AND OCTAL COMMANDS
;RADIX COMMANDS
DECIML: MOVEI T1,^D10 ;SET TEMP RADIX TO DECIMAL
JRST RADIXC ;GET CONFIRMATION ON RADIX
OCTAL: MOVEI T1,^D8 ;SET TEMP RADIX TO OCTAL
RADIXC: MOVEI 2,[FLDDB.(.CMNOI,,<POINT 7,[ASCIZ/addresses/]>)]
COMND ;GIVE GUIDE WORDS
TLNE 1,(CM%NOP) ;CHECK FOR ERROR
JRST EROUT
MOVEI 2,[FLDDB.(.CMCFM)]
COMND ;WAIT FOR CONFIRMATION
TLNE 1,(CM%NOP) ;CHECK FOR ERROR
JRST EROUT
MOVEM T1,RADIX ;PUT NEW RADIX IN PARAM TABLE
JRST COMAND
SUBTTL LIST AND CLOSE COMMANDS
OPEN: MOVEI 2,[FLDDB. (.CMNOI,,<POINT 7,[ASCIZ/ROM data listing file/]>)]
COMND ;GIVE GUIDE WORDS
TLNE 1,(CM%NOP) ;CHECK FOR ERROR
JRST EROUT
MOVEI 2,[FLDDB. (.CMOFI)]
COMND ;GET A FILE NAME
TLNE 1,(CM%NOP) ;CHECK FOR ERROR
JRST EROUT
MOVEM 2,T1 ;SAVE JFN
MOVEI 2,[FLDDB.(.CMCFM)]
COMND ;WAIT FOR CONFIRMATION
TLNE 1,(CM%NOP) ;CHECK FOR ERROR
JRST EROUT
SKIPN LSTJFN ;IS THERE LIST JFN ALREADY?
JRST NOLJFN ;JRST HERE IF NO
PMSGC <ERROR - LIST FILE ALREADY OPEN>
JRST COMAND
NOLJFN: MOVEM T1,LSTJFN# ;SAVE JFN AWAY
MOVE 1,LSTJFN ;PUT JFN IN PLACE FOR OPENF
MOVE 2,[7B5!OF%WR] ;SET UP BITS (BYTE SIZE OF 7 FOR WRITE)
OPENF ;OPEN THE FILE
ERJMP EROUT
JRST COMAND ;HERE WHEN OPEN
CLOSE: MOVEI 2,[FLDDB. (.CMNOI,,<POINT 7,[ASCIZ/listing file/]>)]
COMND ;GIVE GUIDE WORDS
TLNE 1,(CM%NOP) ;CHECK FOR ERROR
JRST EROUT
MOVEI 2,[FLDDB.(.CMCFM)]
COMND ;WAIT FOR CONFIRMATION
TLNE 1,(CM%NOP) ;CHECK FOR ERROR
JRST EROUT
SKIPE 1,LSTJFN ;IS THERE LIST JFN?
JRST NOCJFN ;JRST HERE IF YES
PMSGC <ERROR - LIST FILE NOT OPEN YET>
JRST COMAND
NOCJFN: CLOSF ;CLOSE THE FILE, RELEASE JFN
ERJMP EROUT
JRST COMAND ;AND FINISHED
SUBTTL BYTE COMMAND
;BYTE POSITION COMMAND
BYTEC: MOVEI 2,[FLDDB.(.CMNOI,,<POINT 7,[ASCIZ/position/]>)]
COMND ;GIVE GUIDE WORDS
TLNE 1,(CM%NOP) ;CHECK FOR ERROR
JRST EROUT
MOVEI 2,NUMBER ;INPUT A NUMBER
MOVEI ^D10 ;IN DECIMAL
MOVEM NUMBER+.CMDAT ;PUT IN FUNCTION DESCRIPTOR BLOCK
COMND
TLNE 1,(CM%NOP) ;CHECK FOR ERROR
JRST EROUT
MOVEM 2,T1 ;SAVE NUMBER
MOVEI 2,[FLDDB.(.CMCFM)]
COMND ;WAIT FOR CONFIRMATION
TLNE 1,(CM%NOP) ;CHECK FOR ERROR
JRST EROUT
JUMPL T1,[PMSGC <?Negative byte position is not allowed.>
JRST COMAND ]
MOVEM T1,BYTE ;SAVE NUMBER IN PARAMETER TABLE
JRST COMAND ;GO BACK FOR ANOTHER COMMAND
SUBTTL ARRAY AND RELEASE COMMAND
;PROM POSITION IN ARRAY SPECIFIER
;SIZE MUST HAVE BEEN SPECIFIED PREVIOUSLY
;FIRST ARGUMENT SPECIFIES POSITION OF ADDRESS
;SECOND ARGUMENT SPECIFIES POSITION OF BYTE
RELEAS: SETOM RELFLG# ;SET FLG TO INDICATE RELEASE CMD
JRST ARRREL ;USE COMMON CODE
ARRAY: SETZM RELFLG ;CLR FLG TO INDICATE ARRAY CMD
ARRREL: MOVEI 2,[FLDDB.(.CMNOI,,<POINT 7,[ASCIZ/position of address/]>)]
COMND ;GIVE GUIDE WORDS
TLNE 1,(CM%NOP) ;CHECK FOR ERRORS
JRST EROUT
MOVEI 2,[FLDDB.(.CMNUM,CM%DPP,^D10,,0)]
COMND ;GET NUMBER
TLNE 1,(CM%NOP) ;CHECK FOR ERRORS
JRST EROUT
MOVEM 2,ARAYAD# ;SAVE NUMBER
MOVEI 2,[FLDDB.(.CMNOI,,<POINT 7,[ASCIZ/position of byte/]>)]
COMND ;GIVE GUIDE WORDS
TLNE 1,(CM%NOP) ;CHECK FOR ERRORS
JRST EROUT
MOVEI 2,[FLDDB.(.CMNUM,CM%DPP,^D10,,0)]
COMND ;GET NUMBER
TLNE 1,(CM%NOP) ;CHECK FOR ERROR
JRST EROUT
MOVEM 2,ARAYBT# ;SAVE NUMBER
SKIPE RELFLG ;SKIP IF ARRAY CMD, DON'T WAIT FOR CONFIRM
JRST ARRL1 ;BR IF RELEASE CMD, DON'T WAIT FOR CONFIRM
MOVEI 2,[FLDDB.(.CMCFM)]
COMND ;WAIT FOR CONFIRMATION
TLNE 1,(CM%NOP) ;CHECK FOR ERRORS
JRST EROUT
ARRL1:
;CHECK THAT SIZE HAS BEEN SPECIFIED
SKIPN SIZE
JRST [PMSGC <?SIZE command must be given first.>
JRST COMAND ]
;CALCULATE FIRST ADDRESS
MOVE ARAYAD ;GET FIRST ARGUMENT
IMUL SIZE ; TIMES SIZE OF PROM
MOVEM FIRST ;STORE IN FIRST
;CALCULATE BYTE POSITION
AOS T1,ARAYBT ;GET FIRST ARGUMENT PLUS ONE
MOVEM T1,BYTE ;STORE IN BYTE
SKIPN RELFLG ;SKIP IF RELEASE
JRST COMAND ;GO GET NEXT COMMAND (IF ARRAY CMD)
;HERE IF RELEASE COMMAND
SUBTTL RELEASE AND OUTPUT COMMAND
OUTPUT: SETOM RELFLG ;SET RELEASE FLG FOR PRINT ROUTINE
SETZM OUTJFN ;CLR OUT THE OUTPUT JFN (WE DON'T HAVE ONE YET)
MOVEI 2,[FLDDB.(.CMTXT,CM%HPP!CM%SDH,,<ROM part # and comment>)]
COMND ;DO THE COMMAND
TLNE 1,(CM%NOP) ;WAS THERE AN ERROR?
JRST EROUT ;HERE IF YES
MOVE S1,.CMABP(1) ;GET THE ATOM BUFFER POINTER
;WE MUST FIRST GET AND CHK THE PART # CLASS (SHOULD BE 23-)
SETZM S3 ;CLR OUT PART CLASS HOLDER S3
MOVE T1,[POINT 7,S3] ;GET POINTER TO S3
ILDB S1 ;GET 1ST BYTE
IDPB T1 ;DEPOSIT IN S3
ILDB S1 ;GET 2ND BYTE
IDPB T1 ;DEPOSIT IN S3
ILDB S1 ;GET 3RD BYTE
IDPB T1 ;DEPOSIT IN S3
CAME S3,[ASCIZ/23-/] ;COMPARE PART CLASS WITH 23
JRST PNBAD ;BR IF NOT CLASS 23
;NOW WE GET THE NEXT 5 OR 6 CHARACTERS UNTIL THE "-" FOR THE FILE NAME
MOVE S4,[POINT 7,OFNAM] ;SET UP POINTER TO FILE NAME
MOVEI S2,6 ;CHARACTER COUNTER
PNLP: ILDB S1 ;GET A BYTE
CAIN "-" ;SKIP IF NOT MINUS
JRST PNDON ;BR IF FILE NAME IS DONE
JUMPE PNDON ;BR IF FILE NAME IS DONE
IDPB S4 ;DEPOSIT THE BYTE
SOJL S2,PNBAD ;BR IF TOO MANY CHARACTERS
JRST PNLP ;BR BACK FOR REST OF NUMBER
PNDON: MOVE S2,[POINT 7,[ASCIZ/.DAT/]] ;POINTER TO FINISH NAME
MOVEI S3,5 ;COUNTER TO FINISH
PNDLP: ILDB S2 ;GET A CHARACTER
IDPB S4 ;PUT IN NAME BUFFER
SOJN S3,PNDLP ;BR BACK TO FINISH NAME
;NOW WE TRY TO GTJFN ON THE GIVEN FILE NAME
;DON'T CLOBBER S1 - IT CONTAINS POINTER TO COMMENT (IF ANY)
MOVSI 1,(GJ%SHT) ;SET UP FOR SHORT GTJFN
HRROI 2,OFNAM ;POINTER TO OUTPUT FILE NAME
GTJFN
ERJMP EROUT ;JUMP IF ERROR
MOVE 2,[^D36B5!13B9!OF%WR] ;WRITE, 36 BIT BYTE, IMAGE BINARY MODE
OPENF ;OPEN THE FILE
ERJMP EROUT ;HERE IF ERROR
MOVEM 1,OUTJFN# ;SAVE THE OUTPUT JFN
;NOW WE FINISH PARSING THE COMMAND LINE FOR COMMENTS
;FIRST WE MUST SKIP OVER THE REST OF THE PART NUMBER GARBAGE (IF ANY)
LDB S1 ;GET THE TERMINATION CHAR
JRST PNGLP1 ;JUMP INTO SEPARATOR LOOP
SETZM COMBUF ;CLR OUT 1ST WORD OF COMMENT BUFFER
PNGLP: ILDB S1 ;GET NEXT CHARACTER
PNGLP1: JUMPE COMNUL ;BR IF THE END, NO COMMENT
CAIN 11 ;IS IT TAB?
JRST OVRSP ;BR IF YES, WE ARE AT SEPARATOR
CAIE 40 ;IS IT SPACE?
JRST PNGLP ;BR IF NO, STILL SKIPPING PART NR
;NOW WE ARE AT TERMINATOR - WE MUST SKIP OVER IT
OVRSP: ILDB S1 ;GET NEXT CHARACTER
JUMPE COMNUL ;BR IF THE END, NO COMMENT
CAIN 11 ;IS IT TAB?
JRST OVRSP ;BR IF YES, KEEP SKIPPING
CAIN 40 ;IS IT SPACE?
JRST OVRSP ;BR IF YES, KEEP SKIPPING
;WE ARE NOW AT THE COMMENT
CMSON: MOVE S2,[POINT 7,COMBUF] ;POINTER TO COMMENT STORAGE
IDPB S2 ;STORE THE FIRST COMMENT CHARACTER
CMSLP: ILDB S1 ;GET A TYPED CHARACTER
IDPB S2 ;PUT IN COMMENT BUFFER
JUMPN CMSLP ;BR IF NOT THE END, KEEP LOADING
COMNUL: PUSHJ P,GENBUF ;GENERATE BUFFER OF DATA
JRST COMAND ;NO SKIP RTN IF NO DATA
SKIPE 1,LSTJFN ;SKIP IF NOT LISTING
JRST LISTIT ;HERE TO LIST (AC1 = JFN)
PNTRTN: MOVEI 377 ;GET INITIAL DATA MARKER
MOVEM ROMBUF-1 ;PUT IMMEDIATELY BEFORE BUFFER
SKIPN BINMOD ;SKIP IF PACKED BINARY MODE
JRST IMMOD ;HERE IF IMAGE - DON'T REPACK
;HERE WE MUST REPACK THE BINARY DATA FOR PDP-11 PACKED MODE
MOVE T1,SNDSIZ ;GET #BYTES
AOS T1 ;MAKE ALLOWANCE FOR 377 START BYTE
MOVE T4,[POINT 8,ROMBUF-1,27] ;GET POINTER TO SOURCE DATA
MOVEI T3,ROMBUF-1 ;GET POINTER TO 1ST WORD
MOVE T2,[-4,,PMBTAB] ;BYTE POINTER TABLE INDEX
SETZM S2 ;CLR OUT BYTE ACCUMULATOR
IMLP: ILDB T4 ;GET A BYTE OF DATA
DPB (T2) ;DEPOSIT BYTE IN S2
AOBJN T2,IMLP1 ;LOOP FOR ALL 4 BYTES
MOVE T2,[-4,,PMBTAB] ;BYTE POINTER TABLE INDEX
MOVEM S2,(T3) ;DEPOSIT DATA
SETZM S2 ;CLR OUT BYTE ACCUMULATOR
AOS T3 ;POINT TO NEXT WORD
IMLP1: SOJG T1,IMLP ;INCR THE INDEX FOR DEPOSIT, LOOP BACK
MOVEM S2,(T3) ;SET UP PARTIALLY FORMED WORD
;(OR 0 IF WE JUST FORMED A WORD)
;NOW WE ACTUALLY OUTPUT THE DATA TO THE FILE
IMMOD: MOVE 1,OUTJFN ;GET THE JFN
MOVE 2,[POINT 8,ROMBUF-1,27] ;START POINTER AT 377 BYTE
SKIPE BINMOD ;SKIP IF IN IMAGE MODE
MOVE 2,[POINT 36,ROMBUF-1] ;FULL WORDS IF IN PACKED MODE
MOVE 3,SNDSIZ ;NEED THIS MANY BYTES
AOS 3 ;PLUS 1 FOR DATA MARKER
SKIPN BINMOD ;SKIP IF PACKED MODE - FUDGE CNT
JRST IMMOD1 ;HERE IF IMAGE
ADDI 3,3 ;ROUND UP IF UNEVEN
LSH 3,-2 ;SHIFT 2 PLACES FOR DIVIDE BY 4
IMMOD1: MOVN 3,3 ;NEGATE THE COUNT
SOUT ;OUTPUT THE DATA
ERJMP EROUT ;HERE IF ERROR
MOVE 1,OUTJFN ;GET THE JFN
CLOSF ;CLOSE THE FILE
ERJMP EROUT ;HERE IF ERROR
SETZM OUTJFN ;THE FILE IS NOW CLOSED
JRST COMAND ;AND DONE
PNBAD: PMSGC <Illegal part number>
JRST COMAND ;AND START OVER
SUBTTL INVERT COMMANDS
;INVERT AND NOINVERT COMMANDS
INVRT: TROA T1,-1 ;SET FLAG
NOINVRT:SETZ T1, ;CLEAR FLAG
MOVEI 2,[FLDDB. (.CMCFM)] ;WAIT FOR CONFIRMATION
COMND
TLNE 1,(CM%NOP) ;CHECK FOR ERROR
JRST EROUT
MOVEM T1,INVERT ;STORE FLAG IN MEMORY
JRST COMAND
SUBTTL IMAGE AND PACKED COMMANDS
PACKED: TROA T1,-1 ;SET FLAG
IMAGE: SETZ T1, ;CLEAR FLAG
MOVEI 2,[FLDDB. (.CMNOI,,<POINT 7,[ASCIZ/binary tape mode/]>)]
COMND ;GIVE GUIDE WORDS
TLNE 1,(CM%NOP) ;CHECK FOR ERROR
JRST EROUT
MOVEI 2,[FLDDB. (.CMCFM)] ;WAIT FOR CONFIRMATION
COMND
TLNE 1,(CM%NOP) ;CHECK FOR ERROR
JRST EROUT
MOVEM T1,BINMOD ;STORE FLAG IN MEMORY
JRST COMAND
SUBTTL AUTHOR COMMAND
AUTHOR: MOVEI 2,[FLDDB.(.CMTXT,CM%HPP!CM%SDH,,<(your name, turkey)>)]
COMND ;DO THE COMMAND
TLNE 1,(CM%NOP) ;WAS THERE AN ERROR?
JRST EROUT ;HERE IF YES
MOVE S1,.CMABP(1) ;GET THE ATOM BUFFER POINTER
MOVE S2,[POINT 7,AUTHST] ;GET POINTER TO AUTHOR STRING
ATHLP: ILDB S1 ;GET A BYTE
IDPB S2 ;PUT IN SAVED AREA
JUMPN ATHLP ;LOOP UNTIL 0 BYTE
JRST COMAND ;AND DONE
SUBTTL COMENT COMMAND
COMENT: MOVEI 2,[FLDDB.(.CMTXT,CM%HPP!CM%SDH,,<(whatever you want)>)]
COMND ;DO THE COMMAND
TLNE 1,(CM%NOP) ;WAS THERE AN ERROR?
JRST EROUT ;HERE IF YES
MOVE S1,.CMABP(1) ;GET THE ATOM BUFFER POINTER
MOVE S2,[POINT 7,COMBUF] ;GET POINTER TO COMMENT STRING
COMLP: ILDB S1 ;GET A BYTE
IDPB S2 ;PUT IN SAVED AREA
JUMPN COMLP ;LOOP UNTIL 0 BYTE
JRST COMAND ;AND DONE
SUBTTL HELP COMMAND
;HELP COMMAND
HELP: MOVEI 2,[FLDDB.(.CMCFM)]
COMND ;GIVE GUIDE WORDS
TLNE 1,(CM%NOP) ;CHECK FOR ERROR
JRST EROUT
MOVSI 1,(GJ%SHT) ;GET A JFN TO HELP FILE
HRROI 2,[ASCIZ/HLP:BLAST.HLP/]
GTJFN
ERJMP EROUT
MOVSI 2,(FLD(7,OF%BSZ)) ;OPEN FILE
HRRI 2,OF%RD ;FOR READING
OPENF
ERJMP EROUT
MOVEM 1,T1 ;SAVE JFN
HLPOUT: MOVE 1,T1 ;GET INPUT FILE JFN
BIN ;READ A BYTE
ERJMP COMAND ;STOP ON ANY ERROR
MOVEI 1,.PRIOU ;SET TERMINAL AS OUTPUT DEVICE
BOUT ;WRITE TO BYTE OUT
JRST HLPOUT
SUBTTL ERROR MESSAGES
;ERROR MESSAGE PRINTER
EROUT: PUSH P,1 ;SAVE AC'S THAT MAY CONTAIN ERROR DATA
PUSH P,2
PUSH P,3
MOVEI 1,.PRIOU ;OUTPUT DESIGNATOR
MOVEI 2,-1 ;PRINT MOST RECENT ERROR
HRLI 2,.FHSLF ;FOR CURRENT PROCESS
MOVEI 3,0 ;NO LIMIT ON MESSAGE SIZE
ERSTR ;PRINT THE MESSAGE
HALTF
HALTF
JRST COMAND
ERQUIT: PUSH P,1 ;SAVE AC'S THAT MAY CONTAIN ERROR DATA
PUSH P,2
PUSH P,3
PMSGC <Cannot Access device BLASTR:>
MOVEI 1,.PRIOU ;OUTPUT DESIGNATOR
MOVEI 2,-1 ;PRINT MOST RECENT ERROR
HRLI 2,.FHSLF ;FOR CURRENT PROCESS
MOVEI 3,0 ;NO LIMIT ON MESSAGE SIZE
ERSTR ;PRINT THE MESSAGE
HALTF
HALTF
HALTF ;EXIT TO MONITOR
JRST START ;RESTART IF CONTINUED
SUBTTL FILE READ ROUTINES
;THE FOLLOWING ARE TWO ROUTINES FOR EACH FILE FORMAT.
;THE FIRST ROUTINE IS CALLED ONCE TO OPEN THE FILE AND
;INITIALIZE FOR THE SECOND ROUTINE.
;THE SECOND ROUTINE IS CALLED FOR EACH DATA BYTE OBTAINABLE
;FROM THE FILE. THIS ROUTINE GIVES A SKIP RETURN WHEN A DATA
;BYTE IS BEING SUPPLIED FROM THE FILE. ON A SKIP RETURN, THE
;8-BIT DATA BYTE MUST BE IN T2 AND THE ADDRESS INTO WHICH
;THIS DATA IS TO BE PLACED MUST BE IN T3.
;THESE ROUTINES MAY ALSO USE THE FOLLOWING ACCUMULATORS:
; 0, 1, 2, 3, 4, S1, S2, S3, S4, S5.
;A BUFFER AREA AT ATOMBF OF SIZE ATOMBS WORDS MAY ALSO
;BE USED.
SUBTTL ROM FILE TYPE READ ROUTINES
;ROM FILE READ ROUTINES
;OPEN FILE FOR INPUT
ROMI: MOVE 1,FILE ;GET JFN
MOVSI 2,(FLD(7,OF%BSZ)) ;BYTE SIZE OF 7
HRRI 2,OF%RD+OF%PLN ;FOR READING
OPENF
ERJMP EROUT
SETOB T3,S3 ;INIT ADDRESS AND END OF LINE FLAG
MOVEI S1,1 ;SET LINE NUMBER TO FIRST LINE
POPJ P, ;RETURN
;READ A DATA BYTE
ROMDAT: SETZB S2,T2 ;CLEAR DIGIT COUNTER AND DATA BYTE
ADDI T3,1 ;INCREMENT ADDRESS
ROMD2: MOVE 1,FILE ;GET JFN
BIN ;READ A CHARACTER FROM FILE
ERJMP ROMDER
JUMPE 2,ROMD2 ;IGNORE NULL CHARACTERS
CAIN 2,15 ;IGNORE CARRIAGE RETURNS
JRST ROMD2
CAIN 2,";" ;CHECK FOR START OF COMMENT
JRST ROMCMT
CAIN 2,"/" ;CHECK FOR SLASH CHARACTER
JRST ROMSLA
CAIN 2,12 ;CHECK FOR LINE FEED
JRST ROMLF
CAIE 2,13 ;CHECK FOR VERTICAL TAB
CAIN 2,14 ; OR FORM FEED
JRST ROMLF ;TREAT AS A LINE FEED
CAIE 2," " ;CHECK FOR A SPACE
CAIN 2," " ; OR A TAB
JRST ROMSEP
CAIL 2,"0" ;CHECK FOR AN OCTAL DIGIT
CAILE 2,"7"
JRST ROMILC ;IF NOT, ILLEGAL CHARACTER
;A DIGIT
LSH T2,3 ;MAKE ROOM FOR DIGIT
ORI T2,-"0"(2) ;SET IN NEW DIGIT
AOJA S2,ROMD2 ;COUNT DIGIT AND GET NEXT CHARACTER
;COMMENT
ROMCMT: MOVE 1,FILE ;GET JFN
BIN ;READ ANOTHER CHARACTER FROM FILE
ERJMP ROMDER
CAIE 2,12 ;LOOK FOR A LINE FEED
JRST ROMCMT ;INPUT UNTIL FIND ONE
JRST ROMLF ;NOW HONOR THE LINE FEED
;SLASH
ROMSLA: JUMPE S2,ROMSLI ;NUMBER INPUT
JUMPE S3,ROMSLI ; AND FIRST NUMBER ON LINE OR ERROR
SETZB S2,S3 ;CLEAR DIGIT COUNTER AND END OF LINE FLAG
MOVE T3,T2 ;COPY NUMBER INPUT TO ADDRESS
SETZ T2, ;CLEAR NUMBER
JRST ROMD2 ;NOW INPUT THE DATA NUMBER
ROMSLI: PMSG <?Error reading input file. "/" not after first number>
JRST ROMERR
;LINE FEED
ROMLF: SETO S3, ;SET END OF LINE FLAG
ADDI S1,1 ;COUNT THE LINE
JUMPE S2,ROMD2 ;KEEP LOOKING FOR NUMBER IN NONE FOUND YET
ROMSND: AOS (P) ;FIVE SKIP RETURN
POPJ P,
;SPACE OR TAB
ROMSEP: JUMPE S2,ROMD2 ;KEEP READING IF NO DIGIT INPUT YET
JUMPE S3,ROMSND ;SEND DATA BYTE IF NOT FIRST DIGIT ON LINE
ROMSAD: MOVE 1,FILE ;GET JFN
BIN ;READ NEXT CHARACTER
ERJMP ROMDER
JUMPE 2,ROMSAD ;IGNORE NULL CHARACTERS
CAIE 2," " ;SPACE
CAIN 2," " ; OR TAB
JRST ROMSAD ;YES, KEEP READING
CAIN 2,"/" ;SLASH?
JRST ROMSLA ;YES, GO HONOR THE SLASH
MOVE 1,FILE ;NOT A SLASH, BACKUP THE FILE POINTER
BKJFN
ERJMP EROUT
JRST ROMSND ;NOW SEND THE NUMBER AS A DATA BYTE
ROMILC: PMSG <?Error reading input file. Illegal charACter ">
MOVE 1,2 ;GET ILLEGAL CHARACTER
PBOUT ;TYPE IT
PMSG <">
ROMERR: PMSG < on line >
MOVEI 1,.PRIOU ;SELECT THE TERMINAL
MOVE 2,S1 ;TYPE LINE NUMBER
MOVEI 3,^D10 ;IN DECIMAL
NOUT
ERJMP EROUT
PMSGC <.>
JRST COMAND
;FILE READ ERROR
ROMDER: GTSTS ;READ FILE STATUS
TLNN 2,(GS%EOF) ;AT END OF FILE?
JRST EROUT ;NO, REPORT ERROR MESSAGE
JUMPN S2,ROMSND ;SEND DATA BYTE IF ANY
POPJ P, ;GIVE NON-SKIP RETURN
SUBTTL A78, DAT, PTP FILE TYPE READ ROUTINES
;INTEL 8080 PAPER TAPE FORMAT READ ROUTINES
;OPEN FILE FOR INPUT
I80I: MOVE 1,FILE ;GET JFN
MOVSI 2,(FLD(7,OF%BSZ)) ;7 BIT BYTES
HRRI 2,OF%RD+OF%PLN ;FOR READING
OPENF ;OPEN FILE
ERJMP EROUT
SETZB S1,S5 ;CLEAR BYTE COUNTER AND LINE COUNTER
POPJ P, ;RETURN
;READ A DATA BYTE FROM FILE
I80DAT: JUMPN S1,I80NXT ;JUMP IF BYTES STILL IN BUFFER
AOJ S5, ;READ A NEW LINE, COUNT THE LINE
MOVE 1,FILE ;GET JFN
HRROI 2,ATOMBF ;READ A LINE INTO ATOM BUFFER
MOVEI 3,ATOMBS*5 ;SIZE OF BUFFER
MOVEI 4,12 ;TERMINATE ON A <LF> CHARACTER
SIN ;READ A STRING
ERJMP EROUT
SUBI 3,ATOMBS*5 ;COMPUTE CHARACTERS READ
MOVMS 3 ;GET MAGNITUDE OF COUNT
MOVE S2,[POINT 7,ATOMBF] ;GET POINTER TO BUFFER
I80NUL: ILDB S2 ;GET FIRST CHARACTER OF STRING
SKIPN ;IF CHARACTER IS NULL
I80SP: SOJA 3,I80NUL ; DECREASE COUNT AND LOOK AT NEXT
CAIN " " ;CHK FOR SPACE
JRST I80SP ;BR IF SPACE, SKIP IT
CAIN 15 ;IF CARRIAGE RETURN
JRST I80DAT ; LINE IS BLANK, GO READ NEXT
CAIE ":" ;CHECK IF A COLON
JRST [PMSG <?Error reading input file. First character not a colon>
JRST I80ERR ]
PUSH P,S2 ;SAVE POINTER
SUBI 3,3 ;COMPUTE NUMBER OF BYTES IN STRING
LSH 3,-1 ;(CHARACTERS READ MINUS COLON AND
; <CR><LF> DIVIDED BY 2)
CAIGE 3,5 ;CHECK IF AT LEAST 5 BYTES
JRST [PMSG <?Error reading input file. Not enough characters>
JRST I80ERR ]
MOVEM 3,S1 ;SAVE COUNT OF BYTES
SETZ S3, ;CLEAR CHECKSUM
I80CHK: PUSHJ P,I80BYT ;READ A BYTE
ADDM T2,S3 ;ADD TO CHECKSUM
SOJG 3,I80CHK ;READ ALL BYTES
ANDI S3,377 ;STRIP OFF ADDITIONAL BITS
JUMPN S3,[PMSG <?Error reading input file. Checksum error>
JRST I80ERR ]
SUBI S1,5 ;COMPUTE NUMBER OF DATA BYTES IN LINE
POP P,S2 ;GET POINTER TO FIRST BYTE IN LINE
PUSHJ P,I80BYT ;READ THE BYTE
JUMPE T2,I80X ;IF # BYTES = 0, WE ARE AT THE END
CAME T2,S1 ;THIS BYTE SHOULD BE SAME AS COMPUTED
;BYTE COUNT
JRST [PMSG <?Error reading input file. Byte counter does not match line length>
JRST I80ERR ]
JUMPE S1,I80X ;IF BYTE COUNT IS ZERO, REPORT EOF
PUSHJ P,I80BYT ;GET HIGH BYTE OF ADDRESS
LSH T2,8 ;POSITION
MOVEM T2,T3 ;PUT INTO T3
PUSHJ P,I80BYT ;GET REST OF ADDRESS
ORM T2,T3 ;PLACE IN T3
PUSHJ P,I80BYT ;GET RECORD TYPE FIELD
JUMPN T2,[PMSG <?Error reading input file. Record type field not zero>
JRST I80ERR ]
JRST I80NB ;GET BYTE
I80NXT: AOJ T3, ;BUMP ADDRESS
I80NB: SOJ S1, ;COUNT THE BYTE
PUSHJ P,I80BYT ;GET A DATA BYTE
AOS (P) ;CAUSE SKIP RETURN
I80X: POPJ P, ;RETURN
;READ A BYTE OF TWO HEX CHARACTERS INTO T2
I80BYT: PUSHJ P,I80CHR ;READ A CHARACTER
LSH 4 ;POSITION
MOVEM T2 ;STORE IN T2
PUSHJ P,I80CHR ;READ NEXT CHARACTER
ORM T2 ;STORE IN T2
POPJ P, ;RETURN
;READ A HEX CHARACTER INTO 0
I80CHR: ILDB S2 ;READ A CHARACTER
CAIL "0" ;IF NOT 0 TO 9
CAILE "9" ; CHECK IF A TO F
SKIPA
JRST I80CHX ;IF 0 TO 9, JUMP AHEAD
CAIL "A" ;IF NOT A TO F
CAILE "F" ;REPORT ERROR
JRST [PMSG <?Error reading input file. Illegal charACter>
JRST I80ERR ]
ADDI 11 ;IF A TO F, FIX LOW 4 BITS
I80CHX: ANDI 17 ;STRIP TO 4 BITS
POPJ P, ;RETURN
;ERROR REPORTER
I80ERR: PMSG < on line >
MOVEI 1,.PRIOU ;OUTPUT TO TERMINAL
MOVE 2,S5 ;LINE NUMBER IN ERROR
MOVEI 3,^D10 ;IN DECIMAL
NOUT
ERJMP EROUT
PMSGC <.>
JRST COMAND ;ABORT AND GO BACK FOR ANOTHER COMMAND
SUBTTL E16, E32 FILE TYPE READ ROUTINES
;E16 AND E32 FORMAT READ ROUTINES
E16I: MOVE T1,BYTE ;GET BYTE PARAMETER
JUMPE T1,NOBYTE ;ERROR IF NO BYTE POSITION SPECIFIED
CAILE T1,2 ;CHECK IF IN CORRECT RANGE
JRST [PMSGC <?Byte position out of range, must be 1 or 2.>
JRST COMAND ]
MOVE T2,[ -2,,0
-2,,-1 ]-1(T1) ;GET BYTE INPUT CONTROL WORD
JRST EII
NOBYTE: PMSGC <?No byte position was specified.>
SKIPN 1,OUTJFN ;SKIP IF DOING OUTPUT
JRST COMAND
HRLI (CZ%ABT) ;ABORT THE FILE
CLOSF ;CLOSE OUT THE OUTPUT FILE
ERJMP EROUT ;HERE IF ERROR
JRST COMAND
E32I: MOVE T1,BYTE ;GET BYTE PARAMETER
JUMPE T1,NOBYTE ;ERROR IF NO BYTE POSITION SPECIFIED
CAILE T1,4 ;CHECK IF IN CORRECT RANGE
JRST [PMSGC <?Byte position out of range, must be between 1 and 4.>
JRST COMAND ]
MOVE T2,[ -4,,-2
-4,,-3
-4,,0
-4,,-1 ]-1(T1) ;GET BYTE INPUT CONTROL WORD
EII: MOVEM T2,BYTECW# ;SAVE BYTE CONTROL WORD
MOVE 1,FILE ;GET JFN OF INPUT FILE
MOVSI 2,(FLD(^D18,OF%BSZ)) ;18 BIT BYTES
HRRI 2,OF%RD+OF%PLN ;FOR READING
OPENF ;OPEN FILE
ERJMP EROUT
SETZ S1, ;CLEAR BYTE COUNTER
POPJ P, ;RETURN
;E16 AND E32 DATA RETRIEVAL ROUTINES
;THESE ROUTINES ARE THE SAME EXCEPT THAT THE READ CONTROL WORD
;SAVED IN BYTECW WILL CAUSE DIFFERENT AMOUNTS OF DATA TO BE READ.
E16DAT:
E32DAT: PUSHJ P,E32BYT ;READ A BYTE - ADDRESS LOW BYTE
POPJ P, ;EOF - GIVE EOF RETURN
MOVEM T3 ;STORE IN ADDRESS RETURN LOCATION
PUSHJ P,E32BYT ;READ REST OF ADDRESS
JRST E32EOF ;UNEXPECTED EOF
LSH 8 ;POSITION TO HIGH BYTE POSITION
ORM T3 ;PUT IN ADDRESS LOCATION
MOVE S5,BYTECW ;GET BYTE CONTROL WORD
E32DLP: PUSHJ P,E32BYT ;READ A DATA BYTE
JRST E32EOF ;UNEXPECTED EOF
TRNN S5,-1 ;CHECK IF THIS IS DESIRED BYTE
MOVEM T2 ;YES, STORE IN DATA LOCATION
AOBJN S5,E32DLP ;READ ALL BYTES FOR THIS LOCATION
AOS (P) ;GIVE SKIP RETURN
POPJ P, ;ADDRESS IS IN T3, DATA BYTE IN T2
E32EOF: PMSGC <?Error reading input file. EOF block found when not expected.>
JRST COMAND
;READ A BYTE FROM AN E16 OR E32 TYPE FILE.
E32BYT: SOJL S1,E32BLK ;IF NO BYTES IN CORE, READ A NEW BLOCK
ILDB S2 ;READ A BYTE
AOS (P) ;CAUSE A SKIP RETURN
POPJ P, ;DATA BYTE IS IN AC 0
;READ A NEW BLOCK FROM THE FILE
E32BLK: SETZB S3,S4 ;CLEAR CHECKSUM AND SECOND BYTE
MOVE S2,[POINT 8,ATOMBF] ;SET UP POINTER TO STORE BYTES
E32BKF: PUSHJ P,E32IBT ;INPUT A BYTE FROM FILE
JUMPE 2,E32BKF ;KEEP INPUTTING UNTIL FIND FIRST BYTE
CAIE 2,1 ;FIRST BYTE MUST BE A 001
JRST [PMSGC <?Error reading input file. Cannot find start of a block.>
JRST COMAND ]
PUSHJ P,E32IBT ;INPUT SECOND BYTE FROM BLOCK
JUMPN 2,[PMSGC <?Error reading input file. Second byte of block is not zero.>
JRST COMAND ]
PUSHJ P,E32IBT ;READ FIRST BYTE OF BYTE COUNTER
MOVEM 2,S1 ;BUILD BYTE COUNTER IN S1
PUSHJ P,E32IBT ;READ REST OF BYTE COUNTER
LSH 2,8 ;POSITION
ORM 2,S1 ;BUILD BYTE COUNTER
CAILE S1,ATOMBS*4 ;CHECK IF BYTES WILL FIT IN ATOM BUFFER
JRST [PMSGC <?Error reading input file. Byte count from file is greater than buffer size.>
JRST COMAND ]
MOVEM S1,EBYTSV# ;SAVE BYTE COUNTER
SUBI S1,3 ;SUBTRACT 3 FROM COUNT TO COMPUTE
;NUMBER OF BYTES REMAINING TO BE READ
;FROM FILE INCLUDING CHECKSUM
E32BKR: PUSHJ P,E32IBT ;INPUT A BYTE FROM FILE
IDPB 2,S2 ;PUT BYTE IN MEMORY BUFFER
SOJG S1,E32BKR ;READ REST OF BLOCK FROM FILE
ANDI S3,377 ;CLEAR OVERFLOW FROM ADDITION
JUMPN S3,[PMSGC <?Error reading input file. Checksum error.>
JRST COMAND ]
MOVE S2,[POINT 8,ATOMBF] ;GET POINTER TO START OF BUFFER
ILDB S1,S2 ;GET BLOCK TYPE FIELD
ILDB 2,S2 ;TWO BYTES
LSH 2,8
ORM 2,S1 ;BUILD 16 BIT FIELD
CAIN S1,6 ;CHECK IF EOF BLOCK
POPJ P, ;YES, GIVE EOF RETURN
CAIE S1,3 ;CHECK IF A DATA BLOCK
JRST E32BLK ;NO, GO READ NEXT BLOCK
ILDB 2,S2 ;READ ADDRESS FIELD OF BLOCK
ILDB 2,S2 ;AND THROW AWAY
MOVE S1,EBYTSV ;GET SAVED BYTE COUNTER FROM BLOCK
SUBI S1,8 ;ADJUST TO NUMBER OF DATA BYTES
JUMPG S1,E32BYT ;NOW GET FIRST DATA BYTE
PMSGC <?Error reading input file. Data block found with no data.>
JRST COMAND
;INPUT A BYTE FROM E16 AND E32 TYPE FILES.
;BYTE IS READ AS AN 18 BIT CHUNK. THE FIRST BYTE IS RIGHT JUSTIFIED.
E32IBT: JUMPN S4,E32NBT ;JUMP IF BYTE IN S4 (SECOND BYTE FROM 18)
MOVE 1,FILE ;GET JFN
BIN ;READ AN 18 BIT CHUNK FROM FILE
ERJMP EROUT
HRROM 2,S4 ;SAVE SECOND BYTE IN S4
ANDI 2,377 ;CLEAR SECOND BYTE
JRST E32CKB
E32NBT: LDB 2,[POINT 8,S4,27] ;GET SECOND BYTE FROM S4
SETZ S4, ;CLEAR SECOND BYTE STORAGE
E32CKB: ADDM 2,S3 ;ADD BYTE TO CHECKSUM
POPJ P, ;RETURN WITH BYTE IN 2
SUBTTL R16, R28 FILE TYPE READ ROUTINES
;R16 AND R28 FORMAT READ ROUTINES
R16I: MOVE T1,BYTE ;GET BYTE PARAMETER
JUMPE T1,NOBYTE ;ERROR IF NO BYTE POSITION SPECIFIED
CAILE T1,4 ;CHECK IF IN CORRECT RANGE
JRST [PMSGC <?Byte position out of range, must be between 1 and 4.>
JRST COMAND]
SETZM R1628F# ;CLEAR CONTROL FLAG
JRST RII
R28I: MOVE T1,BYTE ;GET BYTE PARAMETER
JUMPE T1,NOBYTE ;ERROR IF NO BYTE POSITION SPECIFIED
CAILE T1,7 ;CHECK IF IN CORRECT RANGE
JRST [PMSGC <?Byte position out of range, must be between 1 and 7.>
JRST COMAND]
SETOM R1628F ;SET CONTROL FLAG
RII: MOVE 1,FILE ;GET JFN OF INPUT FILE
MOVSI 2,(FLD(^D36,OF%BSZ)) ;36 BIT BYTES
HRRI 2,OF%RD+OF%PLN ;FOR READING
OPENF ;OPEN FILE
ERJMP EROUT
MOVEI S5,400 ;GET COUNT OF LEADING BYTES TO IGNORE
RIGNOR: PUSHJ P,R28IN ;READ A BYTE
JRST [PMSGC <?Error reading input file. EOF before first data byte.>
JRST COMAND]
SOJG S5,RIGNOR ;READ ALL LEADING BYTES
SETOM T3 ;SET START ADDRESS TO -1 SO IT CAN
;INCREMENT TO ZERO
POPJ P, ;RETURN
;R16 AND R28 DATA RETRIEVAL ROUTINES
;THESE ROUTINES ARE THE SAME EXCEPT FOR WHERE THE HIGH ORDER TWO
;BITS OF BYTE NUMBER 4 ARE FOUND. R1628F IS USED AS A CONTROL FLAG
;TO GET THESE BITS.
R16DAT:
R28DAT: PUSHJ P,R28IN ;READ NEXT WORD FROM FILE
POPJ P, ;EOF - GIVE NON-SKIP RETURN
SKIPN R1628F ;SKIP IF R28 TYPE
JRST RR16
LDB [POINT 2,2,35] ;GET HIGH ORDER TWO BITS OF BYTE 4
DPB [POINT 2,2,3] ;PLACE IN POSITION AS IN R16 TYPE
RR16: MOVE S2,BYTE ;GET BYTE NUMBER
LDB T2,[POINT 4,2,17
POINT 4,2,13
POINT 4,2,9
POINT 4,2,5
POINT 4,2,33
POINT 4,2,29
POINT 4,2,25 ]-1(S2) ;GET 4 BIT BYTE
AOJ T3, ;INCREMENT ADDRESS IN T3
AOS (P) ;GIVE SUCCESSFUL RETURN
POPJ P,
R28DER: PMSGC <?Error reading input file. EOF in the middle of a four byte group.>
JRST COMAND
;READ A WORD FROM THE FILE
R28IN: MOVE 1,FILE ;GET JFN
BIN ;READ A 36-BIT WORD
ERJMP R28INE ;JUMP IF ANY ERROR
AOS (P) ;CAUSE SKIP RETURN
POPJ P,
R28INE: GTSTS ;GET FILE STATUS
TLNN 2,(GS%EOF) ;CHECK IF FOUND END OF FILE
JRST EROUT ;NO, REPORT ERROR
POPJ P, ;YES, GIVE NON-SKIP RETURN
SUBTTL TAP DATA RETRIEVAL ROUTINES
UTPI: SETOM HDRFLG ;INDICATE HDR GARBAGE TO SKIP
JRST TPCOM ;USE COMMON CODE
TAPI: SETZM HDRFLG ;INDICATE NO HEADER GARBAGE, 377 IS DATA MRK
TPCOM: MOVE 1,FILE ;GET FILE JFN
MOVSI 2,(FLD(^D18,OF%BSZ)) ;18 BIT BYTES
HRRI 2,OF%RD+OF%PLN ;FOR READING
OPENF ;OPEN FILE
ERJMP EROUT
SETZM TAPFLG ;SET UP BYTE ALTERNATION FLG
;THE FOLLOWING LOOP SEARCHES FOR THE -1 MARKER
SKIPN HDRFLG ;SKIP TO DO HDR CHECK
JRST TAPIGN ;JRST HERE IF JUST WAIT FOR 377 CHAR
;IF HERE, WE MUST SKIP OVER THE GOOFIE HEADER FORMAT. WE MUST GO UNTIL
;WE SEE A TRIANGLE AND THEN WAIT FOR THE 377 CODE
PUSH P,S5 ;SAVE A REG
UTPRST: MOVE S5,HDNDX ;GET POINTER TO HEADER END CODE
UTPAGN: PUSHJ P,TAPDAT ;READ A BYTE
JRST [PMSGC <?Error reading input file. EOF before all 1's marker seen.>
JRST COMAND]
CAMN T2,(S5) ;DOES IT LOOK LIKE NEXT CHAR OF TRIANGLE?
AOBJN S5,UTPAGN ;INCR INDEX IF YES TO NEXT REQD CHAR, JMP BACK
JUMPL S5,UTPRST ;LOOP BACK IF ALL PATTERNS NOT SEEN YET
POP P,S5 ;RESTORE THE REG
TAPIGN: PUSHJ P,TAPDAT ;READ A BYTE
JRST [PMSGC <?Error reading input file. EOF before all 1's marker seen.>
JRST COMAND]
CAIE T2,377 ;CHK FOR ALL 1'S (SKIP IF TRUE)
JRST TAPIGN ;IF NOT ALL 1'S LOOP BACK UNTIL TRUE
ITS2ND: SETOM T3 ;INIT NEXT BYTE AS FIRST BYTE OF DATA
POPJ P, ;RETURN
;THIS ROUTINE ACTUALLY READS A BYTE OF DATA FROM THE FILE
TAPDAT: SKIPE TAPFLG# ;CHK FLG TO DECIDE WHETHER NEED A BIN
JRST NOBIN ;BR IF DON'T NEED IT
MOVE 1,FILE ;GET FILE JFN
BIN
ERJMP TAPER ;BR IF ERROR
SKIPN BINMOD ;SKIP IF PACKED BINARY MODE
JRST TAPPAK ;JUMP HERE IF IMAGE MODE
MOVEM 2,SAVTAP# ;SAVE DATA FOR LATER
TRZ 2,777400 ;SAVE ONLY 8 BITS
JRST BINRTN
NOBIN: LDB 2,[POINT 8,SAVTAP,27] ;GET 8 BITS OF 2ND BYTE
BINRTN: SETCMM TAPFLG ;COMPL THE FLAG
BINPRT: AOS T3 ;NEXT ADDRESS
AOS (P) ;DO THE SKIP RTN
MOVE T2,2 ;MOVE DATA TO T2
POPJ P, ;AND RTN
TAPPAK: BIN ;DO NOTHER BIN FOR JUST RIGHT HALF WORD
ERJMP TAPER ;IMAGE (ONLY RIGHTMOST 8 BITS USED PER WORD)
TRZ 2,777400 ;CLR OUT ALL OTHER BITS
JRST BINPRT ;NOW RTN THE DATA
TAPER: GTSTS ;GET FILE STATUS
TLNN 2,(GS%EOF) ;CHK FOR EOF
JRST EROUT ;BR IF ERROR
POPJ P, ;HERE IF JUST EOF. DON'T SKIP RTN
SUBTTL VARIABLE STORAGE
;PROGRAM VARIABLES
;OPERATING PARAMETERS
FIRST: 0 ;FIRST ADDRESS TO SEND
LAST: 0 ;LAST ADDRESS TO SEND (0=NOT SPECIFIED)
SIZE: 0 ;SIZE OF PROM (0=NOT SPECIFIED)
BYTE: 0 ;BYTE POSITION (0=NOT SPECIFIED)
FILE: 0 ;JFN OF FILE (0=NO FILE SELECTED)
TYPE: 0 ;INDEX OF FILE TYPE
CHECK: 0 ;CHECK MODE FLAG (0=OFF, -1=ON)
RADIX: ^D10 ;INPUT RADIX FOR FIRST AND LAST COMMAND
FILL: 0 ;FILL CHARACTER FOR NULL ADDRESSES
BLASTR: 0 ;JFN TO BLASTR:
HDRFLG: 0 ;0 NO HDR (TAP), -1 HDR (UTP)
;BUFFERS
OFNAM: BLOCK 3 ;STORAGE FOR OUTPUT FILE NAME
CMDBFS=^D20
CMDBUF: BLOCK CMDBFS ;COMMAND TEXT BUFFER
ATOMBS=^D20
ATOMBF: BLOCK ATOMBS ;ATOM BUFFER
AUTHST: ASCIZ/(no name given)/ ;AUTHOR'S NAME STORAGE
BLOCK ATOMBS ;NEED AT LEAST AS MUCH AS ATOMBF SIZE
JFNBF: BLOCK 16 ;FILENAME INPUT BUFFER
PROMSZ=^D1024*2
XWD 0 ;MUST HAVE A WORD HERE FOR OUTPUT ROUTINE
ROMBUF: BLOCK <PROMSZ/4>+2 ;PROM DATA BUFFER PLUS COUPLE OF EXTRA WDS
;(NEEDED NEAR COMNUL)
TEMPBF: BLOCK 8
COMBUF: BLOCK ATOMBS ;ROOM FOR COMMENT
PATCH: BLOCK 100 ;PATCH AREA
HDNDX: -^D8,,HDDAT ;# DATA PATTERNS FOR END OF HEADER MARKER
HDDAT: 1 ;THIS TABLE IS THE LIST OF CODES IN UTP MODE
3 ;TO TELL BLAST WHERE THE END OF HEADER IS.
7 ;AFTER THIS CODE, YOU THEN SEARCH FOR THE NEXT
17 ;377 DATA CHAR AND THE NEXT CHAR IS THE 1ST
37 ;CHAR OF DATA
77
177
377
PLIST: -100,,PLISTS-1 ;STACK POINTER
PLISTS: BLOCK 100 ;STACK
SUBTTL TABLE STORAGE
;TABLE OF COMMANDS FOR INPUT BY COMND CALL
F1: ^D23,,^D23 ;NUMBER OF ENTRIES
[ASCIZ/ARRAY/],,ARRAY
[ASCIZ/AUTHOR/],,AUTHOR
[ASCIZ/BYTE/],,BYTEC
[ASCIZ/CLOSE/],,CLOSE
[ASCIZ/COMMENT/],,COMENT
[ASCIZ/DECIMAL/],,DECIML
[ASCIZ/EXIT/],,EXIT
[ASCIZ/FILE/],,FILENM
[ASCIZ/FIRST/],,FIRSTC
[ASCIZ/HELP/],,HELP
[ASCIZ/IMAGE/],,IMAGE
[ASCIZ/INVERT/],,INVRT
[ASCIZ/LAST/],,LASTC
[ASCIZ/NOINVERT/],,NOINVRT
[ASCIZ/NULL/],,NULL
[ASCIZ/OCTAL/],,OCTAL
[ASCIZ/OPEN/],,OPEN
[ASCIZ/OUTPUT/],,OUTPUT
[ASCIZ/PACKED/],,PACKED
[ASCIZ/PRINT/],,PRINT
[ASCIZ/RELEASE/],,RELEAS
[ASCIZ/SEND/],,SEND
[ASCIZ/SIZE/],,SIZEC
;TABLE OF RECOGNIZED TYPE FIELDS
TYPFLD: ^D10,,^D10 ;NUMBER OF ENTRIES
[ASCIZ/A78/],,[I80I,,I80DAT]
[ASCIZ/DAT/],,[I80I,,I80DAT]
[ASCIZ/E16/],,[E16I,,E16DAT]
[ASCIZ/E32/],,[E32I,,E32DAT]
[ASCIZ/PTP/],,[I80I,,I80DAT]
[ASCIZ/R16/],,[R16I,,R16DAT]
[ASCIZ/R28/],,[R28I,,R28DAT]
[ASCIZ/ROM/],,[ROMI,,ROMDAT]
[ASCIZ/TAP/],,[TAPI,,TAPDAT]
[ASCIZ/UTP/],,[UTPI,,TAPDAT]
;TABLE OF SIZES IN K
KSIZE: 2,,2
[ASCIZ/1K/],,^D1024*1
[ASCIZ/2K/],,^D1024*2
PMBTAB: POINT 8,S2,17 ;1ST BYTE
POINT 8,S2,9 ;2ND BYTE
POINT 8,S2,35 ;3RD BYTE
POINT 8,S2,27 ;4TH BYTE
END START