* IF PTDOS * * * BYE COMMAND * CBYE CALL FLCLA CLOSE ALL FILES CALL SYS DB RETOP RETURN TO PTDOS ENDF . PTDOS * * DELETE COMMAND * * DEL N1 DELETE N1 * DEL N1,N2 DELETE FROM N1 TO N2 * DEL ,N2 DELETE FROM FIRST LINE TO N2 * DEL N1, DELETE FROM N1 TO LAST LINE * DEL DELETE ALL LINES * CDEL CALL GLARG GET ARGUMENTS CALL CRLF * LHLD FIRST DESTINATION XCHG LHLD LAST SOURCE * LDAX D CPI EOF JZ END1 * CALL NMOV BC:=(EOFA)-(HL) * XCHG . HL=DEST, DE=SOURCE, BC=COUNT CALL LMOV DELETE * MVI M,EOF NEW END OF FILE SHLD EOFA CALL CCLEAR CLEAR OUT SYM. TAB. JMP END1 * * * SCRATCH COMMAND * CLEAR COMMAND * * THIS COMMAND IS ALSO CALLED FROM THE INIT LOGIC * CCLEAR CALL FLCLA CLOSE ALL FILES JMP ZAPER CSCR CALL FLCLA CLOSE ALL FILES * * ZAPALL LHLD BOFA MVI M,EOF SHLD EOFA DCX H SHLD TXA IN CASE CSCR IS EXECUTED AS A STATEMENT * ZAPER LHLD MEMTOP MVI M,ETYPE DCX H SHLD TSTKA TOP OF ARG STACK * LHLD EOFA WIPE OUT DEFINITIONS INX H SHLD STA * LXI H,0 CLEAR ERRSET TXA SHLD ERRLN * XRA A STA CONTF CANT DO A 'CONT' AFTER 'CLEAR' STA MENT CLR MATRIX ENTRY FLAG * CALL CFF RESET PRINT FORMAT CALL DFC * LXI H,26*2 ALLOCATE AND ZERO SYMTAB BUCKETS JMP ASTAB * * * RENUMBER COMMAND * CREN LXI H,10 SHLD BEG BEGINNING LINE NUMBER SHLD DEL DEFAULT INCREMENT * CALL INTGER JC CREN1 MOV A,H ORA L JZ OBERR SHLD BEG * CALL SCOMA JNZ CREN1 * CALL INTGER JC LNERR MOV A,H ORA L JZ OBERR SHLD DEL * CREN1 CALL GC CPI CR JNZ LNERR * * MAKE SURE ARGS WONT CAUSE OVERFLOW * LXI D,177777Q HIGHEST POSSIBLE LINE NUMBER CALL FINDLN WILL GIVE OBERR IF ARGS TOO BIG FOR PROGRAM * * NOW WE HAVE BEG AND DEL SET UP * BEGIN PASS 1 (CHANGING OF LINE NUMBER REFERENCES) * LHLD BOFA XRA A STA URFLAG CLEAR UNRESOLVED REF FLAG * R0 MOV A,M CPI EOF JZ R5 GOTO PASS 2 INX H PASS LINE LEN BYTE INX H INX H SHLD TXA SAVE ADDR OF THE TEXT OF THIS LINE * R1 CALL GCI THE FIRST THING ON A LINE CAN'T BE AN LNRW CPI CR CHECK FOR EOL JZ R0 R8 CALL LNUM LN FOUND? JC R1 NO, SEARCH * * HERE WE HAVE FOUND A LINE NUM (IN HL) AND ADVANCED TXA * PAST IT * XCHG . PUT LINE NUMBER IN DE CALL FINDLN FIND THE NEW LINE NUMBER RETURNED IN 'NLN' LXI D,0 MAKE A ZERO LN INCASE OF UNRESOLVED REF JC R9 LINE NUMBER NOT FOUND, UNRESOLVED JNZ R9 EXACT MATCH NOT FOUND, UNRESOLVED * LHLD NLN THE NEW LINE NUMBER COMPUTED BY FINDLN XCHG . NEW LINE NUMBER TO DE R9 LHLD TXA NEW LN IS IN DE, HL <= TXA OF WHERE IT GOES + 2 DCX H DCX H CALL DSTOR UPDATE THE LINE NUMBER IN TEXT SHLD TXA MOV A,D ORA E JNZ R8 GOTO R8 IF LN WAS NOT ZERO LDA URFLAG ORI 1 STA URFLAG FLAG SHOWING UNRESOLVED REF JMP R8 * * PASS 2 OF RENUMBER (UPDATE THE LINE NUMBERS) * R5 LHLD DEL MOV B,H MOV C,L INCREMENT LHLD BEG XCHG LHLD BOFA * R6 MOV A,M ACCA NOT USED UNTIL CALL TO ADR BELOW CPI EOF JZ R10 DONE, CHECK FOR UNRESOLVED REF PUSH H SAVE H FOR CALL TO ADR INX H PASS LIN LEN, POINT TO LN CALL DSTOR DE IS NEW LN, STORE IT POP H BACKUP, POINTER TO BEGINNING OF THIS LINE CALL ADR GET TO NEXT LINE, ACCA HAS DISTANCE FROM ABOVE XCHG . LAST LN (DE) TO HL DAD B LINE NUMBER FOR NEXT LINE (LAST LN + DEL) XCHG . LN (HL) TO DE JMP R6 * * R10 LDA URFLAG ORA A JNZ URERR JMP END1 * * URFLAG DS 1 UNRESOLVED REF FLAG FOR REN COMMAND * * * LIST COMMAND * * LIST N1 LIST LINE N1 * LIST N1, LIST FROM N1 TO LAST LINE * LIST ,N2 LIST FROM FIRST LINE TO N2 * LIST N1,N2 LIST FROM N1 TO N2 * LIST LIST ALL LINES * CLIST CALL GLARG GET ARGUMENTS CALL CRLF CALL CRLF XRA A STA LPHED INITIALIZE INDENTATION COUNTER LHLD FIRST GET ADDR OF FIRST LINE * CL1 MOV A,M CPI EOF RZ * LXI D,IBUF1 CALL UPPL CONVERT LINE INTO TEXT (IN IBUF) INX H POINT TO BEGINING OF NEXT LINE TO LIST * PUSH H LXI H,IBUF1+5 MVI M,'"' TERMINATE LINE NUMBER LXI H,IBUF1 CALL PRNT PRINT LINE NUMBER INX H PASS THE " * MVI B,-2 LDA FORFG THIS WILL CONTAIN A 2 IF LOGICLY TRUE ORA A JNZ LPADD MOV B,A LPADD LDA LPHED ADD B ADI 6 MOV E,A CALL PTAB1 * CALL PRNTCR PRINT THE STATEMENT IF SOLOS CALL SPDCK DO SPEED CONTROL ENDF IF PTDOS CALL PCHECK ENDF CALL CRLF POP D * LXI H,LAST ADDR OF ADDR OF END OF LAST LINE CALL DCMP XCHG RZ JMP CL1 * * * EDIT COMMAND * * EDIT EDIT FIRST LINE * EDIT N1 EDIT LINE N1 * EDIT N1,N2 EDIT LINE N1 * EDIT N1, EDIT LINE N1 * EDIT ,N2 EDIT FIRST LINE * CEDIT LDA XOPORT ORA A JNZ NAERR * CALL GLARG GET LINE NUMBER ARGUMENTS CALL CRLF LINE FEED, CARRIAGE RETURN * LHLD BOFA MOV A,M CPI EOF JZ NPERR * IF PTDOS CALL CLR2L BACKUP ONE LINE AND CLEAR TWO LHLD CURFG GET PRESENT VALUES PUSH H LXI H,80H PUT IN PROPER VALUES SHLD CURFG ENDF CALL READR GET CURRENT DISPLAY ADDRESS INTO 'VDMAD' * IF PTDOS MVI M,' '+80H TURN ON THE CURSOR FOR SURE LXI H,PHEAD MVI M,2 MAKE PHEAD NON-ZERO ENDF LHLD FIRST LXI D,IBUF1 PUT LINE IN IBUF1 CALL UPPL DECODE LINE TO IBUF1 RETURNS C=# OF CHARS IN BUFFER DCR C GET RID OF THE CARRIAGE RETURN DCX D THAT UPPL PUT ON THE END * LXI H,CEDRP GET EDIT RETURN POINT PUSH H FOR RETURN FROM 'INLINE' * LXI H,IBUF1 ADDR OF IBUF TO HL PUSH H BECAUSE OF ENTRY POINT USED BELOW JMP INST2 ENTRY TO 'INLINE', C HAS CHARACTER COUNT * CEDRP EQU $ IF PTDOS POP H GET BACK THE CURSOR VALUES SHLD CURFG ENDF PUSH PSW SAVE TERMINATOR CALL PP ENCODE THE LINE JC LNERR ONLY LINES WITH LINE NUMBERS! CALL LINE EDIT LINE IN * POP PSW GET TERMINATOR IF SOLOS CPI LF JNZ CED07 IF LF THEN CRLF, ELSE LFCR CALL CRLF JMP CED08 CED07 MVI B,LF LINE FEED, CARRIAGE RETURN CALL CHOUT MVI B,CR CALL CHOUT CED08 JMP CCLEAR ENDF IF PTDOS CPI LF JNZ CED07 CALL CRLF CALL CRLF JMP CCLEAR CED07 MVI B,LF CALL CHOUT MVI B,LF CALL CHOUT MVI B,CR CALL CHOUT MVI B,CR CALL CHOUT JMP CCLEAR ENDF * * * * CONTINUE COMMAND * CCONT LDA CONTF ORA A JZ NCERR CALL CRLF XRA A STA DIRF POP H RETURTN LINK POP H SAVED VALUE OF PROGRAM TXA SHLD TXA POP H POP D POP B SAVED REGISTORS MVI A,KCAN THIS INCASE WE ARE RETURNING TO INLINE RET . RETURN FROM PCHECK * * * RUN COMMAND * CRUN LDA DIRF ORA A CNZ CRLF NEW LINE IF NOT RUNNING * LHLD TXA PUSH H CALL GLARG GET LINE NUMBER ARG POP H MOV A,M CPI CR IF THERE WAS AN ARGUMENT THEN... PUSH PSW CZ CCLEAR ...DON'T CLEAR * LHLD BOFA MOV A,M CPI EOF CHECK FOR NULL PROGRAM JZ NPERR * DCX H PTR TO CR PRECEDING FIRST LINE TO BE EXECUTED SHLD TXA THE PLACE TO START RUNNING AT XRA A STA DIRF CLEAR DIRECT MODE FLAG (RUN MODE NOW) STA CONTF CLEAR CONTINUE FLAG STA MENT CLEAR MATRIX ENTRY FLAG LXI H,0 CLEAR TIME/COUNT LIMIT SHLD ITIM SHLD ITIM+1 POP PSW JNZ CRUN4 IF THERE WAS A LN ARG THEN SKIP FUNC DEF * CALL CFF RESET TO FREE FORM CALL DFC * LXI H,0 RESET ERROR TRAPPING SHLD ERRLN * LHLD BOFA DCX H POINT TO INITIAL CR WHICH PRECEEDS THE PROG BUFFER SHLD RTXA SET THE READ STATEMENT DATA POINTER (INITIALY) * * * DEFINE FUNCTIONS, CHECK FOR FNEND BALANCE * CRUN1 LXI B,DEFRW*256+FNERW LOOK FOR DEF OR FNEND XRA A CALL LSTAT JC CRUN4 DONE DEFINING CPI FNERW JZ FDERR * * NOW WE KNOW IT MUST HAVE BEEN A DEFRW * MVI B,FNRW CALL EATC CALL FNAME CALL STLK JNC DDERR ERROR IF NAME NOT CREATED PUSH H SYMTAB PTR LXI H,2 CALL ASTAB CALL EATLP XCHG POP H CALL DSTOR SAVE TXA IN SYMTAB * * EAT UP DEFINITON * CALL FEND JMP CRUN1 * * CRUN4 LHLD FIRST STARTING TXA INX H INX H INX H SHLD TXA * LXI H,CRM DO COPYRIGHT CHECK XRA A MVI B,CRML CRUNC ADC M ONES CHECKSUM IS LEFT CIRCULAR INX H DCR B LENGTH JNZ CRUNC * LHLD STA SYMBOLTABLE FREE POINTER (SNIKER...SNIKER) LXI D,STKTOP TOP OF STACK XCHG CKSUM EQU $+1 CPI 00H IS IT WHAT IT SHOULD BE?? JZ CRUNY YES XCHG . NO, THEN HIS VARS WILL CLOBBER THE STACK LXI B,SSIZE-56 CRUNY LXI B,SSIZE STACK SIZE DAD B BOTTOM OF STACK POINTER DCX H LESS ONE SPHL SHLD SPTR * MVI A,CR CLEAR IF TERM STA IFTERM * JMP ILOOP GO TO THE INTERPRETER DRIVER * * * SET COMMAND * CSET CALL GCI GET THING TO SET PUSH PSW IF PTDOS CPI SE6RW JZ CSET2 ENDF CALL PFIXE GET EXPRESSION AND FIX TO DE CSET2 POP PSW PUSH D SAVE RESULT * CPI LNRW ALL 'SET' WORDS ARE BELOW 'LNRW' JNC BSERR SUI SELRW JC BSERR NOT A 'SET' WORD * RAL . MUL TIMES 2 LXI H,STBL ADDR OF SET TABLE CALL ADR HL=HL+A CSET1 CALL LHLI HL=(HL) XTHL . EXPRESSION RESULT TO HL, HL TO STACK MOV A,L A GETS LOW OF EXPRESSION RESULT RET . CALL SETTING ROUTINE, IT WILL RETURN FOR US * * SETLL MOV A,H ORA A JNZ OBERR WAY TOO BIG MVI A,LINMAX CMP L JC OBERR MOV A,L STA LINLEN RET * * SETML LDA DIRF ORA A JZ BSERR * XCHG . DE HAS NEW LIMIT LHLD BOFA LXI B,LINMAX+1 DAD B LOWEST POSSIBLE MEMORY LIMIT IS BOFA+LINMAX+1 XCHG . HL HAS NEW LIMIT, DE HAS MIN LIMIT CALL HDCMP HL-DE TEST JC OBERR TOO SMALL MEMAX EQU $+1 LXI D,0000H THE HIGEST POSSIBLE MEMORY ADDRESS FOR BASIC INX D CALL HDCMP JNC OBERR SHLD MEMTOP JMP CCLEAR THIS MAKES TI TAKE EFFECT RIGHT-A'-WAY * IF SOLOS * * SETDS MVI B,8 SET DISPLAY SPEED JMP ESCSEQ DO ESCAPE SEQ AND RETURN * * SETDB MVI B,7 DISPLAY BYTE JMP ESCSEQ * * SETIP LHLD XIPORT SET INPUT PSEUDO PORT MOV M,A RET * * SETOP LHLD XOPORT SET OUTPUT PSEUDO PORT MOV M,A RET * * DO A SOLOS ESCAPE SEQUENCE * ESCSEQ PUSH PSW AN ESCAPE SEQU. JUST LIKE IN THE BOOK PUSH B MVI B,KESC CALL ZOUT POP B CALL ZOUT POP PSW MOV B,A JMP ZOUT ...AND RETURN ENDF IF PTDOS * * * SETOF LDA XOPORT ORA A CNZ SEF1 END-FILE AND CLOSE THE OLD FILE * CALL GC CPI '#' JZ SEF2 * CALL GFNX GET FILE NAME * SEF8 LXI D,CFN OPEN FILE LXI H,0 CALL SYS DB OPEOP JMP SEF9 IF ERNEX THEN CREATE * SEF0 STA XOPORT NEW OUTPUT FILE NUMBER MVI B,VCLEAR ORA A CZ SYSOT CLEAR SCREEN IF ON INTERNAL DRIVER * LHLD SYSGLO LXI D,GLCOF DAD D LDA XOPORT ORA A JNZ SEF4 MVI A,1 SEF4 MOV M,A SET GLCOF RET * SEF1 CALL SYS DB EOFOP JMP DKERR LDA XOPORT CALL SYS DB CLOOP JMP DKERR RET * SEF2 INX H PASS THE # SHLD TXA CALL PFIXE GET FILE # MOV A,D ORA A JNZ OBERR TOO BIG MOV A,E WHO KNOWS?? JMP SEF0 * SEF9 CPI ERNEX JNZ DKERR * * CREATE AN OUTPUT FILE * MVI A,'.'+80H STA CFT LXI H,04C0H SHLD CBLKS XRA A STA CATTR LXI D,CCREB CALL SYS DB CREOP JMP DKERR JMP SEF8 TRY TO RE-OPEN * * SETFB MOV A,H ORA L JZ SFB0 LXI H,-1 JMP SFB1 SFB0 LXI H,0 SFB1 SHLD OPEBU RET * * SETXI CALL OPEEOF LOOK UP THE FCB JNZ FDERR NO SUCH, TURKEY! CALL DIRT LHLD STA FIND SOME SPACE PUSH H LXI D,256 SIZE OF AN INDEX BLOCK DAD D CALL STOV SHLD STA * POP H INDEX'S MEMORY ADDERSS LDA CSFID FILE # FROM FCB MVI B,4 LOAD INDEX CALL SYS DB CTLOP JMP DKERR RET * * SETDS PUSH PSW CALL SCOMA SYNTAX ',' JC SEDS0 CALL PFIXE GET SPEED CONTROL CODE MOV A,D ORA A JNZ OBERR MOV A,E CPI 3+1 JNC OBERR STA SPDCTRL SET THE SPEED CONTROL BYTE * SEDS0 POP PSW STA SPEED SET SPEED RET * * SETCP LDA XOPORT ORA A JNZ NAERR MOV A,L * LXI H,CHRPO MVI M,80H INVERTED ORA A RNZ MVI M,00H NORMAL RET * * SETCM LDA XOPORT ORA A JNZ NAERR * MOV B,L SAVE THE FLAG CALL CREM GET RID OF ANY CURSOR THAT IS ON MOV A,B ORA A JNZ SCMON GO SET IT ON IF NON-ZERO STA CURFG SET FOR NEXT OFF; ACCA IS ZERO BY TEST RET * SCMON MVI A,80H TURN ON THE BIT STA CURFG XRA M COMPLEMENT THE CURRENT (HL FROM 'CREM') MOV M,A RET ENDF * * * * * TABLE OF "SET" ROUTINE ADDRESSES * STBL DW SETLL SET LINE LENGTH DW SETML SET MEMORY LIMIT IF SOLOS DW SETIP DW SETOP DW SETDS DW SETDB ENDF IF PTDOS DW SETDS DW SETXI DW SETFB DW SETCM DW SETCP DW SETOF ENDF * * * TAPE ON COMMAND * CTON CALL PFIXE MOV A,D ORA A JNZ OBERR WOW! ORA E MOVE E TO A AND TEST JZ OBERR STA CSFID FOR TTON CPI 2+1 JC TTON JMP OBERR * *