;******************** HEXCOM.MAC *********************** TITLE HEXCOM .HEX FILE TO .COM FILE ; Bruce Tanner - Cerritos College 7/22/83 T1=1 T2=2 T3=3 T4=4 I=5 O=6 PC=7 CNT=10 CHK=11 PTR=12 P=17 COM==1 HEX==2 START: RESET RESCAN ;RESCAN THE COMMAND LINE FOR "HEXCOM FOO" MOVE T2,[POINT 6,HEXFIL] LSPACE: INCHWL T1 CAIN T1,40 JRST LSPACE SKIPA RDCHAR: INCHWL T1 CAIN T1,15 ;NO ARG SUPPLIED JRST ASK CAIE T1,40 CAIN T1,11 JRST RDNAME JRST RDCHAR ASK: INCHWL T1 ;EAT LF OUTSTR [ASCIZ/File name: /] RDNAME: INCHWL T1 CAIN T1,"." ;EXT? JRST RDEXT CAIL T1,140 SUBI T1,40 ;LC TO UC SUBI T1,40 ;ASCII TO SIXBIT JUMPLE T1,OPNFIL ;CONTROL CHAR IDPB T1,T2 ;STICK IT JRST RDNAME RDEXT: MOVE T2,[POINT 6,HEXFIL+1] JRST RDNAME OPNFIL: CLRBFI MOVE T1,HEXFIL ;OUTPUT FILE IS SAME AS INPUT FILE MOVEM T1,COMFIL MOVSI T1,'COM' ;BUT WITH A .COM EXT MOVEM T1,COMFIL+1 MOVSI T1,'HEX' SKIPN HEXFIL+1 ;.HEX BY DEFAULT MOVEM T1,HEXFIL+1 OPEN HEX,HEXSPC ;OPEN THE FILES HALT OPEN COM,COMSPC HALT LOOKUP HEX,HEXFIL JRST NOFILE ENTER COM,COMFIL JRST BADFIL MOVSI T1,(POINT 8,0) ;.COM FILE IS 8 BIT BYTES MOVEM T1,OBUF+1 MOVE P,[IOWD 20,STACK] MOVEI PC,400 ;ALL .COM FILES START AT 100H LOOP: PUSHJ P,INCH ;READ SOME BYTES JRST FINI CAIE I,":" ;SEARCH FOR RECORD HEADER JRST LOOP SETZ CHK, ;RESET CHECKSUM PUSHJ P,HEXBYT ;READ BYTE MOVEM T1,CNT ;SAVE BYTE COUNT JUMPE CNT,FINI ;ZERO RECORD SIZE MEANS EOF PUSHJ P,HEXBYT ;GET HIGH BYTE MOVE T4,T1 LSH T4,10 PUSHJ P,HEXBYT ;GET LOW BYTE OR T4,T1 ;PC IN T4 PUSHJ P,HEXBYT ;GET RECORD TYPE SKIPE T1 ;TYPE 0 (CODE)? JRST FINI ;MUST BE TYPE 1 (EOF) OR MORE (ILLEGAL) CAMLE PC,T4 ;OVERLAP PC? JRST OVRLAP ;YES LOOP1: CAMN PC,T4 ;AT RIGHT PC? JRST DODATA ;YES SETZ O, ;GAP IN HEX FILE PUSHJ P,OUCH ;WILL BE FILLED WITH ZEROS AOJ PC, JRST LOOP1 DODATA: PUSHJ P,HEXBYT ;GET A BYTE MOVE O,T1 PUSHJ P,OUCH ;WRITE A BYTE AOJ PC, SOJG CNT,DODATA ;LOOP PUSHJ P,HEXBYT ;READ CHECKSUM ANDI CHK,377 ;MASK 8 BITS JUMPE CHK,LOOP ;CHECKSUM CORRECT, DO ANOTHER RECORD OUTSTR [ASCIZ/Bad checksum at PC /] PUSHJ P,PRNTPC FINI: RELEAS HEX, RELEAS COM, EXIT OVRLAP: OUTSTR [ASCIZ/Code overlap /] JRST FINI EOF: OUTSTR [ASCIZ/Encountered EOF inside a record /] JRST FINI HEXBYT: PUSHJ P,NYBBLE MOVE T1,I LSH T1,4 ;SHIFT TO HIGH NYBBLE PUSHJ P,NYBBLE OR T1,I ADD CHK,T1 ;UPDATE CHECKSUM POPJ P, NYBBLE: PUSHJ P,INCH ;GET HEX DIGIT JRST EOF ;SHOULD ONLY GET EOF OUTSIDE OF RECORD SUBI I,"0" ;TO BINARY CAIL I,^D10 ;SKIP IF NUMERIC SUBI I,"A"-"9"-1 ;ELSE MAKE 10 THRU 15 POPJ P, PRNTPC: MOVE T1,PC PUSHJ P,DOBYTE MOVE T1,PC LSH T1,-10 DOBYTE: PUSH P,T1 ADD CHK,T1 ;UPDATE CHECKSUM LSH T1,-4 ;HIGH NYBBLE PUSHJ P,DONYBB POP P,T1 DONYBB: ANDI T1,17 ;JUST 4 BITS MOVE O,T1 CAIL O,^D10 ;IF NUMERIC JRST .+3 ADDI O,"0" ;JUST MAKE ASCII JRST OUCH ;AND OUTPUT ADDI O,"A"-^D10 ;ELSE MAKE A THRU F OUCH: SOSGE OBUF+2 ;OUTPUT A CHAR IN O JRST OUCH1 IDPB O,OBUF+1 POPJ P, OUCH1: OUTPUT COM, JRST OUCH INCH: SOSGE IBUF+2 ;INPUT A CHAR IN I JRST INCH1 ILDB I,IBUF+1 AOS (P) POPJ P, INCH1: IN HEX, JRST INCH POPJ P, NOFILE: OUTSTR [ASCIZ/?File not found /] EXIT BADFIL: OUTSTR [ASCIZ/?Enter error /] EXIT HEXSPC: 0 SIXBIT /DSK/ IBUF COMSPC: 14 SIXBIT /DSK/ OBUF,,0 COMFIL: 0 0 0 0 HEXFIL: EXP 0,0,0,0 IBUF: BLOCK 3 OBUF: BLOCK 3 BUFFER: BLOCK 50 STACK: BLOCK 20 END START