************************************* * * * I M P R O S * * VERSION 1.2 11/09/79 * * IMAGE PROCESSING SYSTEM * * COPYRIGHT 1979 * * VECTOR GRAPHIC, INCORPORATED * * BY C.A. SELBY * * EXCEPT WHERE NOTED * * * ************************************* * ORG 0100H * * LDA @INIFLG ;INITIALIZED YET? CPI 0A5H JZ PROMPT LXI H,BANMSG ;PRINT BANNER CALL PRINTCR PROMPT CALL CRLF ;PRINT CRLF AND PROMPT CHAR MVI A,'<' CALL PTCN CALL CONSDVR ;GET NEW CMD LINE IN CMD BFR LXI H,CMDTBL ;POINT TO CMD TABLE FOR SCAN LXI D,CMDBFR ;POINT TO START OF CMD LINE CALL SKIPSPC JC PROMPT CALL SCAN ;SCAN LINE FOR FIRST CMD JC INVCMD ;AND IF NOT FOUND, PRINT CMD ERR MSG PCHL * * CONSDVR LXI D,CMDBFR MVI B,0 ;CLR CHR CNTR CONSLOOP CALL CNTLC ;WAIT FOR INPUT JZ CONSLOOP CPI BAKSPC JNZ STOIT MOV C,A MOV A,B ;CHECK TO SEE IF AT ANA A ;BEGINNING OF CMDBFR MOV A,C JZ CONSLOOP ;IF YES, IGNORE DCX D ;IF NO, BACK UP BFR PTR DCR B ;DEC CHR CNTR CALL PTCN JMP CONSLOOP STOIT CPI 0DH ;CARR. RETURN? JZ STOCHR ;IF YES, SKIP LINEFULL CHECK MOV C,A ;CHECK IF LINE IS FULL MOV A,B SUI LINLENGTH-1 JNC CONSLOOP ;IF FULL, DON'T STORE CHAR MOV A,C STOCHR STAX D ;STORE CHAR CALL PTCN INR B ;INCREMENT CHAR COUNT CPI 0DH ;CARRIAGE RETURN? RZ ;IF YES, EXIT TO CALLER INX D ;ELSE POINT TO NEXT CHAR POSITION JMP CONSLOOP ;AND WAIT FOR NEXT CHAR * * * OUT16 MOV A,M ;PRINT HIGH BYTE CALL BYTOUT DCX H MOV A,M ;PRINT LOW BYTE CALL BYTOUT JMP CRLF * * * * EXECCMD CALL ARGSEARCH ;GET JMP ADDRESS IF VALID JC INVARG CALL HEXMEM JC INVARG PCHL GO TO IT * * PGRMCMD CALL ARGSEARCH ;GET PROGRAMMING ADDRESS CALL HEXMEM JC INVARG ADJADR MOV A,L ;FORCE EVEN ADDRESS ANI 0FEH MOV L,A SHLD DISPADR ;SAVE DISPLAY ADDRESS MOV A,H ;GET H LS NYBBLE ANI 0FH MOV B,A ;SAVE FOR NOW MVI A,0F0H ;GET H MS NYBBLE ANA H MOV H,B RARR H ;SHIFT LOW 12 BITS RIGHT RARR L ORA H ;COMBINE 12 LOW SHIFTED BITS WITH UNADJUSTED 4 HI BITS MOV H,A PGRMLOOP PUSH H ;SAVE REAL MEMORY ADDRESS LHLD DISPADR CALL ADROUT ;PRINT ADDRESS POP H MOV A,M CALL BYTOUT ;PRINT CONTENTS OF THAT ADDRESS PUSH H ;POINT TO ODD BYTE LXI D,SIZE ;PROM SIZE OFFSET DAD D MOV A,M CALL BYTOUT ;PRINT CONTENTS OF ODD BYTE POP H MVI A,'-' CALL PTCN ;PRINT A DASH AFTER BYTE PGRMIN CALL KEYHEX ;GET HEX BYTE JC NXTADR ;JUST GO TO NEXT ADDRESS IF NO VALID DATA DEPOSIT MOV M,D ;STORE NEW DATA AT ADDRESS PUSH H ;POINT TO ODD BYTE PUSH D LXI D,SIZE DAD D POP D MOV M,E ;STORE ODD BYTE POP H * NXTADR CPI BAKSPC ;BACKSPACE? JZ DCRADR ;IF YES, DECREMENT MEM ADDR CPI ' ' ;IF SPACE, JUST GOTO NEXT ADDRESS JZ INRADR CPI 3 ;CNTL C? JZ PROMPT ;IF YES, EXIT TO EXECUTIVE CPI 'N' ;NEW ADDRESS? JNZ PGRMIN ;IF NOT, WAIT FOR MORE DATA NEWADDR CALL KEYHEX ;GET NEW ADDRESS JC NEWADDR ;RETRY IF DATA NOT VALID CPI 3 ;ABORT? JZ PROMPT CPI ' ' ;DEPOSIT ADDRESS? JNZ NEWADDR ;IF NOT, TRY FOR ADDRESS UNTIL SOMETHING VALID XCHG ;PUT ADDRESS IN HL JMP ADJADR DCRADR DCX H ;DECREMENT REAL MEMORY ADDRESS PUSH H LHLD DISPADR ;GET DISPLAY ADDRESS DCX H ;DECREMENT IT DCX H SHLD DISPADR ;UPDATE DISPLAY ADDRESS POP H JMP PGRMLOOP INRADR INX H ;INCREMENT REAL MEMORY ADDRESS PUSH H LHLD DISPADR ;GET DISPLAY ADDRESS INX H ;INCREMENT IT INX H SHLD DISPADR ;UPDATE DISPLAY ADDRESS POP H JMP PGRMLOOP * * LOADCMD CALL ARGSEARCH ;SEARCH FOR START ADDRESS ENTRY JC INVARG CALL HEXMEM JC INVARG MOV A,L ;FORCE EVEN ANI 0FEH MOV L,A SHLD @SRCSTRT CALL ARGSEARCH ;SEARCH FOR SOURCE ENDING ADDRESS JC INVARG CALL HEXMEM JC INVARG MOV A,L ;FORCE EVEN ANI 0FEH MOV L,A SHLD @SRCEND CALL ARGSEARCH ;SEARCH FOR DESTINATION ADDRESS JC INVARG CALL HEXMEM JC INVARG MOV A,L ;FORCE EVEN ANI 0FEH MOV L,A SHLD @DEST LHLD @SRCEND ;DETERMINE NUMBER OF WORDS TO BE MOVED LDED @SRCSTRT ANA A ;CLR CARRY DSBC D ;START-END=COUNT PUSH H ;PUT RESULT IN B POP B LDED @DEST ;DESTINATION ADDRESS IN D SRLR B ;DIVIDE COUNT BY 2 RARR C ;BECAUSE WE WILL MOVE 2 BYTES PER PASS CALL CRLF ;PRINT LENGTH MESSAGE LXI H,LENGTHMSG CALL PRINT MOV A,B CALL BYTOUT MOV A,C CALL BYTOUT LHLD @SRCSTRT ;SOURCE ADDRESS IN H MOVEIT MOV A,M ;GET EVEN BYTE STAX D ;MOVE TO EVEN (MSB) DEST. INX H ;POINT TO ODD SOURCE PUSH D PUSH H LXI H,SIZE ;POINT TO ODD (LSB) DEST DAD D XCHG ;ODD DEST IN D POP H ;ODD SOURCE IN H MOV A,M STAX D POP D INX H ;POINT TO NEXT EVEN SOURCE INX D ;POINT TO NEXT EVEN DEST. DCX B ;DECREMENT AND TEST COUNT MOV A,B ORA C JRNZ MOVEIT JMP PROMPT ;DONE * LENGTHMSG DTZ 'LENGTH= ' * * PRGPROMCMD CALL GETARGS ;GET START, END AND OPTIONAL PROM ADDRESSES CPI 2 ;WERE AT LEAST 2 ARGS ENTERED? JC INVARG ;IF NOT, ERROR LHLD ARG1 ;GET SOURCE START ADDRESS SHLD @SRCSTRT ;PUT IN @SRCSTART PUSH D ;SAVE COMMAND INPUT BUFFER POINTER XCHG LHLD ARG2 ;GET SOURCE ENDING ADDRESS INX H ;ADD 1 TO IT TO ALLOW PROGRAMMING ONLY 1 LOCATION ANA A DSBC D ;END-STRT=COUNT POP D ;RESTORE INPUT BUFFER POINTER IN CASE ERROR JC INVARG ;START>END? IF YES, ERROR JZ INVARG SHLD @SRCEND ;PUT COUNT AT @SRCEND PUSH D ;SAVE INPUT BUFFER POINTER LXI D,1024+1 ;CHECK COUNT TO ENSURE IT IS ANA A ;LESS THAN OR EQUAL TO THE MAXIMUM PROM SIZE (1024 FOR 2708) DSBC D POP D ;REGAIN BUFFER POINTER IN CASE OF ERROR JNC INVARG CPI 3 ;WAS A THIRD ARGUMENT ENTERED? JC GETDEFADDR ;IF NOT, GET DEFAULT ADDRESS LHLD ARG3 ;GET ENTERED ADDRESS SHLD @DEST ;PUT IN @DEST JMP BLNKTST ;GO CHECK IF PROM AREA IS BLANK * GETDEFADDR LXI H,DEFPROMADDR ;SET @DEST TO DEFAULT PROM ADDRESS SHLD @DEST BLNKTST CALL GETPROMPARMS ;GET SETUP REGISTERS FOR BLANK TEST, IE SRC,DST,COUNT BLNKTSTLOOP LDAX D ;GET A BYTE FROM PROM CPI 0FFH ;=FFH? JNZ NOTBLANK ;IF NOT, EXIT HERE AND LOG ERROR MSG INX D ;POINT TO NEXT BYTE DCX B ;DECREMENT COUNT MOV A,B ORA C ;COUNT = 0? JNZ BLNKTSTLOOP ;IF NOT, GO REPEAT ABOVE JMP PROMPRG ;TEST OK, GO PROGRAM PROM * NOTBLANK LXI H,BLANKMSG ;INFORM USER THAT TARGET PROM AREA IS NOT BLANK CALL PRINTCR CALL RDCN ;WAIT FOR USER RESPONSE CPI 'Y' ;IF (Y)ES, CONTINUE JNZ PROMPT ;OTHERWISE ABORT PROMPRG XRA A ;CLEAR PASSCOUNTER STA @PASSCOUNT CALL CRLF ;GO TO NEW LINE ON CONSOLE PROMPASSLOOP CALL GETPROMPARMS ;GET START, COUNT, DEST ADDRESSES XRA A ;CLEAR ERROR FLG STA ERRFLG PROMPRGLOOP MOV A,M ;GET A BYTE TO PROGRAM STAX D ;WRITE TO PROM LDAX D ;TRY TO READ IT BACK SUB M ;COMPARE IT WITH WHAT IT JUST WROTE PUSH B ;OR IN RESULT WITH ERRFLG MOV B,A LDA ERRFLG ORA B STA ERRFLG ;IF ANY ERRORS OCCUR IN THIS PASS, ERRFLG WILL BE >0 POP B INX H ;POINT TO NEXT SOURCE, DEST INX D DCX B ;DECREMENT COUNT MOV A,B ORA C ;TEST IF ZERO JNZ PROMPRGLOOP ;IF NOT, DO ANOTHER BYTE LXI H,PASSMSG ;PRINT PASS COUNT MESSAGE CALL PRINT LXI H,@PASSCOUNT MOV A,M ;GET AND PRINT ACTUAL PASS COUNT CALL BYTOUT LDA ERRFLG ;IF ANY ERRORS OCCURRED DURING THE LAST PASS ANA A ;PRINT A PERIOD AFTER THE PASS NUMBER ON THE CONSOLE MVI A,'.' CNZ PTCN CALL CRLF ;GO TO NEW LINE ON CONSOLE MOV A,M ;GET PASS COUNT INR A ;INCREMENT IT MOV M,A JNZ PROMPASSLOOP ;IF IT OVERFLOWS TO ZERO, JMP PROMPT ;PROGRAMMING DONE * * GETPROMPARMS LHLD @DEST ;GET PROM START ADDRESS XCHG ;PUT IN DE LHLD @SRCEND ;GET NUMBER OF BYTES TO PROGRAM MOV B,H ;PUT IN BC MOV C,L LHLD @SRCSTRT ;GET SOURCE STARTING ADDRESS RET * * PASSMSG DTZ 'PASS ' BLANKMSG DTZ 'SPECIFIED PROM AREA NOT BLANK - CONTINUE? (Y) OR (N) ' * * * * ***************************************** * * * COMMAND LOOKUP TABLE * * FORMAT: * * FIRST BYTE=NUMBER OF LETTERS IN * * COMMAND * * SECOND THRU N BYTES=COMMAND STRING * * N+1= FIRST 16 BIT PARAMETER (USUAL- * * LY ADDRESS FOR THAT PARTICULAR * * COMMAND * * N+3= SECOND 16 BIT PARAMETER * * (USUALLY USED AS AN UPPER * * LIMIT PARAMETER) * * N+5= THIRD AND FINAL PARM USED * * AS LOWER LIMIT PARAMETER * * TABLE TERMINATION OCCURS WHEN THE * * FIRST BYTE IS EQUAL TO 0 * ***************************************** * * CMDTBL DB 4 ;EXEC COMMAND DT 'EXEC' DW EXECCMD DW 0 DW 0 * DB 3 ;DOS CMD DT 'DOS' DW 0 ;CP/M WARM BOOT DW 0 DW 0 * DB 4 ;PROGRAM MEM CMD DT 'PRGM' DW PGRMCMD DW 0 DW 0 * DB 4 ;LOAD FROM 8 BIT MEMORY TO 16 BIT MEMORY DT 'LOAD' DW LOADCMD DW 0 DW 0 * DB 8 ;PROGRAM PROM CMD DT 'PROGPROM' DW PRGPROMCMD DW 0 DW 0 * DB 0 ;END TABLE * ************************************ * ROUTINE: GETARGS * * THIS ROUTINE TAKES UP TO 8 * * 4 DIGIT ASCII NUMERICAL * * ARGUMENTS, CONVERTS THEM TO HEX. * * AND PLACES THEM AT ARG1,2...8. * * CALLING SEQUENCE: * * (DE)=ASCII BUFFER POINTER. * * ON RETURN, A AND NARGS = NUMBER * * OF ARGUMENTS ACTUALLY ACQUIRED * * ALSO, IF NO ARGS WERE FOUND, * * THE Z FLAG WILL BE SET * * (DE) POINTS TO FIRST NON NUMERIC * * CHARACTER IN THE STRING * * REGISTERS B,C,H,L NOT ALTERED * ************************************ * * GETARGS PUSH H ;SAVE H MVI A,0 ;INITIALIZE NARGS STA NARGS LXI H,ARG1 ;POINT ARGPTR TO ARG1 FOR STARTS SHLD ARGPTR GETARGLOOP CALL ARGSEARCH ;SKIP OVER SPACES JC GETARGEXIT ;IF NO ARGS FOUND, EXIT CALL HEXMEM ;GET AN ARG JC GETARGEXIT ;EXIT HERE IF NON NUMERICAL PUSH D XCHG ;MOVE ARG TO DE LHLD ARGPTR MOV M,E ;PUT ARG IN ARGn INX H MOV M,D INX H POP D SHLD ARGPTR ;SAVE UPDATED ARGPTR LDA NARGS ;INCREMENT AND TEST ARG COUNTER INR A STA NARGS CPI MAXNARGS ;TEST IF MAXIMIMUM NUMBER OF ARGS HAVE BEEN ACQUIRED JC GETARGLOOP ;IF NOT, TRY TO GET ANOTHER ONE GETARGEXIT LDA NARGS ANA A ;SET OR RESET THE Z FLAG AS APPROPRIATE POP H RET * * * * ************************************ * ROUTINE: HEXMEM * * THIS ROUTINE TAKES UP TO 4 ASCII * * NUMERICAL CHARACTERS AND CONVERTS* * THEM TO HEXADECIMAL * * CALLING SEQUENCE: * * (DE)=ASCII BUFFER POINTER * * ON RETURN, HL=HEX RESULT, RIGHT * * JUSTIFIED. (DE)=FIRST NON-NUMER- * * ICAL CHAR ENCOUNTERED * * ROUTINE TERMINATES ON ANY NON- * * NUMERIC CHAR. IF NO NUM. CHARS. * * WERE FOUND, CARRY IS SET * * REGISTERS B AND C NOT ALTERED * ************************************ HEXMEM LXI H,0 ;CLR H LDAX D ;GET A CHAR FROM CMDBFR CALL ASCHEX ;CONVERT T0 HEX RC ;IF NOT VALID, RETURN W/ERROR FLG SET ASCLOOP INX D ;POINT TO NEXT LDAX D CALL ASCHEX JNC ASCLOOP ANA A ;CLR ERR FLG RET * * ************************************ * ROUTINE: KEYHEX * * SAVE AS HEXMEM EXCEPT INPUT IS * * DIRECTLY FROM KEYBOARD * * CALLING SEQUENCE:NONE * * REGISTERS B,C,H,L NOT ALTERED * ************************************ * KEYHEX XCHG ;SAVE H IN D LXI H,0 ;CLR H CALL INWAIT ;WAIT FOR INPUT CALL ASCHEX ;CONVERT TO HEX XCHG ;RESTORE H AND D RC ;RETURN IF FIRST CHAR INVALID XCHG KEYLOOP CALL NYBOUT ;PRINT NEWLY AQUIRED NYBBLE CALL INWAIT ;WAIT FOR MORE INPUT CALL ASCHEX JNC KEYLOOP XCHG CMC ;CLR CARRY RET ;DONE * * INWAIT CALL CNTLC ;POLL KEYBD JZ INWAIT RET * * ************************************ * ROUTINE: ASCHEX * * CONVERTS BYTE IN A FROM ASCII TO * * HEXADECIMAL (IF NUMERICAL) * * ON RETURN: * * IF A WAS NUMERICAL, THE HEX * * EQUIVALENT REPLACES THE ORIGINAL * * CONTENTS OF A AND THE NUMBER IS * * ALSO RIGHT SHIFTED INTO HL. * * IF A WAS NOT NUMERICAL, A IS * * UNCHANGED AS IS HL AND THE * * ROUTINE RETURNS WITH THE CARRY * * FLAG SET * * REGISTERS B,C,D,E NOT ALTERED * ************************************ * * ASCHEX PUSH PSW ;SAVE INCOMING CHAR IN CASE INVALID SUI 30H ;CONVERT ASCII TO 1 HEX NYB JC NOTHEX ;AND IF VALID, SHIFT IT IN TO HL CPI 0AH ;IF NOT, RETURN ILLEGAL CHAR JC NUMERIC ;IN REG. A AND RETURN W/CARRY SET SUI 7 CPI 0AH JC NOTHEX CPI 10H CMC JC NOTHEX NUMERIC DAD H ;SHIFT LEFT 4 DAD H DAD H DAD H ORA L MOV L,A INX SP ;DUMMY POP INX SP RET ;DONE * NOTHEX POP PSW ;GET ILLEGAL CHAR IN A STC ;SET CARRY RET ;RETURN * ************************************** * SCAN ROUTINE * * CALLING SEQUENCE: * * HL POINTS TO COMMAND TABLE * * DE POINTS TO INPUT COMMAND BUFFER * * * * ON RETURN: * * DE POINTS TO LAST VALID CHARACTER * * OF COMMAND IN COMMMAND BUFFER * * HL CONTAINS PARM 1 * * @CMDPTR POINTS AT PARM 2 * * * * IF ROUTINE RETURNS TO CALLER * * WITH CARRY SET, COMMAND ENTERED * * WAS NOT FOUND. * * ROUTINE TERMINATES ON A CARRIAGE * * RETURN * * ALL REGISTERS ALTERED * ************************************** * * SCAN SHLD @CMDPTR ;SAVE COMMAND TABLE POINTER MOV B,M ;GET CMD SIZE PUSH D ;SAVE CMD BUFFER POINTER CMDLOOP INX H COMPLOOP LDAX D ;SEARCH FOR CMD ENTRY IN CMD TABLE CPI 0DH ;CARRIAGE RETURN? JZ ERREXIT ;IF YES, TAKE ERROR EXIT CMP M JNZ NXTCMD ;EXIT LOOP ON DISCREPANCY INX D ;ELSE POINT TO NEXT CHAR. INX H DCR B ;ENTIRE COMMAND SCANNED? JNZ COMPLOOP ;IF NOT, GO TO COMPLOOP FNDIT POP B ;DUMMY POP PUSH D ;SAVE CURRENT CMD. BFR. POINTER MOV E,M ;COMMAND FOUND INX H ;NOW GET JUMP ADDRESS IN DE MOV D,M INX H ;POINT TO NEXT PARM SHLD @CMDPTR ;AND SAVE POINTER XCHG POP D ;RESTORE CMD BFR PTR ANA A ;CLR ERROR FLAG RET * NXTCMD POP D ;POINT TO NEXT CMD IN PUSH D ;CMD TABLE LHLD @CMDPTR ;AND CHECK TO SEE IF MOV A,M ;CMD TABLE IS EXHAUSTED ADI 7 ;ADD THE 7 BYTES FOR STRING LENGTH & THE 3 PARM WORDS MVI B,0 ;TO THE NUMBER OF CHARS IN THE STRING MOV C,A DAD B SHLD @CMDPTR ;SAVE NEW CMDPTR MOV A,M ;CHECK IF CMDSIZE IS ANA A ;0, IF YES, CMD TBL EXHAUSTED MOV B,A ;IF NOT, GO TO CMDLOOP JNZ CMDLOOP ERREXIT POP D STC RET * *********************************** * ROUTINE: SKIPSPC * * SEARCHES CMD BUFFER FOR NON * * OCCURENCE OF SPACES. IF NOTHING * * IS FOUND EXCEPT A CARR. RET * * IT RETURNS W/CARRY SET * * CALLING SEQUENCE: * * DE POINTS TO CMDBFR * * REGS. B,C,H,L NOT ALTERED * *********************************** * SKIPSPC LDAX D ;DELETE LEADING SPACES CPI 20H ;SPACE? JNZ TERMFND INX D JMP SKIPSPC * TERMFND CPI 0DH ;NON-SPACE CHAR=CR? STC ;SET ERR FLG IN CASE RZ ;RETURN ON ERROR ANA A ;ELSE CLR ERR FLG RET ;DONE * * ************************************ * ROUTINE: SAVARG * * GETS ASCII ARG FROM CMDBFR, CON- * * VERTS IT TO HEX, CHECKS IF IT IS * * WITHIN THE BOUNDARIES SPECIFIED * * IN THE COMMAND TABLE USED BY THE * * SCAN ROUTINE, AND IF IT IS IT * * STORES IT AT THE LOCATION POINTED* * TO BY (HL) * * CALLING SEQUENCE: * * (DE)=ASCII ARGUMENT IN CMDBFR * * (HL)=ARGUMENT TARGET ADDRESS * * IT RETURNS W/CARRY SET IF ARG. * * IS INVALID OR OUT OF BOUNDS * * REGISTERS B AND C NOT ALTERED * ************************************ SAVARG CALL GETNTST ;GET PARM AND CHECK IF VALID JC INVARG LDA @NEWPARM ;GET NEW PARM MOV M,A INX H LDA @NEWPARM+1 MOV M,A RET * ************************************ * ROUTINE: GETNTST * * GETS ASCII NUM ARGS FROM CMD BFR * * CONVERTS TO HEX, CHECKS IF IN * * BOUNDS * * CALLING SEQUENCE: * * (DE)=POINTS TO ASCII NUM. ARG IN * * CMD BFR * * ON RETURN, DE POINTS TO FIRST NON* * NUMERICAL CHAR, NEW HEX ARG IS * * STORED IN @NEWPARM IN PBLK * * REGARDLESS OF VALIDITY * * CARRY SET IF ARG NOT VALID * * REGISTERS B,C,H,L NOT ALTERED * ************************************ * GETNTST PUSH H ;SAVE PARM ADDRESS CALL HEXMEM ;GET HEX DATA JNC NOERR POP H ;RESTORE PARM ADDRESS STC ;NO, RETURN TO CALLER RET CHKTERM CPI ' ' ;TERMINATE W/SPACE OR CR? JZ NOERR CPI 0DH JZ NOERR STC ;NO, GARBAGE INPUT POP H RET NOERR SHLD @NEWPARM ;SAVE NEWLY AQUIRED PARM CALL COMP16 ;IS IT BELOW MAX? JNC TSTMIN POP H RET TSTMIN CALL COMP16 ;TEST IF ABOVE MIN CMC POP H RET * * CSEARCH PUSH B ;SEARCH FOR CHAR IN REG A MOV C,A CLOOP LDAX D CMP C JZ CFOUND CPI 0DH ;CR INSREAD? JZ NOTFOUND INX D JMP CLOOP NOTFOUND STC ;SET END OF LINE FLAG CFOUND POP B RET * * COMP16 PUSH B ;COMPARE NEW PARM WITH PUSH H ;PARM MAX OR MIN VALUES LHLD @CMDPTR MOV C,M INX H MOV B,M INX H SHLD @CMDPTR LHLD @NEWPARM CALL CHGSINBC ;NEWPARM - PARM LIMIT DAD B POP H POP B RET * * CHGSINBC PUSH PSW ;TWO'S COMPLEMENT BC MOV A,C CMA MOV C,A MOV A,B CMA MOV B,A INX B POP PSW RET * * MULTIPLICATION ROUTINE * B=MULTIPLIER, * E=MULTIPLICAND * ON RETURN, DE=PRODUCT * MLTPLY PUSH H LXI H,0 MVI D,0 MPY DAD D DCR B JNZ MPY XCHG POP H RET * * ************************************ * ROUTINE: ARGSEARCH * * IT SEARCHES CMD LINE FOR FIRST * * OCCURENCE OF A SPACE AND THEN * * SEARCHES FOR NEXT NON-OCCURRENCE * * OF A SPACE. IT TERMINATES ON A * * CARRIAGE RETURN, ALSO, IN WHICH * * CASE CARRY IS SET, INDICATING * * NO ARGUMENT WAS FOUND * * CALLING SEQUENCE: * * DE POINTS TO COMMAND BUFFER * * ON RETURN, DE POINTS TO FIRST * * CHAR OF ARGUMENT- NUMERICAL OR * * ALPHA * * REGISTERS B,C,H,L NOT ALTERED * ************************************ ARGSEARCH MVI A,' ' ;CHECK IF ANY MORE ARGS CALL CSEARCH ;ON CURRENT CMD LINE RC JMP SKIPSPC * * INVCMD LXI H,CMDMSG ;PRINT CMD ERR MSG, PROMPT, RET CALL CRLF JMP PREXIT INVPARM LXI H,PARMSG ;PRINT PARM ERR MSG, JMP REPRINT ;PRINT OFFENDING PARM, RETURN INVARG LXI H,ARGMSG ;PRINT ERR MSG, REPRINT CALL CRLF ;PRINT OFFENDING ARG, PROMPT CALL PRINTCR LDAX D ;LAST CHAR CR? CPI 0DH JZ STOQUES INX D STOQUES MVI A,'?' ;PRINT ? AFTER OFFENDING CHAR STAX D ;IN CMD LINE XRA A INX D STAX D LXI H,CMDBFR ;POINT TO CMDBFR PREXIT LXI B,PROMPT ;PRINT LINE AND RETURN TO PUSH B ;PROMPT INSTEAD OF HERE * PRINTCR LXI B,CRLF ;PRINT CR AFTER LINE PUSH B PRINT MOV A,M ANA A RZ CPI 0DH JZ CRLF ;PRINT CRLF AND RETURN CALL PTCN INX H JMP PRINT * * ADROUT CALL CRLF ;PRINT CONTENTS OF H, AND A COLON CALL WORDOUT PUSH PSW MVI A,':' ;PRINT COLON CALL PTCN POP PSW JMP SPCE * WORDOUT PUSH PSW MOV A,H CALL BYTOUT ;PRINT H FIRST MOV A,L CALL BYTOUT ;THEN L POP PSW RET * BYTOUT PUSH PSW RAR ;SHIFT HIGH NYBBLE TO LOW NYBBLE RAR RAR RAR CALL NYBOUT ;PRINT IT POP PSW ;NOW PRINT LOW * NYBOUT PUSH PSW ANI 0FH ;MASK HI NYBBLE ADI 30H ;ASCII BIAS CPI 3AH ;ALPHA? JNC ALPHA CALL PTCN ;NO POP PSW RET ALPHA ADI 7 ;NOW MAKE 3AH=41H=A IN ASCII CALL PTCN POP PSW RET * NPAUSEDMP CALL DUMPMEM ;DUMP MEMORY W/NO PAUSE POLLING RZ JMP NPAUSEDMP * PAUSEDMP CALL DUMPMEM ;DUMP MEMORY WITH PAUSE POLLING RZ CALL PAUSE JMP PAUSEDMP * DUMPMEM PUSH D ;DUMP MEMORY STARTING AT (HL) MVI D,16 ;THE NUMBER OF BYTES DUMPED IS IN BC CALL ADROUT LOCLOOP MOV A,M CALL BYTOUT CALL SPCE INX H DCR D DCX B MOV A,B ;DONE YET? ORA C JZ TERMEXIT ;IF DONE, SET ZERO FLAG AND RETURN MOV A,D ;CHECK IF ONE LINE DUMPED ANA A JNZ LOCLOOP ORA B ;NOT DONE. CLR ZERO FLG AND RETURN ORA C ;TO CALLER ANYWAY IN CASE PAUSE IS REQUESTED TERMEXIT POP D RET * * * *********************** * * * FDOS FUNCTION CODES * * * *********************** * * SYSRESET EQU 0 ;SYSTEM RESET FUNCTION CONSINPUT EQU 1 ;CONSOLE INPUT FUNCTION CONSOUTPT EQU 2 ;CONSOLE OUTPUT READIN EQU 3 ;READER INPUT PUNOUT EQU 4 ;PUNCH OUT LSTOUT EQU 5 ;LIST OUTPUT DIRIO EQU 6 ;DIRECT CONSOLE I/O GETIO EQU 7 ;GET I/O BYTE SETIO EQU 8 ;SET I/O BYTE PTSTNG EQU 9 ;PRINT STRING RDCONSBFR EQU 10 ;READ CONSOLE BUFFER CONSSTS EQU 11 ;GET CONSOLE STATUS VERSION EQU 12 ;GET VERSION NUMBER RESDISK EQU 13 ;RESET DISK SYSTEM SELDISK EQU 14 ;SELECT DISK OPFILE EQU 15 ;OPEN FILE CLFILE EQU 16 ;CLOSE FILE SCHFIRST EQU 17 ;SEARCH FOR FIRST NAME MATCH IN DIR SCHNEXT EQU 18 ;SEARCH FOR NEXT NAME MATCH IN DIR DELFILE EQU 19 ;DELETE FILE RDSEQ EQU 20 ;READ SEQUENTIAL WRSEQ EQU 21 ;WRITE SEQUENTIAL CRFILE EQU 22 ;CREATE FILE RENFILE EQU 23 ;RENAME FILE RETLOG EQU 24 ;RETURN LOGIN VECTOR RETDISK EQU 25 ;RETURN CURRENT DISK SETDMA EQU 26 ;SET DMA ADDRESS GETALLOC EQU 27 ;GET ADDRESS ALLOCATION WRPROT EQU 28 ;WRITE PROTECT DISK GETRO EQU 29 ;GET READ ONLY VECTOR SETATTR EQU 30 ;SET FILE ATTRIBUTES GETPARMS EQU 31 ;GET DISK PARMS SETGET EQU 32 ;SET/GET USER CODE RDRNDM EQU 33 ;READ RANDOM WRRNDM EQU 34 ;WRITE RANDOM COMPSIZE EQU 35 ;COMPUTE FILE SIZE SETRNDM EQU 36 ;SET RANDOM RECORD * * FDOS EQU 0005H ;FDOS ENTRY POINT * * ********************** * * * CP/M I/O * * INTERFACE * * * ********************** * * CNTLC PUSH H ;SAVE REGS PUSH D PUSH B MVI C,DIRIO ;SET FUNCTION MVI E,0FFH ;SET MODE (IN) CALL FDOS ;GET CONSOLE STATUS/DATA ANA A ;SET FLAGS EXIT POP B ;RESTORE REGS POP D POP H RET * PAUSE CALL CNTLC ;GET KEYBOARD INPUT IF ANY RZ ;EXIT IF NONE CPI 20H ;SPACE? RNZ SPCHLD CALL CNTLC ;SPACE ENTERED, WAIT FOR ANOTHER JZ SPCHLD CPI 20H RZ ;EXIT WHEN THIS OCCURS JMP SPCHLD * RDCN CALL CNTLC ;WAIT FOR A CHAR FROM KEYBD JZ RDCN * PTCN PUSH H ;PRINT THE CHAR. IN THE A REGISTER PUSH D PUSH B PUSH AF MVI C,DIRIO ;SET FUNCTION FOR FDOS MOV E,A ;CHAR TO BE SENT IN A CALL FDOS ;PRINT IT POP AF JMP EXIT * CRLF MVI A,0DH ;SEND CARRIAGE RETURN/LINE FEED TO CONSOLE CALL PTCN MVI A,0AH JMP PTCN * SPCE MVI A,20H ;SEND SPACE TO CONSOLE JMP PTCN * * * CMDMSG DTZ 'INVALID COMMAND' PARMSG DTZ 'INVALID PARAMETER' ARGMSG DTZ 'INVALID ARGUMENT' * * BANMSG DB 4 ;CLEAR SCREEN FIRST DTZ 'IMAGE PROCESSING SYSTEM - IMPROS - VERSION 1.1' DTZ 'COPYRIGHT 1979 BY VECTOR GRAPHIC, INC.' * * * PARAMETER STORAGE AREA * * * SYSGEN PARAMETERS * * BAKSPC EQU 8 LINLENGTH EQU 132 SIZE EQU 1024 MAXNARGS EQU 8 ;MAXIMUM NUMBER OF ARGUMENTS ACQUIRED BY GETARGS DEFPROMADDR EQU 0EC00H ;DEFAULT PROM STARTING ADDRESS FOR PROGPROM COMMAND * INIFLG DB 0A5H * BOTTOM EQU $ PRT 'BOTTOM=',BOTTOM @INIFLG DB 0 ;INITIALIZED RAM FLAG * * SCRATCHPAD AREA FOR RUNCMD AND SCAN SUBROUTINE * * @CMDPTR DW 0 ;CMD OR PARM TABLE POINTER STORAGE DISPADR DW 0 ;FAKE MEMORY ADDRESS POINTER @NEWPARM DW 0 ;NEW HEX PARM STORAGE LOC @SRCSTRT DW 0 ;SOURCE START ADDRESS STORE @SRCEND DW 0 ;SOURCE END ADDRESS STORE @DEST DW 0 ;DESTINATION STARTING ADDRESS @PASSCOUNT DB 0 ;NUMBER OF PROGRAMMING PASSES FOR PROGPROM COMMAND NARGS DB 0 ;NUMBER OF ARGUMENTS ACQUIRED BY GETARGS ROUTINE ERRFLG DB 0 ;VERIFICATION ERROR FLAG FOR PROGPROM COMMAND ARGPTR DW 0 ;ARGUMENT POINTER FOR SAME ARG1 DW 0 ;ARGUMENT STORAGE LOCATIONS ARG2 DW 0 ARG3 DW 0 ARG4 DW 0 ARG5 DW 0 ARG6 DW 0 ARG7 DW 0 ARG8 DW 0 * * * CMDBFR FILL LINLENGTH+1,0 ;INPUT COMMAND BUFFER * * * *