; JUMPING TO THIS LOCATION IS LIKE RETSKP. IT ASSUMES THE INSTRUCTION ; AFTER THE CALL IS A JMP ADDR. RSKP: POP HL ; GET THE RETURN ADDRESS. INC HL ; INCREMENT BY THREE. INC HL INC HL JP (HL) ; THIS ROUTINE PRINTS THE NUMBER IN HL ON THE SCREEN IN DECIMAL. ; SAVES ALL ACS. NOUT: PUSH AF ; SAVE OUR ACS. PUSH BC PUSH DE PUSH HL LD BC,-10 ; GET SOME USEFUL CONSTANTS. LD DE,-1 NOUT2: ADD HL,BC ; SUBTRACT AS MANY 10S AS POSSIBLE. INC DE ; COUNT THEM. JP C,NOUT2 ; IF SOME LEFT KEEP GOING. LD BC,10 ; RESTORE THE LAST 10 WE TOOK AWAY. ADD HL,BC EX DE,HL ; SWAP THE REMAINDER AND THE QUOTIENT. LD A,H ; GET THE NUMBER OF 10S FOUND. OR L ;* I THINK THIS CHECKS IF H EQUALS ZERO. IF CALL NZ,NOUT ; IF NON ZERO, RECURSE. LD A,E ; GET THE REMAINDER. ADD A,30H ; MAKE THE NUMBER PRINTABLE. CALL CONOUT POP HL ; RESTORE THE ACS. POP DE POP BC POP AF RET ; THIS SET OF ROUTINES PROVIDES A USER ORIENTED WAY OF PARSING ; COMMANDS. IT IS SIMILAR TO THAT OF THE COMND JSYS IN TOPS-20. ; THIS ROUTINE PRINTS THE PROMPT IN DE AND SPECIFIES THE REPARSE ; ADDRESS. PROMPT: POP HL ; GET THE RETURN ADDRESS. PUSH HL ; PUT IT ON THE STACK AGAIN. LD (CMRPRS),HL ; SAVE IT AS THE ADDRESS TO GO TO ON REPARSE. LD (CMOSTP),SP ; SAVE FOR LATER RESTORAL. LD (CMPRMP),DE ;save the prompt location LD HL,CMDBUF LD (CMCPTR),HL ; INITIALIZE THE COMMAND POINTER. LD (CMDPTR),HL XOR A LD (CMAFLG),A ; ZERO THE FLAGS. LD (CMCCNT),A LD A,0FFH ; TRY IT THIS WAY (DAPHNE.) LD (CMSFLG),A LD DE,CMCRLF CALL PRTSTR LD DE,(CMPRMP) ; PRINT THE PROMPT. CALL PRTSTR RET ; THIS ADDRESS IS JUMPED TO ON REPARSE. REPARS: LD SP,(CMOSTP) ; GET THE OLD STACK POINTER. LD HL,CMDBUF LD (CMDPTR),HL LD A,0FFH ; TRY IT THIS WAY (DAPHNE.) LD (CMSFLG),A LD HL,(CMRPRS) ; GET THE REPARSE ADDRESS. JP (HL) ; GO THERE. ; THIS ADDRESS CAN BE JUMPED TO ON A PARSING ERROR. PRSERR: LD SP,(CMOSTP) ; GET THE OLD STACK POINTER. LD HL,CMDBUF LD (CMCPTR),HL ; INITIALIZE THE COMMAND POINTER. LD (CMDPTR),HL XOR A LD (CMAFLG),A ; ZERO THE FLAGS. LD (CMCCNT),A LD A,0FFH ; TRY IT THIS WAY (DAPHNE.) LD (CMSFLG),A LD DE,CMCRLF CALL PRTSTR LD DE,(CMPRMP) ; GET THE PROMPT. CALL PRTSTR ;* INSTEAD RETURN TO BEFORE THE PROMPT CALL. LD HL,(CMRPRS) JP (HL) ; THIS ROUTINE PARSES THE SPECIFIED FUNCTION IN A. ANY ADDITIONAL ; INFORMATION IS IN DE AND HL. ; RETURNS +1 ON SUCCESS ; +4 ON FAILURE (ASSUMES A JMP FOLLOWS THE CALL) COMND: LD (CMSTAT),A ; SAVE WHAT WE ARE PRESENTLY PARSING. CALL CMINBF ; GET CHARS UNTIL AN ACTION OR A ERASE CHAR. CP CMCFM ; PARSE A CONFIRM? JP Z,CMCFRM ; GO GET ONE. CP CMKEY ; PARSE A KEYWORD? JP Z,CMKEYW ; TRY AND GET ONE. CP CMIFI ; PARSE AN INPUT FILE SPEC? JP Z,CMIFIL ; GO GET ONE. CP CMIFIN ; INPUT FILE-SPEC SILENT? JP Z,CMIFIL ; DO AS HE WISHES CP CMOFI ; OUTPUT FILE SPEC? JP Z,CMOFIL ; GO GET ONE. CP CMTXT ; PARSE ARBITRARY TEXT? JP Z,CMTEXT ; GO DO IT. LD DE,CMER00 ; "?UNRECOGNIZED COMND CALL" CALL PRTSTR RET ; THIS ROUTINE PARSES ARBITRARY TEXT UP TO A CR. ; ACCEPTS DE: ADDRESS TO PUT TEXT ; RETURNS IN A: NUMBER OF CHARS IN TEXT (MAY BE 0) ; DE: UPDATED POINTER CMTEXT: EX DE,HL ; PUT THE POINTER TO THE DEST IN HL. LD (CMPTAB),HL ; SAVE THE POINTER. LD B,0 ; INIT THE CHAR COUNT CMTXT1: CALL CMGTCH ; GET A CHAR. OR A ; TERMINATOR? JP P,CMTXT5 ; NO, PUT IN USER SPACE. AND 7FH ; TURN OFF MINUS BIT. CP ESC ; AN ESCAPE? JR NZ,CMTXT2 ; NO. LD A,BELL ; GET A BELL. CALL CONOUT XOR A LD (CMAFLG),A ; TURN OFF THE ACTION FLAG. LD HL,(CMCPTR) ; MOVE THE POINTER TO BEFORE THE ESCAPE. DEC HL LD (CMCPTR),HL LD (CMDPTR),HL LD HL,CMCCNT ; GET THE CHAR COUNT. DEC (HL) ; DECREMENT IT BY ONE. JP CMTXT1 ; TRY AGAIN. CMTXT2: CP '?' ; IS IT A QUESTION MARK? JR Z,CMTXT3 ; IF SO PUT IT IN THE TEXT. CP ' ' ;blank? JR Z,CMTXT3 ;if so put in the text CP FF ; IS IT A FORMFEED? CALL Z,CMBLNK ; IF SO BLANK THE SCREEN. LD A,B ; RETURN THE COUNT. LD HL,(CMPTAB) ; RETURN UPDATED POINTER IN HL. EX DE,HL JP RSKP ; RETURN SUCCESS. CMTXT3: LD HL,CMAFLG ; POINT TO THE ACTION FLAG. LD (HL),0 ; SET IT TO ZERO. CMTXT5: INC B ; INCREMENT THE COUNT. CP 'a' JR C,CMTXT6 ;lower than 'a' CP 'z' JR NC,CMTXT6 ;greater than 'z' AND 5FH ;capitalize it CMTXT6 LD HL,(CMPTAB) ; GET THE POINTER. LD (HL),A ; PUT THE CHAR IN THE ARRAY. INC HL LD (CMPTAB),HL ; SAVE THE UPDATED POINTER. JP CMTXT1 ; GET ANOTHER CHAR. ; THIS ROUTINE GETS A CONFIRM. CMCFRM: LD DE,CMIN00 ; PRINT SOMETHING USEFUL. CALL PRTSTR LD DE,CMCRLF ; PRINT A CRLF. CALL PRTSTR LD DE,(CMPRMP) ; REPRINT THE PROMPT. CALL PRTSTR LD HL,(CMDPTR) ; GET THE POINTER INTO THE BUFFER. LD A,'$' ; PUT A $ THERE FOR PRINTING. LD (HL),A LD HL,(CMCPTR) DEC HL ; DECREMENT AND SAVE THE BUFFER POINTER. LD (CMCPTR),HL LD DE,CMDBUF CALL PRTSTR XOR A ; TURN OFF THE ACTION FLAG. LD (CMAFLG),A CALL @KEY ;get a key from the keyboard CP CR JR Z,CMCFR3 CP FF JR Z,CMCFR3 CP 4 RET M LD HL,(CMCPTR) INC HL LD (HL),A INC HL LD (CMCPTR),HL CALL CONOUT JP REPARS ; REPARSE EVERYTHING. CMCFR3: CP FF ; IS IT A FORM FEED? CALL Z,CMBLNK ; IF SO BLANK THE SCREEN. JP RSKP ; THIS ROUTINE PARSES A KEYWORD FROM THE TABLE POINTED ; TO IN DE. THE FORMAT OF THE TABLE IS AS FOLLOWS: ; ; ADDR: DB N ; WHERE N IS THE # OF ENTRIES IN THE TABLE. ; DB M ; M IS THE SIZE OF THE KEYWORD. ; DB 'STRING$' ; WHERE STRING IS THE KEYWORD. ; DB A,B ; WHERE A & B ARE PIECES OF DATA ; ; TO BE RETURNED. (MUST BE TWO OF THEM.) ; ; THE KEYWORDS MUST BE IN ALPHABETICAL ORDER. ;**** NOTE: THE DATA VALUE A IS RETURNED IN REGISTERS A AND E. THE ;**** DATA VALUE B IS RETURNED IN REGISTER D. THIS ALLOWS THE TWO DATA ; BYTES TO BE STORED AS: ; DW XXX ; AND RESULT IN A CORRECTLY FORMATTED 16-BIT VALUE IN REGISTER PAIR ; DE. CMKEYW: LD (CMHLP),HL ; SAVE THE HELP. LD (CMPTAB),DE ; SAVE THE BEGINNING OF KEYWORD TAB FOR '?'. LD A,(DE) ; GET THE NUMBER OF ENTRIES IN THE TABLE. LD B,A ;save in B INC DE LD (CMKPTR),DE LD HL,(CMDPTR) ; SAVE THE COMMAND POINTER. LD (CMSPTR),HL CMKEY2: LD A,B OR A ; ANY LEFT? RET Z ; IF NOT WE FAILED. LD HL,(CMKPTR) LD E,(HL) ; GET THE LENGTH OF THE KEYWORD. INC HL CMKEY3: DEC E ; DECREMENT THE NUMBER OF CHARS LEFT. LD A,E CP 0FFH ; HAVE WE PASSED THE END? JP M,CMKEY5 ; IF SO GO TO THE NEXT. CALL CMGTCH ; GET A CHAR. OR A ; IS IT A TERMINATER? JP P,CMKEY4 ; IF POSITIVE, IT IS NOT. AND 7FH ; TURN OFF THE MINUS BIT. CP '?' JP NZ,CMKY31 XOR A LD (CMAFLG),A ; TURN OFF THE ACTION FLAG. LD HL,CMCCNT ; DECREMENT THE CHAR COUNT. DEC (HL) ;* MUST GO THROUGH THE KEYWORD TABLE AND PRINT THEM. LD DE,(CMHLP) ; FOR NOW PRINT THE HELP TEXT. CALL PRTSTR LD DE,CMCRLF ; PRINT A CRLF. CALL PRTSTR LD DE,(CMPRMP) ; REPRINT THE PROMPT. CALL PRTSTR LD HL,(CMDPTR) ; GET THE POINTER INTO THE BUFFER. LD A,'$' ; PUT A $ THERE FOR PRINTING. LD (HL),A LD HL,(CMCPTR) DEC HL ; DECREMENT AND SAVE THE BUFFER POINTER. LD (CMCPTR),HL LD DE,CMDBUF CALL PRTSTR JP REPARS ; REPARSE EVERYTHING. CMKY31: CP ESC ; IS IT AN ESCAPE? JP NZ,CMKY35 XOR A LD (CMAFLG),A ; TURN OFF THE ACTION FLAG. PUSH DE PUSH BC PUSH HL CALL CMAMBG JP CMKY32 LD A,BELL CALL CONOUT LD HL,(CMCPTR) ; MOVE THE POINTER TO BEFORE THE ESCAPE. DEC HL LD (CMCPTR),HL LD (CMDPTR),HL LD HL,CMCCNT ; GET THE CHAR COUNT. DEC (HL) ; DECREMENT IT BY ONE. POP HL POP BC POP DE INC E ; INCREMENT THE LEFT TO PARSE CHAR COUNT. JP CMKEY3 CMKY32: LD HL,(CMCPTR) ; POINTER INTO BUFFER. DEC HL ; BACKUP TO THE ESCAPE. EX DE,HL POP HL PUSH HL CMKY33: LD A,(HL) ; GET THE NEXT CHAR. CP '$' ; FINISHED? JP Z,CMKY34 INC HL EX DE,HL LD (HL),A ; MOVE IT INTO THE BUFFER. INC HL EX DE,HL LD A,(CMCCNT) ; INCREMENT THE CHAR COUNT. INC A LD (CMCCNT),A JP CMKY33 CMKY34: LD A,(CMCCNT) ; GET THE CHARACTER COUNT. INC A ; INCREMENT AND SAVE IT. LD (CMCCNT),A EX DE,HL ; PUT THE COMMAND BUFFER POINTER IN HL. LD A,' ' ; GET A BLANK. LD (HL),A ; PUT IT IN THE COMMAND BUFFER. INC HL ; INCREMENT THE POINTER LD (CMCPTR),HL ; SAVE THE UPDATED POINTER. LD (CMDPTR),HL POP HL PUSH HL EX DE,HL CALL PRTSTR ; PRINT THE REST OF THE KEYWORD. LD A,' ' CALL CONOUT POP HL POP BC POP DE JP CMKY37 CMKY35: PUSH HL PUSH DE CALL CMAMBG JP CMKY36 LD DE,CMER01 CALL PRTSTR ; SAY ITS AMBIGUOUS. JP PRSERR ; GIVE UP. CMKY36: POP DE POP HL CMKY37: INC E ; ADD ONE INCASE IT IS NEGATIVE. LD D,0 ADD HL,DE ; INCREMENT PAST THE KEYWORD. INC HL ; PAST THE $. LD E,(HL) ; GET THE DATA. INC HL LD D,(HL) LD A,E JP RSKP CMKEY4: CP 'a' ; IS IT LESS THAN A? JR C,CMKY41 ; IF SO DON'T CAPITALIZE IT. CP 'z' ; IS IT MORE THAN Z? JR NC,CMKY41 ; IF SO DON'T CAPITALIZE IT. AND 137O ; CAPITALIZE IT. CMKY41: LD D,(HL) ; GET THE NEXT CHAR OF THE KEYWORD. INC HL CP D ; MATCH? JP Z,CMKEY3 ; IF SO GET THE NEXT LETTER. CMKEY5: LD D,0 LD A,E ; GET THE NUMBER OF CHARS LEFT. OR A ; IS IT NEGATIVE? JP P,CMKY51 LD D,0FFH ; IF SO, SIGN EXTEND. CMKY51: ADD HL,DE ; INCREMENT PAST THE KEYWORD. LD DE,0003H ; PLUS THE $ AND DATA. ADD HL,DE LD (CMKPTR),HL DEC B ; DECREMENT THE NUMBER OF ENTRIES LEFT. LD HL,(CMSPTR) ; GET THE OLD CMDPTR. LD (CMDPTR),HL ; RESTORE IT. ;* CHECK SO WE DON'T PASS IT. JP CMKEY2 ; GO CHECK THE NEXT KEYWORD. CMAMBG: DEC B ; DECREMENT THE NUMBER OF ENTRIES LEFT. RET M ; IF NONE LEFT THEN IT IS NOT AMBIGUOUS. INC E ; THIS IS OFF BY ONE; ADJUST. LD C,E ; SAVE THE CHAR COUNT. LD A,E OR A ; ANY CHARS LEFT? RET Z ; NO, IT CAN'T BE AMBIGUOUS. LD D,0 ADD HL,DE ; INCREMENT PAST THE KEYWORD. LD E,3 ; PLUS THE $ AND DATA. ADD HL,DE LD B,(HL) ; GET THE LENGTH OF THE KEYWORD. INC HL EX DE,HL LD HL,(CMKPTR) ; GET POINTER TO KEYWORD ENTRY. LD A,(HL) ; GET THE LENGTH OF THE KEYWORD. SUB C ; SUBTRACT HOW MANY LEFT. LD C,A ; SAVE THE COUNT. CP B JP Z,CMAMB0 RET P ; IF LARGER THAN THE NEW WORD THEN NOT AMB. CMAMB0: LD HL,(CMSPTR) ; GET THE POINTER TO WHAT PARSED. CMAMB1: DEC C ; DECREMENT THE COUNT. JP M,RSKP ; IF WE ARE DONE THEN IT IS AMBIGUOUS. EX DE,HL ; EXCHANGE THE POINTERS. LD B,(HL) ; GET THE NEXT CHAR OF THE KEYWORD INC HL EX DE,HL ; EXCHANGE THE POINTERS. LD A,(HL) ; GET THE NEXT PARSED CHAR. INC HL CP 'a' ; IS IT LESS THAN A? JR C,CMAMB2 ; IF SO DON'T CAPITALIZE IT. CP 'z' ; IS IT MORE THAN Z? JR NC,CMAMB2 ; IF SO DON'T CAPITALIZE IT. AND 137O CMAMB2: CP B ; ARE THEY EQUAL? RET NZ ; IF NOT THEN ITS NOT AMBIGUOUS. JP CMAMB1 ; CHECK THE NEXT CHAR. CMIFIL EX DE,HL LD (CMFCB),HL EX DE,HL LD HL,(CMFCB) LD B,50 ;number to blank CMIFI0: LD (HL),' ' ; BLANK THE FCB. INC HL DJNZ CMIFI0 CMIFI1: LD HL,(CMDPTR) ;GET COMMAND FCB CALL @FSPEC JR Z,CMIFI2 LD DE,CMER02 CALL PRTSTR JP PRSERR CMIFI2: LD (CMDPTR),HL JP RSKP CMOFIL: JP CMIFIL CMINBF: PUSH AF PUSH DE PUSH HL LD A,(CMAFLG) ; IS THE ACTION CHAR FLAG SET? OR A JP NZ,CMINB9 ; IF SO GET NO MORE CHARS. LD HL,(CMCPTR) LD DE,CMFCB ;END OF BUFFER XOR A SBC HL,DE LD B,L ;size of cmdbuf LD HL,(CMCPTR) CALL @KEYIN ;rom lineinput routine JP C,PRSERR ;action if typed LD A,B LD (CMCCNT),A OR A JP Z,PRSERR ; IF NOT, JUST START OVER. LD HL,(CMCPTR) LD E,B LD D,0 ADD HL,DE LD (CMCPTR),HL ;update pointer CMINB6: LD A,0FFH ; SET THE ACTION FLAG. LD (CMAFLG),A CMINB9: POP HL POP DE POP AF RET CMGTCH: PUSH HL PUSH BC CMGTC1: LD A,(CMAFLG) OR A ; IS IT SET. CALL Z,CMINBF ; IF THE ACTION CHAR FLAG IS NOT SET GET MORE. LD HL,(CMDPTR) ; GET A POINTER INTO THE BUFFER. LD A,(HL) ; GET THE NEXT CHAR. INC HL LD (CMDPTR),HL CP ' ' ; IS IT A SPACE? JP Z,CMGTC2 CP TAB ; OR A TAB? JP NZ,CMGTC3 CMGTC2: LD A,(CMSFLG) ; GET THE SPACE FLAG. OR A ; WAS THE LAST CHAR A SPACE? JP NZ,CMGTC1 ; YES, GET ANOTHER CHAR. LD A,0FFH ; SET THE SPACE FLAG. LD (CMSFLG),A LD A,' ' POP BC POP HL JP CMGTC5 CMGTC3: PUSH AF XOR A LD (CMSFLG),A ; ZERO THE SPACE FLAG. POP AF POP BC POP HL CP ESC JP Z,CMGTC5 CP '?' ; IS THE USER CURIOUS? JP Z,CMGTC4 CP CR JP Z,CMGTC4 CP LF JP Z,CMGTC4 CP FF RET NZ ; NOT AN ACTION CHAR, JUST RETURN. CMGTC4: PUSH HL LD HL,(CMDPTR) DEC HL LD (CMDPTR),HL POP HL CMGTC5: OR 80H ; MAKE THE CHAR NEGATIVE TO INDICATE IT IS RET ; A TERMINATOR.