REV EQU 16H ; 06/13/79 R. CURTISS NO ERR ON REWIND CLOSED FILE ;REV EQU 15H ; 06/10/79 R. CURTISS DREV, C, ICNTL ;REV EQU 14H ; 05/31/79 R. CURTISS FIX LF, MORE, XDEVC, GBPDEV ;REV EQU 13H ; 05/30/79 R. CURTISS XDEVC FIX, PATCH SPACE ;REV EQU 12H ; 05/29/79 R. CURTISS IWRT5,MCHOFF ;REV EQU 11H ; 05/29/79 R. CURTISS MORE,FPRS,FNAME ;REV EQU 10H ; 05/29/79 R. CURTISS NEW VERSION ; ; STAGE2 MAIN PROGRAM AND I/O OPERATION PACKAGE ; ; REVISION B02 03/15/78 R. CURTISS ADD COMMENTS ; MAIN EQU 100H PROGR EQU 1000H ORG MAIN JMP F4IO ; MAIN ENTRY POINT - PROGRAM STARTUP DB REV ; IOOP REVISION JMP IOOP ; ENTRY POINT - I/O PACKAGE DB DREV ; DISK I/O REVISION JMP TRAP ; ENTRY POINT - END OF MACROS DETECTED NOP JMP MEMSET ; ENTRY POINT - SET UP FLUB MEMORY BOUNDS NOP PROGRM: JMP PROGR ; EXTERNAL REFERENCE - STAGE2, FLT1, FLT2 NOP EXIT: JMP 0000H ; EXTERNAL REFERENCE - RETURN TO CP/M NOP ; ; ------------------------------------- ; ; MAIN PROGRAM ; DS 38H ; STACK SPACE F4IO: LXI SP,F4IO ; CALL INIT CALL PROGRM ; ; CLOSE ALL CHANNELS ; CALL GCLOSE CALL EXIT JMP F4IO ; ; -------------------------------------- ; ; INITIALIZE CHANNEL I/O TABLE ; INIT: MVI B,6*MAXCH LXI D,CHAN LXI H,JCHAN+1 ; INIT1: LDAX D MOV M,A INX D INX H DCR B JNZ INIT1 ; CALL FINIT ; GET FILES FROM COMMAND LINE RET ; ; ----------------------------------------- ; ; INITIAL VALUES FOR CHANNEL CONTROL TABLE ; CHAN: ; R W O C U S DB 1,0,1,1,2,1 ; CHANNEL 1 - INPUT FILE DB 1,1,1,1,1,1 ; CHANNEL 2 - SCRATCH FILE DB 0,1,1,1,2,1 ; CHANNEL 3 - OUTPUT FILE DB 0,1,1,1,3,1 ; CHANNEL 4 - LISTING FILE DB 1,1,0,0,2,4 ; CHANNEL 5 - CONSOLE I/O ; MAXCH EQU ($-CHAN)/6 ; ; ; R KCH+1 READ ACCESS ; 0 - ILLEGAL ; 1 - CHANNEL AVAILABLE FOR READ ; ; W KCH+2 WRITE ACCESS ; 0 - ILLEGAL ; 1 - MACHINE READABLE OUTPUT ; 2 - HUMAN READABLE OUTPUT ; 3 - FIRST LINE OF HUMAN READABLE OUTPUT ; ALLOWS TOP OF FORM ; ; O KCH+3 OPEN ACCESS ; 0 - NO ACTION REQUIRED ; 1 - OPEN REQUIRED ; ; C KCH+4 CONTROL ACCESS (CLOSE) ; 0 - NO ACTION REQUIRED ; 1 - CLOSE REQUIRED ; ; U KCH+5 DEVICE CODE ; 0 - NULL DEVICE ; 1 - DISK ; 2 - CONSOLE ; 3 - LIST DEVICE ; ; S KCH+6 CHANNEL STATUS ; 0 - NOT AVAILABLE ; 1 - CLOSED ; 2 - OPEN FOR READ ; 3 - OPEN FOR WRITE ; 5 - END OF FILE ON READ ; END OF MEDIUM ON WRITE ; ; ------------------------------------- ; TRAP: NOP ; TRAP AT END OF MACRO READING NOP RET ; ; -------------------------------------- ; ; SET FLUB MEMORY BOUNDS ; DE LOW LIMIT ; HL HIGH LIMIT ; MEMSET: LHLD 0006H ; GET BDOS ENTRY ADDRESS DCR H ; ONE PAGE LESS TO BE SAFE RET ; ; ---------------------------------------- ; ; I/O SUPERVISOR ; ; OPERATION CODE ; 0 - CLOSE ; 1 - WRITE ; -1 - READ ; ; OPERATION STATUS ; 0 - NORMAL ; 1 - EOF OR END OF MEDIUM ; 2 - ILLEGAL OPERATION ; 3+ ERROR CODE ; ; STATUS = IOOP ( OPERATION , CHANNEL , BUFFER ) ; (A) (B) (HL) ; ; MAXLEN: DB N ; LENGTH: DS 1 ; BUFFER: DS N+1 ; ; READ OPERATION ; REGISTER BEFORE AFTER ; A -1 STATUS ; B CHANNEL ; HL START OF LINE ; BUFFER MAXLEN LENGTH ; LINE DATA ; ; WRITE OPERATION ; REGISTER BEFORE AFTER ; A 1 STATUS ; B CHANNEL ; HL START OF LINE ; BUFFER LENGTH ; LINE DATA ; ; CLOSE/REWIND OPERATION ; REGISTER BEFORE AFTER ; A 0 STATUS ; B CHANNEL ; IOOP: STA JOP ; SAVE OPERATION CODE SHLD POINT ; SAVE BUFFER POINTER MOV A,B STA NCHAN ; SAVE CHANNEL NUMBER ORA A ; TEST CHANNEL NUMBER JM LL7 ; JUMP IF < 0 ERROR CONDITION JZ LL5 ; JUMP IF = 0 NULL CHANNEL BIT BUCKET ; CPI MAXCH+1 JP LL7 ; JUMP IF CHANNEL > MAX CHANNEL ; CALL MCHOFF ; MAKE CHANNEL OFFSET XCHG SHLD CHOFF ; CHANNEL OFFSET XCHG ; LXI H,JCHAN+6 ; STATUS = JCHAN(KCH+6) DAD D MOV A,M ORA A JZ LL7 ; JUMP IF STATUS = UNAVAILABLE ; MOV B,A ; SAVE CHANNEL STATUS LDA JOP ORA A JM LL10 ; JUMP IF READ OPERATION JNZ LL20 ; JUMP IF WRITE OPERATION ; ; ------------------------------------- ; ; CONTROL OPERATION ; MOV A,B ; GET CHANNEL STATUS CPI 1 JZ LL4 ; JUMP IF STATUS = CLOSED ; LXI H,JCHAN+4 DAD D MOV A,M ; CONTROL ACCESS = JCHAN(KCH+4) ; ORA A JZ LL3 ; JUMP IF CONTROL OPERATION UNAVAILABLE ; PUSH D ; SAVE KCH CALL ICNTL ; PERFORM CONTROL OPERATION POP D ; RESTORE KCH RET ; LL3: LXI H,JCHAN+6 ; SET CHANNEL STATUS TO INACTIVE DAD D MVI M,1 ; JCHAN(KCH+6) = 1 ; LL4: ; NORMAL TERMINATION XRA A ; SET OPERATION STATUS TO ZERO RET ; LL5: ; NULL CHANNEL I/O LDA JOP ORA A JP LL4 ; JUMP IF NOT READ OPERATION ; LL6: MVI A,1 ; EOF STATUS OR END OF MEDIUM RET ; LL7: MVI A,2 ; ILLEGAL OPERATION STATUS RET ; ; --------------------------------- ; ; READ OPERATION ; LL10: MOV A,B ; GET CHANNEL STATUS DCR A JZ LL11 ; JUMP IF CLOSED DCR A JZ LL12 ; JUMP IF OPEN FOR READ DCR A JZ LL7 ; JUMP IF OPEN FOR WRITE ERROR DCR A JZ LL12 ; JUMP IF OPEN FOR BOTH READ AND WRITE DCR A JZ LL6 ; JUMP IF END OF FILE JMP LL7 ; ERROR ; LL11: LXI H,JCHAN+1 DAD D MOV A,M ; GET READ ACCESS PERMISSION ; ORA A JZ LL7 ; JUMP IF READING NOT ALLOWED ; LXI H,JCHAN+6 DAD D MVI M,2 ; SET CHANNEL STATUS OPEN FOR READ ; LXI H,JCHAN+3 DAD D MOV A,M ; GET OPEN ACCESS FOR CHANNEL ORA A JZ LL12 ; JUMP IF OPEN NOT REQUIRED ; PUSH D ; SAVE KCH LXI B,IACCE ; READ ACCESS CALL IOPEN POP D ORA A RNZ ; RETURN IF OPEN ERROR ; LL12: PUSH D ; SAVE KCH CALL IREAD ; PERFORM READ OPERATION POP D JMP LL30 ; ; ------------------------------------- ; ; WRITE OPERATION ; LL20: MOV A,B ; GET CHANNEL STATUS DCR A JZ LL21 ; JUMP IF CLOSED DCR A JZ LL7 ; JUMP IF OPEN FOR READ DCR A JZ LL22 ; JUMP IF OPEN FOR WRITE DCR A JZ LL22 ; JUMP IF OPEN FOR READ OR WRITE DCR A JZ LL6 ; JUMP IF AT END OF MEDIUM JMP LL7 ; ERROR ; LL21: LXI H,JCHAN+2 DAD D MOV A,M ; GET WRITE ACCESS ORA A JZ LL7 ; JUMP IF WRITING NOT POSSIBLE ; LXI H,JCHAN+6 DAD D MVI M,3 ; SET CHANNEL OPEN FOR WRITE ; LXI H,JCHAN+3 DAD D MOV A,M ; GET OPEN ACCESS ORA A JZ LL22 ; JUMP IF NO OPEN REQUIRED ; PUSH D ; SAVE KCH LXI B,OACCE ; WRITE ACCESS CALL IOPEN POP D ORA A RNZ ; RETURN IF OPEN ERROR ; LL22: PUSH D ; SAVE KCH CALL IWRIT ; PERFORM WRITE OPERATION POP D ; ; LL30: CPI 1 RNZ ; RETURN IF NOT EOF OR EOM ; LXI H,JCHAN+6 DAD D MVI M,5 ; SET STATUS TO EOF OR EOM RET ; ; -------------------------------------- ; ; BUFFER READ ROUTINE ; IREAD: CALL GBPDEV ; HL = BUFFER POINTER ORA A ; A = DEVICE CODE JZ IRED0 ; JUMP IF 0 - NULL DCR A JZ IRED1 ; JUMP IF 1 - DISK DCR A JZ IRED2 ; JUMP IF 2 - CONSOLE IN IRED0: MVI A,1 ; END OF FILE OR ERROR CONDITION RET ; ; IRED1: PUSH H DCX H SHLD ARGLST+2 ; SET LENGTH POINTER DCX H SHLD ARGLST ; SET MAX LENGTH POINTER CALL GFTAB ; HL = FILE TABLE POINTER POP D ; DE = BUFFER POINTER LXI B,ARGLST CALL LREAD ; READ LINE ORA A RZ ; RETURN IF NO ERROR OR EOF IREOF: CALL MORE ; CHECK FOR CHAN 1 MULTIPLE INPUTS JZ IREAD ; JUMP IF ANOTHER INPUT FILE RET ARGLST: DW 0 ; MAX LINE LENGTH POINTER DW 0 ; ACTUAL LINE LENGTH POINTER ; ; GET LINE FROM CONSOLE ; IRED2: XCHG DCX D DCX D CALL CIB ; INPUT BUFFER FROM CONSOLE MVI E,0AH CALL CO ; SEND LINE FEED TO CONSOLE LHLD POINT MOV A,M CPI 1AH ; CONTROL Z JZ IREOF ; JUMP IF FIRST CHAR IN BUFFER IS ^Z XRA A ; NO ERROR RET ; ; ------------------------------------ ; ; CHECK FOR CHANNEL 1 MULTIPLE INPUTS ; MORE: LDA NCHAN DCR A JZ MORE1 ; JUMP IF CHAN 1 MVI A,1 ; END OF FILE RET MORE1: LHLD FNPTR1 ; P = IP MVI C,',' CALL SCAN JZ MORE2 ; JUMP IF ',' FOUND MVI A,1 ; END OF FILE RET MORE2: INX H SHLD FNPTR1 ; IP = P+1 CALL GDEVIC ; GET DEVICE CODE DCR A JNZ MORE3 ; JUMP UNLESS 1 - DISK CALL GFTAB ; HL = FILE TABLE POINTER CALL DCLOSE ; CLOSE DISK FILE MORE3: LHLD FNPTR MVI B,1 CALL XDEVC ; LU(1) = XUNIT(IP) ORA A JZ MORE8 ; ERROR IF NUL: CPI 3 JZ MORE ; ERROR IF LIST DEVICE LXI B,IACCE CALL IOPEN ; OPEN FILE IF DISK RET MORE8: MVI A,1 ; END OF FILE RET ; ; ------------------------------------- ; ; BUFFER WRITE ROUTINE ; IWRIT: LXI H,JCHAN+2 ; GET WRITE ACCESS DAD D MOV B,M ; JHOW = JCHAN(KCH+2) ; DCR B JZ IWRTB ; JUMP IF JHOW = 1 MACHINE READABLE FILE ; DCR B JZ IWRTA ; JUMP IF JHOW = 2 HUMAN READABLE OUTPUT ; ; *** MAYBE OUTPUT FORM FEED MVI M,2 ; SET JHOW TO 2 TOP OF FORM DONE CALL GBPDEV ; HL - BUFFER POINTER CPI 3 ; A - DEVICE CODE JNZ IWRT1 ; JUMP UNLESS LIST DEVICE MVI E,0CH CALL LO ; FORM FEED TO PRINTER IWRTA: IWRTB: CALL GBPDEV ; HL - BUFFER POINTER ORA A ; A - DEVICE CODE RZ ; RETURN IF 0 - NULL DEVICE DCR A JZ IWRT1 ; JUMP IF 1 - DISK DEVICE DCR A JZ IWRT2 ; JUMP IF 2 - CONSOLE OUT DCR A JZ IWRT3 ; JUMP IF 3 - LIST DEVICE MVI A,1 ; ERROR CONDITION RET ; ; IWRT1: LHLD POINT ; RECALL BUFFER POINTER LDA NCHAN ; RECALL CHANNEL NUMBER CPI 5 JZ IWRT2 ; JUMP IF CONSOLE CHANNEL PUSH H CALL GFTAB ; HL = FILE TABLE POINTER POP D ; DE = BUFFER POINTER MOV B,D MOV C,E DCX B ; BC = POINTER TO LINE LENGTH CALL LWRITE ; WRITE LINE ORA A RZ ; RETURN IF NO ERROR MVI A,1 RET ; ; SEND LINE TO CONSOLE ; IWRT2: DCX H MOV C,M ; GET LINE LENGTH INR C IWRT2L: DCR C JZ IWRT2D INX H MOV E,M PUSH B PUSH H CALL CO POP H POP B JMP IWRT2L IWRT2D: MVI E,0DH CALL CO MVI E,0AH CALL CO XRA A ; NO ERROR RET ; ; SEND LINE TO LIST DEVICE ; IWRT3: DCX H MOV C,M ; GET LINE LENGTH INR C IWRT3L: DCR C JZ IWRT3D INX H MOV E,M PUSH B PUSH H CALL LO POP H POP B JMP IWRT3L IWRT3D: MVI E,0DH CALL LO MVI E,0AH CALL LO XRA A RET ; ; ------------------------------------- ; ; OPEN CHANNEL ; IOPEN: PUSH B ; BC POINTS TO ACCESS CODE CALL GFTAB ; HL = FILE TABLE POINTER PUSH H CALL FNAME ; DE = FILE NAME POINTER POP H POP B RZ ; RETURN UNLESS DISK DEVICE CALL DOPEN ; OPEN FILE ORA A RZ ; RETURN IF NO ERROR MVI A,1 ; *** *** ERROR MESSAGE RET ; ; -------------------------------------- ; ; CLOSE CHANNEL ; ICNTL: CALL GBPDEV ; HL - BUFFER POINTER CPI 1 ; A - DEVICE CODE JNZ ICNT3 ; JUMP UNLESS 1 - DISK DEVICE LXI H,JCHAN+6 DAD D MVI M,1 ; SET STATUS CLOSED CALL GFTAB ; HL = FILE TABLE POINTER CALL DCLOSE ; CLOSE FILE ORA A RZ ; RETURN IF NO ERROR MVI A,1 RET ICNT3: XRA A ; SET OPERATION STATUS = 0 RET ; ; ------------------------------------ ; ; GET BUFFER POINTER & DEVICE CODE NUMBER ; HL A ; GBPDEV: LHLD CHOFF ; RECALL CHANNEL OFFSET XCHG LXI H,JCHAN+5 DAD D ; ADD CHANNEL OFFSET MOV A,M ; DEVICE CODE LHLD POINT RET ; ; --------------------------------- ; ; GET FILE TABLE POINTER ; GFTAB: LDA NCHAN ; GET CHANNEL NUMBER DCR A ADD A MOV E,A MVI D,0 LXI H,FTABP DAD D MOV A,M INX H MOV H,M MOV L,A RET ; ; ------------------------------------- ; ; GET FILE NAMES FROM COMMAND LINE ; FINIT: LXI D,80H LXI H,COMLIN-1 LDA 80H INR A MOV C,A ; # OF CHARACTERS FINIT1: LDAX D MOV M,A INX H INX D DCR C JNZ FINIT1 FINIT2: MVI M,0 ; TERMINATE LINE WITH NULL CALL FINIT3 ; CONVERT TO UPPER CASE CALL FPRS ; PARSE COMMAND LINE RZ ; RETURN IF NO COMMAND LINE ERROR LXI D,COMERR CALL COB ; ERROR MESSAGE TO CONSOLE LXI D,COMLIN-2 CALL CIB ; GET NEW COMMAND LINE LXI H,COMLIN-1 MOV E,M ; GET LINE LENGTH MVI D,0 INX H DAD D JMP FINIT2 FINIT3: LXI H,COMLIN-1 MOV C,M ; LENGTH OF COMMAND LINE INX H INR C FINIT4: DCR C RZ ; RETURN IF AT END OF LINE MOV A,M ; GET CHARACTER CALL FINIT5 ; CONVERT IF LOWER CASE MOV M,A JMP FINIT4 FINIT5: CPI 'A'+20H RC ; RETURN IF < 'a' CPI 'Z'+21H RNC ; RETURN IF > 'z' SUI 20H RET ; ; -------------------------------------- ; ; PARSE COMMAND LINE ; FPRS: LXI H,COMLIN ; P = ^COM MVI C,'=' CALL SCAN JZ FPRS1 ; JUMP IF '=' FOUND LXI H,COMLIN SHLD FNPTR1 ; IP = ^COM LXI H,FNCON SHLD FNPTR3 ; OP = ^'CON:' LXI H,FNLST SHLD FNPTR4 ; LP = ^'LST:' JMP FPRS3 FPRS1: MVI M,0 ; MEM(P) = 0 INX H ; P = P + 1 SHLD FNPTR1 ; IP = P LXI H,COMLIN ; P = ^COM SHLD FNPTR3 ; OP = ^CHANNEL 3 SPECIFICATION MVI C,',' CALL SCAN JZ FPRS2 ; JUMP IF ',' FOUND LXI H,FNLST SHLD FNPTR4 ; LP = ^'LST:' JMP FPRS3 FPRS2: MVI M,0 ; MEM(P) = 0 INX H ; P = P + 1 SHLD FNPTR4 ; LP = ^CHANNEL 4 SPECIFICATION FPRS3: LHLD FNPTR1 MVI B,1 CALL XDEVC ; LU(1) = XUNIT(IP) ORA A JZ FPRS8 ; ERROR IF NUL: SPECIFIED CPI 3 JZ FPRS8 ; ERROR IF LST: SPECIFIED LHLD FNPTR3 MVI B,3 CALL XDEVC ; LU(3) = XUNIT(OP) LHLD FNPTR4 MVI B,4 CALL XDEVC ; LU(4) = XUNIT(LP) XRA A ; NO COMMAND ERROR DETECTED RET FPRS8: ORI 1 ; COMMAND ERROR DETECTED RET ; ; ------------------------------------- ; SCAN: MOV A,M CMP C RZ ; RETURN IF SEARCH SUCCESSFUL ORA A JZ SCAN1 ; JUMP IF END OF STRING INX H JMP SCAN SCAN1: INR A ; Z=0 - SEARCH FAILS RET ; ; ------------------------------------- ; ; GET FILE NAME POINTER FOR OPEN ; FNAME: CALL GDEVIC ; GET DEVICE CODE CPI 1 JZ FNAME1 ; JUMP IF DISK DEVICE XRA A RET FNAME1: LDA NCHAN DCR A ADD A MOV E,A MVI D,0 LXI H,FNPTR ; FILE NAME POINTER TABLE DAD D MOV E,M INX H MOV D,M MVI A,1 ORA A RET GDEVIC: LHLD CHOFF ; CHANNEL TABLE OFFSET LXI D,JCHAN+5 DAD D MOV A,M RET ; ; -------------------------------------- ; ; HL - POINTER TO FILE NAME ; B - CHANNEL NUMBER ; A - DEVICE CODE NUMBER ; XDEVC: CALL SKIPB ; SKIP BLANKS MVI C,0 ; NULL DEVICE JZ XDEVC4 ; JUMP IF , = OR NULL FOUND PUSH H LXI D,XDVTBL-2 ; SPECIAL DEVICE CODE TABLE XDEVC2: INX D XDEVC1: INX D XDEVC0: LDAX D MOV C,A CPI 1 JZ XDEVC3 ; JUMP IF END OF TABLE POP H PUSH H INX D LDAX D INX D CMP M JNZ XDEVC2 ; JUMP IF NO MATCH INX H LDAX D INX D CMP M JNZ XDEVC1 ; JUMP IF NO MATCH INX H LDAX D INX D CMP M JNZ XDEVC0 ; JUMP IF NO MATCH INX H ; TABLE MATCH FOUND MVI A,':' CMP M JZ XDEVC3 ; JUMP IF COLON MVI C,1 ; DISK DEVICE ASSUMED XDEVC3: POP H ; RESTORE STACK XDEVC4: PUSH B ; B - CHAN # C - DEVICE CODE # CALL MCHOFF ; MAKE CHANNEL OFFSET POINTER POP B LXI H,JCHAN+5 DAD D MOV M,C ; JCHAN(CH+5) = DEVICE CODE MOV A,C RET ; ; XDVTBL: DB 0,'NUL' DB 2,'CON' DB 2,'TTY' DB 2,'CRT' DB 2,'KBD' DB 3,'LST' DB 3,'LPT' DB 1 ; ; SKIPB: MOV A,M ORA A RZ SUI ',' RZ MOV A,M SUI '=' RZ MOV A,M CPI ' ' RNZ INX H JMP SKIPB ; ; ----------------------------------- ; MCHOFF: DCR B ; COMPUTE CHANNEL OFFSET MOV A,B ; FOR TABLE LOOKUP RLC ; KCH = (JCH-1)*6 ADD B RLC MOV E,A MVI D,0 RET ; ; ------------------------------------- ; ; CONSOLE I/O ; BDOS EQU 0005H CIB: MVI C,10 CALL BDOS RET COB: MVI C,9 CALL BDOS RET CO: MVI C,2 CALL BDOS RET LO: MVI C,5 CALL BDOS RET ; ; ------------------------------------ ; ; STORAGE ; JCHAN: DS 6*MAXCH+1 ; WORKING STORAGE FOR I/O TABLE JOP: DS 1 ; STORAGE FOR OPERATION CODE POINT: DS 2 ; BUFFER POINTER NCHAN: DS 1 ; STORAGE FRO CHANNEL NUMBER LEN: DS 1 ; LINE LENGTH CHOFF: DS 2 ; CHANNEL TABLE OFFSET ; IACCE: DB 1 ; READ ACCESS CODE OACCE: DB 3 ; WRITE ACCESS CODE WITH DELETE FTABP: DW FTAB1 DW FTAB2 DW FTAB3 DW FTAB4 FTAB1: DB 0,0,0,'1' ; CHAN 1 FILE TABLE DS 33+128 FTAB2: DB 0,0,0,'2' DS 33+128 FTAB3: DB 0,0,0,'3' DS 33+128 FTAB4: DB 0,0,0,'4' DS 33+128 FNPTR: FNPTR1: DS 2 FNPTR2: DW FNCH2 FNPTR3: DS 2 FNPTR4: DS 2 FNCH2: DB 'STAGE2.CH2',0 FNNUL: DB 'NUL:',0 FNCON: DB 'CON:',0 FNLST: DB 'LST:',0 DB 128,0 COMLIN: DS 129 ; STORAGE FOR COMMAND LINE COMERR: DB 0DH,0AH,'>>>>> COMMAND ERROR - REENTER' DB 0DH,0AH,'$',0 ; ;