* * * OUTPUT FILTER #1 * CHARACTER IS IN B * OF1 LDA LEDFG ORA A JZ OF13 TRANSLATE THIS CHARACTER? * XRA A CLEAR LEAD IN FLAG STA LEDFG MOV A,B CPI '&' &&=& JZ OF2 JUST PRINT IT * MVI A,-64 ADD B TRANSLATE CHARACTER TO CTRL-CHARACTER MOV B,A JMP OF2 PRINT CHARACTER * OF13 MOV A,B CPI '&' LEAD IN CHARACTER? JNZ OF2 NO, PRINT CHARACTER STA LEDFG RET * * * OUTPUT FILTER #2 * ALIAS "CHOUT" * CHARACTER IS IN B * IF SOLOS XSYOUT EQU $ ENDF OF2 EQU $ IF PTDOS MOV A,B ACCA FOR PTDOS ENDF CALL SYSOT SEND IT OUT MOV A,B SUI CR JZ OF21 MOV A,B CPI ' ' RC . NO PHEAD INC FOR CTRL-CHARACTERS LDA PHEAD INR A * OF21 STA PHEAD RET * CHOUT EQU OF2 * * * CARRIAGE RETURN * IF NEEDED * CCRLF LDA PHEAD ORA A RZ * * CARRIAGE RETURN * ALWAYS * CRLF MVI B,CR CALL CHOUT MVI B,LF JMP CHOUT * * CHECK IF PANIC CHARACTER HAS BEEN HIT * IF SOLOS XSYT2 EQU $ ENDF PCHECK CALL SYSTS RZ * * * INPUT FILTER #3 * MASKS OFF PARITY AND CHECKS FOR ESCAPE * CHARACTER RETURNED IN A * PCHK1 EQU $ IF3 EQU $ IF PTDOS CALL SYSIN ENDF ANI 7FH DIRTY LITTLE BIT! CPI ESC RNZ * * CHECK TO SEE IF PANIC HAPPENED DURING RUN * PUSH B PUSH D PUSH H INCASE OF STOP SO CCONT CAN CONTINUE LDA DIRF ORA A JZ STOP1 MUST HAVE BEEN RUN MVI B,'\' MUST HAVE BEEN INPUT (OR LIST) CALL CHOUT CALL CRLF JMP CMND1 ABORT * * * SPEED CONTROL CHECKING * IF SOLOS XSYT6 EQU $ SPDCK CALL SYSTS RZ . ANI 7FH CPI ' ' JNZ SPD1 WAIT IF SPACE BAR XSYT3 EQU $ SPD0 CALL SYSTS JZ SPD0 SPD1 CPI '1' JC PCHK1 CPI '9'+1 JNC PCHK1 * * 1-9 IS SPEED CONTROL * SUI '0' MOV B,A XRA A SPED STC . RAL . DCR B JNZ SPED RAR . JMP SETDS SET DISPLAY SPEED ENDF * * * INPUT FILTER #1 * CHARACTER IS IN A AND B * IF1 LDA CTLFG GET CTRL-CHARACTER FLAG ORA A JZ IF12 NO CTRL-CHARACTER EXPANSION MOV B,A XRA A MOV C,A ZERRO DISPATCH FLAG STA CTLFG CLEAR CTRL-CHARACTER EXPANTION FLAG MOV A,B RET . NOTE: CARRY IS CLEAR * IF12 CALL IF2 GET CHARACTER * MVI C,SCHRZ SPECIAL CHARACTER TABLE SIZE (IN ENTRIES) LXI H,SCHRT ADDR OF SPECIAL CHARACTER TABLE SCTS CMP M A=M? INX H POINT TO ADDR OF ROUTINE STC . INCASE OF MATCH RZ . A=M, CARRY<>0 MEANS DISPATCH INX H INX H DCR C JNZ SCTS SPECIAL CHARACTRER TABLE SEARCH * CPI ' ' CTRL-CHARACTER? RNC . NO, RETURN CARRY IS 0 * ADI 64 CONVERT TO NON-CTRL-CHARACTER STA CTLFG SAVE FOR EXPANTION MVI A,'&' MOV B,A RET . NOTE: CARRY IS 0 * * * INPUT FILTER #2 * CHARACTER IN A AND B * IF2 PUSH H IF20 LXI H,ITIMCONST IF SOLOS XSYT4 EQU $ ENDF IF21 CALL SYSTS JNZ IF22 THERE IS A CHARACTER * LDA DIRF ORA A JNZ IF21 NO TIMING IN DIRECT MODE * DCX H TICK...TOCK MOV A,H ORA L JNZ IF21 LHLD ITIM GET INPUT TIME LIMIT MOV A,H ORA L JZ IF20 NOT ACTIVE DCX H SHLD ITIM UPDATE TIME LIMIT MOV A,H ORA L JZ IF23 TIME'S UP SINKER...SINKER JMP IF20 NOT YET * IF22 CALL IF3 MASK AND TEST FOR ESCAPES MOV B,A POP H RET * IF23 MVI A,CR THIS IS WHAT YOU GET FOR TAKING SO LONG MOV B,A POP H RET * * * INPUT A LINE FROM THE TERMINAL * PCR EQU $ IF SOLOS XCHG . TERMINATE AT END OF LINE (DE) ENDF IF PTDOS PCR0 CALL HDCMP OUTPUT TEXT TI'LL HL = DE JZ PLF MOV B,M PUSH H PUSH D CALL OF2 POP D POP H INX H JMP PCR0 ENDF PLF MVI M,CR TERMINATE AT PRESENT POSITION (HL) INR C THERE IS ALWAYS ROOM FOR A CR! (THIS WON'T BE CORRECT!) * MOV B,A LDA TOPT GET OLD PHEAD ADD C STA PHEAD * LDA DIRF ORA A MOV A,B RNZ . NO TIME/COUNT CLEAR IF IN DIRECT MODE LXI H,0 SHLD ITIM THIS ZEROS ITIM SHLD ITIM+1 THIS ZEROS ICNT RET . RETURN C HAS LINE LENGTH * INL0 CALL CRLF ENTRY THAT RE-GETS A LINE * * THIS IS THE ENTRY TO GET A LINE * INLINE EQU $ LDA PHEAD STA TOPT SAVE PHEAD IF SOLOS CALL READR GET VDM ADDRESS TO 'VDMAD' ENDF INL9 LXI H,IBUF1 READ CHARACTRERS INTO IBUF MOV D,H HL=PRESENT POSITION, DE=LAST CHARACTER POSITION MOV E,L INITIALY SAME AT FIRST XRA A MOV C,A C COUNTS THE NUMBER OF CHARACTERS IN THE LINE * INL1 LDA DIRF ORA A JNZ INL1B NO COUNT LIMIT IN DIRECT MODE * LDA ICNT GET INPUT COUNT LIMIT ORA A SET? JZ INL1B NO, CONTINUE CMP C EQUAL? JZ PCR COUNT'S UP....SNIKER...SINKER * INL1B PUSH H GET NEXT CHARACTER PUSH B PUSH D CALL IF1 GET CHARACTER POP D POP B MOV B,A JC INLSD SPECIAL DISPATCH POP H * LDA INSFG TEST INSERT FLAG ORA A JNZ INSRT INSERT ON * CALL HDCMP CMP HL-DE JNZ INL2 DIDN'T PASS DE (POINTER NEXT EMPTY CELL) MOV A,C CPI LINMAX-2 JNC INL1 GREATER THAN OR EQU TO, DONT KEEP IT INX D INR C * INL2 MOV M,B PUT IN BUFFER CALL OF2 PRINT IT INX H JMP INL1 NEXT CHARACTER * * * DISPATCH TO A SPECIAL CHARACTER HANDLER * INLSD CALL LHLI GET ROUTINE ADDRESS TO HL XTHL . SAVED HL TO HL, ROUTINE ADDRESS TO STACK RET . GOTO ROUTINE (NOT A CALL) * * PROCESS BACK SPACEING * PBS CALL HDCMP AT END OF LINE? JNZ PBS0 JMP IF IN MIDDLE XRA A A=0 CMP C IS C = 0 ? JZ INL9 YES, LINE IS EMPTY DCX H DCX D BACK UP BOTH POINTERS DCR C PBS9 MVI B,05FH THIS GOES BACK ON THE SOLOS VDM DRIVER CALL OF2 PRINT IT JMP INL1 CONTINUE * PBS0 DCR C ONE LESS CHARACTER JZ INL9 LINE NOW EMPTY IF PTDOS DCX H BACKUP ONE CHARACTER ENDF PUSH H * PBS1 INX H SHIFT IT ALL DOWN MOV A,M DCX H MOV M,A INX H CALL HDCMP JNZ PBS1 DCX D EOL ADDR POP H CHR POINTER IF PTDOS JMP PBS9 DO BACKSPACE ON VDM ENDF IF SOLOS JMP INL1 NEXT CHARACTER ENDF IF SOLOS * * PROCESS LEFT CURSOR MOVEMENT * PLFT PUSH D LXI D,IBUF1 CALL HDCMP ALL THE WAY LEFT ALREADY? POP D JZ INL1 YES, IGNORE DCX H ENDF * PCKEY MVI A,80H TURN ON HIGH BIT FOR SOLOS ORA B MOV B,A * PECHO CALL OF2 PRINT CHARACTER JMP INL1 CONTINUE * * PROCESS RIGHT MOVEMENT * PRIT CALL HDCMP JNC INL1 ALREADY ALL THE WAY OVER! IF PTDOS MOV B,M GET CHARACTER FROM BUFFER ENDF INX H MOVE IF SOLOS JMP PCKEY ENDF IF PTDOS JMP PECHO ENDF * * PROCESS INSERT MODE ON/OFF * PIOFF XRA A INSERT MODE OFF PION STA INSFG SET INSERT FLAG JMP INL1 CONTINUE * * INSERT MODE * INSRT MOV A,C CPI LINMAX-2 DOES IT FIT? JNC INL1 NO, IGNORE COMMAND INR C INX H INX D PUSH B SAVE CHARACTER (IN B) IF SOLOS MVI B,KRIGHT MOVE CURSOR RIGHT ONE ENDF CALL OF2 IF PTDOS, ECHO CHR; ELSE MOVE CURSOR POP B PUSH H DCX H * INST1 MOV A,M SHIFT CHARACTERS UP MOV M,B MOV B,A CALL HDCMP DONE? INX H JC INST1 NO, KEEP LOOPING * INST2 EQU $ IF SOLOS LHLD XOPORT MOV A,M TEST FOR NON-VDM OUTPUT PORT ORA A JNZ INST4 NOT ON VDM, DON'T CHANGE SCREEN * PUSH D SAVE POINTER TO END OF BUFFER PUSH B SAVE CHARACTER COUNT AND INPUT CHARACTER LXI D,IBUF1 BUFFER POINTER LHLD VDMAD SCREEN POINTER MOV A,C CHARACTER COUNT TO MOVE CPI 63+1 JC INST3 MVI C,63 MOVE A MAX OF 63 CHARACTERS * INST3 XCHG MOV B,M CHARACTER FROM IBUF1 XCHG MOV A,M CHARACTER FROM SCREEN ANI 80H EXTRACT "CURSOR" BIT ORA B ADD "CURSOR" BIT TO B MOV M,A CHARACTER TO VDM SCREN INX H INX D DCR C DONE? JNZ INST3 * MOV A,M FORCE LAST CHARACTER TO BLANK ANI 80H PRESERVE "CURSOR" BIT ORI 20H MAKE LAST CHARACTER BLANK MOV M,A * POP B POP D INST4 EQU $ ENDF POP H JMP INL1 DONE INSERTING/DELETING, CONTINUE IF SOLOS * * * READ VDM SCREEN ADDRESS * READR XRA A STA INSFG INIT INSFG TO OFF MVI B,KESC CALL ZOUT MVI B,4 THE PROPER CODE TO GET ADDRESS CALL ZOUT MOV H,B MOV L,C SHLD VDMAD SAVE ADDRESS RET * * OUTPUT TO PORT ZERO (VDM) * ZOUT XRA A XAOUT EQU $ JMP AOUT OUTPUT AND RETURN * ENDF * * * * * * SPECIAL CHARACTER TABLE * SCHRT DB CR DW PCR DB BS DW PBS DB KRIGHT DW PRIT DB KCAN DW INL0 IF SOLOS DB KLEFT DW PLFT ENDF DB KION DW PION DB KIOFF DW PIOFF DB KLF DW PLF SCHRZ EQU $-SCHRT/3 TABLE LENTH IN ENTRIES * * * * I/O RELATED RAM * IF SOLOS VDMAD DS 2 VDM ADDRESS XOPORT DS 2 XIPORT DS 2 ENDF ITIM DS 2 INPUT TIME LIMIT ICNT DS 1 INPUT COUNT LIMIT LINLEN DS 1 LENGTH OF A LINE TWIDTH DB 14 WIDTH OF A COMMA TAB FIELD PHEAD DS 1 PRINTER HEAD POSITION * DS 1 FOR THE '!' OBUF DS WMAX+1 FOR NUMERIC CONVERTIONS EOBUF DS 1 FOR THE '"' * IBCNT DS 1 CURRENT LINE LENGTH (OF INCOMMING LINE) IBLN DS 2 CURRENT LINE NUMBER (OF INCOMMING LINE) IBUF DS LINMAX/2 THE I/O BUFFER IBUF1 DS LINMAX * * * STACK DEFINITION * STKTOP DS SSIZE THE STACK CMNDSP EQU STKTOP+SSIZE-1 ADDR OF TOP OF STACK CSPM1 EQU CMNDSP-1 SPCMND EQU CMNDSP/256*256 TSTKA DS 2 TOP OF ARG STACK POINTER SPTR DS 2 STACK SAVE FOR 'CONTINUE' * *