* * * * VERSION 2.0 * JANUARY 30, 1983 * * * * VDMBASE EQU 0F800H McVideo 24x80 screen * For SOLOS at F000 Hex * * EDIT1 LXI SP,AREA+18 LHLD BFP PUSH H CALL INITS CLEAR SCREEN SUB A MOV B,A CALL SCUR SET CURSOR TO LINE 0, CHR 0 POP H SHLD FFLNP * * Entry point from BMOV, HIGFN, FIND, etc. * * * * * * * * * * * * * * * * * * * RE-ENTRY POINT FROM SOLOS * * * * * * * * * * * * * * * * * * REENT CALL WPAG * * COMMAND DISPATCHER * DISPO CALL DISP GET COMMAND AND PROCESS JMP DISPO * DISP CALL SCCUR TURN ON THE CURSOR CALL CONIN ANI 7FH DISPT CPI SPACE CHECK FOR CONTROL CHAR JNC CHAR CPI 'A'-40H LEFT CURSOR JZ LCUR CPI 'S'-40H RIGHT CURSOR JZ RCUR CPI 'H'-40H DELETE CHAR JZ DELC CPI 'T'-40H TOGGLE INSERT MODE JZ IMOD CPI 'I'-40H TAB JZ TABOVER PUSH PSW UPDATE FILE BEFORE MODIFING SCREEN CALL UPDT POP B CHR IS IN B LXI H,CTABL POINT TO COMMAND TABLE * TSRCH MOV A,M ORA A RZ . IT'S A PHONEY CMP B TEST FOR MATCH INX H JZ CDISP INX H INX H JMP TSRCH * * COMMAND FOUND-- DISPATCH TO IT * CUST LXI H,CADDR POINT TO CUSTOM COMMAND CDISP MOV A,M GET LOW BYTE INX H MOV H,M MOV L,A PCHL . GO DO IT * * * TABLE FOR ALL LEGAL COMMANDS * CTABL DB 'W'-40H UP CURSOR DW UCUR * DB 'Z'-40H DOWN CURSOR DW DCUR * DB 'E'-40H UP SCROLL DW USCR * DB 'X'-40H DOWN SCROLL DW DSCR * DB 'R'-40H ROLL UP 20 LINES DW UPAG * DB 'C'-40H DOWN 20 LINES DW DPAG * DB 10 LINE FEED DW LFD * DB 'B'-40H INSERT LINE DW CTLB * DB 13 CR DW CRET * DB 'P'-40H DELETE LINE DW DLIN * DB 'F'-40H EXIT EDITOR DW DONE * DB 'O'-40H --FIND COMMAND DW ENTRY * DB 'L'-40H --FIND REPEAT DW EOVEP * DB 'Y'-40H COMGET DW COMGET * DB 'Q'-40H SET CURSOR DW CSET * DB 'U'-40H USER COMMAND DW CUST * DB 'V'-40H HIGHER FUNCTIONS DW HIGFN * DB 1BH "ESC" EDIT ABORT DW ABORT * DB 0 TERMINATOR * CSET XRA A STA CCP MVI A,10 Put cursor on 10th line JMP UCUR2 * * EXIT EDITOR * DONE CALL SAVCUR Save current cursor pos. in case mistake. CALL INITS CALL OUST DW 0A0DH ASC "*** Editor exit DW 0A0DH DW 0DH ZERO TERMINATES LHLD BFP CALL OUT16 CALL OUST ASC " File start address DW 0A0DH DB 0 LHLD EFP CALL OUT16 CALL OUST ASC " File end address DW 0A0DH DB 0 LHLD EFP XCHG LHLD BFP MOV A,E SUB L MOV L,A MOV A,D SBB H MOV H,A INX H CALL OUT16 CALL OUST ASC " File count DW 0A0DH DW 0A0DH ASC /OK to write to "/ DB 0 LXI H,OFILE CALL PRINT Print outfile's name. CALL OUST ASC /"? / DB 0 CALL CONIN PUSH PSW CALL CONOUT POP PSW CALL MAP CPI 'Y' JNZ HRET1 User doesn't want to exit. * * Open the output file. Create it if necessary. * OPNIT LXI D,OFILE DE->file's name (for PSCAN) LXI H,OFILE HL is where PSCAN will read from. MVI A,PSCO+40H open file, create if necessary CALL PSCAN MOV A,E get error # or file # JC OER1 error STA OFNUM file number LXI D,GPRAM start of file * * Write new code to file. * OUTLUP LDAX D get bytecount (length of line) MVI B,0 MOV C,A BC=max xfer count for write LDA OALS8 Should we write in ALS8 format? CPI YES JZ OPNT1 Yes. Bytecount goes along with line. INX D Skip length byte DCX B and transfer one less byte. OPNT1 LDA OFNUM MVI L,CR delimiter (end of line) CALL SYS DB DWROP delimited write JMP OER1 DCX D Did we just write (or skip) the eof marker? LDAX D INX D CPI EOF done? JNZ OUTLUP Nope. Continue. * * END FILE * LDA OFNUM CALL SYS DB EOFOP JMP OER1 * * CLOSE FILE * CLOST LDA OFNUM CALL SYS DB CLOOP JMP OER1 EXIT LHLD SYSGLO Reset error handling. LXI D,GLERM DAD D XCHG LHLD ERRET XCHG MOV M,E INX H MOV M,D SYSRT CALL SYS DB RETOP * ABORT CALL SAVCUR Save current cursor position. CALL INITS User hit ESC -- was it an accident? CALL OUST ASC /Abort? / DB 0 CALL CONIN PUSH PSW CALL CONOUT Echo. POP PSW CALL MAP CPI 'Y' JZ EXIT JMP HRET1 User didn't want to abort. * SAVCUR LDA CLN Current line position. STA CLNSAV LDA CCP Current character position. STA CCPSAV RET * OER0 MVI A,ERNAX NAME EXPECTED ERROR OER1 CALL SYS DB ABTOP RER1 EQU OER1 ERTOB CALL OUST DW 0A0DH ASC "Edit aborted DW 0A0DH ASC 'Load exceeds buffer space DW 0A0DH DB 0 LDA SFNUM Close the source file. CALL SYS DB CLOOP JMP OER1 JMP EXIT * COER1 CPI ERNEX JNZ OER1 LXI D,OTYPE CREATE CALL SYS DB CREOP JMP OER1 JMP OPNIT * OUST POP H OUST5 MOV A,M FETCH CHAR INX H ORA A JZ OUST9 CALL CONOUT JMP OUST5 OUST9 PCHL * OUT16 MOV A,H CALL OUT8 MOV A,L * OUT8 MOV C,A RAR RAR RAR RAR CALL OUT8A MOV A,C * OUT8A ANI 15 ADI 144 DAA ACI 64 DAA JMP CONOUT * * HIGFN CALL SAVCUR Save current cursor address. CALL INITS Clear screen. HIG1 CALL PROMPT get command LXI H,IBUF LXI D,COMT2 command table for CNTL-V commands CALL FDCOM find command in table JZ HRET1 bad command LDAX D DE-> addr of routine to process this command MOV L,A put this address in HL INX D LDAX D MOV H,A PCHL . go to the routine * * The following are the routines which process the * HIGFN commands. They are called by the above PCHL. * Some of these routines just change the value of * CADDR -- the address of the routine executed when * CNTL-U is hit. * HTAB LXI H,TAB change custom command to 'tab' HRET SHLD CADDR HRET1 CALL INITS LDA CCPSAV Get old cursor position back. MOV B,A LDA CLNSAV CALL SCUR JMP WPAG back to editor * * HNULL LXI H,NULRET change custom command to 'null' JMP HRET * * HBMOV LXI H,BMOV change custom command to block move JMP HRET * * * This routine replaces the current line with an * EOF marker (a byte containing a 1), effectively * making the line before the current one the last * line in the file. After doing so, it returns * to the editor with the last line at the bottom * of the screen (unless the file is too small for that). * ENDIT LHLD CFLNP Get pointer to first byte of current line CALL BTEST See if it is the only line. JZ HRET1 Yep. Can't do anything. MVI M,EOF Make that the end of the file. SHLD EFP Make end-of-file pointer point correctly. LDA CLNSAV Now roll the screen down so that the last line MOV B,A in the file is the last line on the screen. MVI A,24 We need to roll down 24-CLNSAV lines. SUB B Set A=24-CLNSAV * ROLLEM PUSH PSW Save loop counter. CALL DFLNP Down one li. JZ ROLL1 We are at the beginning of the file. POP PSW DCR A Done yet? JNZ ROLLEM Nope. JMP ROLL2 Okay. Back to editor. * * ROLL1 POP PSW We can't roll down any more. ROLL2 PUSH PSW Save A. CALL INITS Clear screen and put cursor on last line. POP PSW MOV B,A MVI A,23 SUB B Bottom line is 23-A MVI B,0 Cursor goes to left edge of this line. CALL SCUR Set cursor. JMP WPAG Back to editor. * * * This routine makes the current line the first one in * the file, deleting all previous lines. * BEGIT LHLD BFP Get pointer to beginning of file. XCHG . DE-> start of file LHLD CFLNP Get pointer to 1st byte of current line. SCOOT MOV A,M Scoot this part of file to the beinning. STAX D CPI EOF Did we just scoot the end-of-file marker? JZ BEG00 Yep. All done. INX H Next source byte. INX D Next destination byte. JMP SCOOT Continue. BEG00 XCHG . HL is where we put last char (the EOF mark) SHLD EFP Make end-of-file pointer right. JMP EDIT1 Print first 24 lines of file on screen. * * * Routine to move to the last line of the file and * leave the cursor there. * LASTLN LHLD EFP HL-> the eof mark SHLD FFLNP Make that the first line. MVI A,24 Roll backwards 24 lines. JMP ROLLEM We already have it in ENDIT. * * * Routine to find the two-letter command pointed to * by HL in the table pointed to by DE. If no match * return with Z flag set. * FDCOM LDAX D ORA A Test for table end. RZ . Not found. PUSH H Save start of command address. MOV B,A Save the character from the table. MOV A,M Get 1st character of command. CALL MAP Make sure it's upper case. CMP B Compare with table entry. INX D JNZ NCOM Didn't match. INX H LDAX D MOV B,A Save table char. MOV A,M Get 2nd char of command. CALL MAP CMP B JNZ NCOM Didn't match. * POP H Restore original scan address. ORA A Set non-zero flag (reset Z) since found. INX D Make DE-< address of handling routine. NULRET RET . Success. (also used as a do-nothing routine) * * NCOM INX D Go to next entry. INX D INX D POP H Get back start of command. JMP FDCOM Continue search. * * * Command table for HIGFN (CNTL-V) commands. * COMT2 ASC 'TA' Set custom command to 'tab' DW HTAB ASC 'NU' Set custom command to do nothing. (Null) DW HNULL ASC 'BM' Set custom command to Block Move. (BMOV) DW HBMOV ASC 'EN' Make current line of file the end of the file. DW ENDIT (deletes current line and all following) ASC 'ST' Make current line the first line in the file. DW BEGIT (deletes all lines preceding current line) ASC 'FL' Move to first line of file. DW EDIT1 ASC 'LL' Move to last line of file. DW LASTLN ASC 'PA' Execute pattern matching code. DW RPAT ASC 'IF' INSERT FILE DW IFILE ASC 'TS' SET TAB STOPS DW TABSET DB 0 End of table marker. * * Tab command. * TAB CALL CCCUR CALL CONIN SUI 30H JMP LCUR1 * * * SET TAB STOPS * DELAY EQU 0E00H TABSBASE EQU 0FD00H Line 17 * TABSET EQU $ * LXI D,TABSBASE LOAD TAB MAP TO SCREEN LXI H,TABMAP CALL MOVE * CTRL3 LXI H,TABSBASE CTRL4 MOV B,M SAVE CHARACTER MVI A,080H IF CURSOR IS ON TURN IT OFF ORA M MOV M,A CALL GETCHR GET CONSOLE CHAR WHILE FLASHING CURSOR MOV M,B * CPI 'A'-040H CURSOR LEFT ONE POSITION PUSH PSW CZ LEFT1 POP PSW * CPI 'S'-040H CURSOR RIGHT ONE POSITION PUSH PSW CZ RIGHT1 POP PSW * CPI 'I'-040H SET OR RESET A TAB STOP JNZ CTRL0 MOV A,M XRI 080H THE 7 BIT WILL TELL THE TELL MOV M,A CALL RIGHT1 MOVE ONE POSITION TO RIGHT JMP CTRL4 * CTRL0 CPI 'C'-040H CLEAR ALL TAB STOPS JNZ CTRL2 LXI H,TABSBASE MVI C,80 CTRL1 MOV A,M ANI 07FH MOV M,A INX H DCR C JNZ CTRL1 JMP CTRL3 * CTRL2 CPI CR JNZ CTRL4 * LXI H,TABSBASE REWRITE TAB MAP LXI D,TABMAP CALL MOVE JMP HRET1 ALL DONE. * MOVE EQU $ MOVE 80 BYTES STARTING AT HL TO DE * MVI B,80 MOV1 MOV A,M STAX D INX H INX D DCR B RZ JMP MOV1 * LEFT1 EQU $ DECREMENT CURENT CURSOR POSITION BY 1 * DCX H MOV A,L ORA A RP MVI L,79 INR H Back to line 17 RET * RIGHT1 EQU $ INCREMENT CURRENT CURSOR POSITION BY 1 * INX H MOV A,L CPI 50H Line 18 RNZ MVI L,0 Back to line 17 RET * GETCHR EQU $ GETS ONE CHARACTER. FLASHES CURSOR WHILE WAITING MOV A,M PUSH PSW GETC1 PUSH H LXI H,DELAY GETC2 CALL CONTST JNZ GETIT DCX H MOV A,H ORA L JNZ GETC2 MVI A,080H POP H XRA M MOV M,A JMP GETC1 * GETIT POP H POP PSW MOV M,A CALL CONIN RET * * TABMAP ASC '123456' DB '7'+080H ASC '890123' DB '4'+080H ASC '567890' DB '1'+080H ASC '234567' DB '8'+080H ASC '901234' DB '5'+080H ASC '678901' DB '2'+080H ASC '345678' DB '9'+080H ASC '012345' DB '6'+080H ASC '789012' DB '3'+080H ASC '456789' DB '0'+080H ASC '123456' DB '7'+080H ASC '890' DB 080H * * * MOVE CURSOR TO NEXT TAB STOP * TABOVER CALL CCCUR REMOVE THE CURSOR FROM THE SCREEN. PUSH H SAVE THE ADDRESS OF THE CURSOR COLUMN. * LXI H,TABMAP POINT TO THE TAB TABLE. MOV A,B USE THE CURRENT CURSOR POSITION ADD L TO MOVE TO THE CORRESPONDING TABLE ENTRY. MOV L,A MVI A,0 ADC H MOV H,A * TAB0 INX H MOVE TO THE NEXT COLUMN. MOV A,M LOOK AT IT. ORA A IS THE HIGH BIT SET? JP TAB0 NOPE, KEEP LOOKING. * LXI D,-TABMAP GET COUNT OF BYTE IN TABLE. DAD D MOV A,L A IS NOW 1 TO 80 CPI 80 JC TAB1 XRA A MAKE 80 BE 0. TAB1 POP H GET BACK ADDRESS OF CURSOR COLUMN. MOV M,A UPDATE IT. JMP SCUR1 PUT NEW CURSOR ON SCREEN AND RETURN. * * * REPEAT COMMAND * COMGET CALL CONIN GET COMMAND STA BBUF SAVE IN BBUF CALL CONIN SUI 30H * COMDO PUSH PSW SAVE NUMBER OF TIMES LDA BBUF CALL DISPT DO COMMAND POP PSW DCR A RZ JMP COMDO NOT ZERO--DO THE NEXT * * * SCROLL DOWN ONE LINE * DSCR CALL DFLNP JNZ WPAG SCROLL DOWN IF NOT LAST LINE * * * UP CURSOR * UCUR LDA CLN DCR A JP UCUR2 LDA LVLN WRAP AROUND UCUR2 STA CLN * * FILL WHOLE SCREEN WITH TEXT STARTING AT FFLNP * WPAG LHLD FFLNP GET FIRST FILE LINE ON SCREEN SHLD LFLNP NOW IT'S THE LAST XRA A STA IMODF PUSH PSW WPAG1 STA LVLN XCHG LXI H,CLN CMP M XCHG JNZ WPAG3 SHLD CFLNP * WPAG3 CALL CFTS WPAG2 POP PSW INR A CPI 24 RZ MOV B,A CALL ILLNP XCHG . TO GET ADDRESS TO HL MOV A,B PUSH PSW * JNZ WPAG1 MVI B,0 COPY GARBAGE TO SCREEN MVI C,GARB MVI H,80 MVI L,1 CALL BLOT JMP WPAG2 * * * SCROLL UP 20 LINES * UPAG MVI A,20 UPAG0 PUSH PSW CALL ILLNP SEE IF POSSIBLE TO UP SCROLL CNZ USCR1 POP PSW DCR A JNZ UPAG0 RET * * SCROLL DOWN 20 LINES * DPAG MVI A,20 DPAG0 PUSH PSW CALL DFLNP CNZ WPAG POP PSW DCR A JNZ DPAG0 RET * * FILE SPACE EXHAUTED MESSAGE * TOOBG LXI D,TBMSG SHOW ERROR MESSAGE AT CURRENT LINE MVI C,17 LDA CLN CALL CLTS TOOB0 CALL CONIN WAIT FOR CTRL-Q CPI 17 JNZ TOOB0 LDA IFNUM IS INSERT FILE OPEN? CPI -1 JZ EDIT1 NOPE CALL SYS YEP--CLOSE IT DB CLOOP NOP . IGNORE ERRORS NOP . NOP . CALL IFRESET RESET DRIVE NOT READY TRAP JMP EDIT1 * TBMSG ASC 'Full--type CTRL Q' * * LEFT CURSOR * LCUR CALL CCCUR MOV A,B DCR A JP LCUR1 MVI A,80-1 LCUR1 CPI 80 JNZ LCUR2 XRA A LCUR2 MOV M,A JMP SCUR1 * * DOWN CURSOR * DCUR LDA CLN LXI H,LVLN CMP M JNZ DCUR1 MVI A,0FFH WRAP AROUND DCUR1 INR A JMP UCUR2 * * TOGGLE CHARACTER INSERT MODE * IMOD LDA IMODF XRI 1 STA IMODF RET * * BLANK REST OF LINE, HOME CURSOR AND SCROLL UP * LFD CALL CPHL MOV A,B Put CCP in A LFD1 MVI M,BLANK BLANK REST OF LINE LOOP INX H INR A CPI 79 EOL? JNZ LFD1 CALL UPDT SUB A HOME CURSOR STA CCP * * SCROLL UP ONE LINE * USCR CALL ILLNP JZ DCUR USCR1 LXI H,FFLNP UPDATE FIRST LINE POINTER CALL ILNP JMP WPAG * * Carriage Return * Blank to EOL and append blank line * CRET LXI H,CFLNP CALL ILNP INCREMENT CURRENT LINE JNZ CRET1 LHLD EFP MOVE POINTERS TO END OF FILE IF APPENDING SHLD CFLNP CRET1 CALL INSL INSERT BLANK LINE IN FILE XRA A HOME CURSOR STA CCP LDA LVLN CPI 23 LDA CLN JNZ DCUR1 LXI H,FFLNP CALL ILNP JMP WPAG DB 1 * * Control B * INSERT BLANK LINE BEFORE CURSOR LINE * CTLB CALL INSL XRA A STA CCP JMP WPAG * * DELETE CURRENT CURSOR LINE * DLIN SUB A STA IMODF LHLD BFP Don't delete only line in file! MOV A,M CALL DADD MOV A,M CPI EOF RZ CALL ILLNP TEST FOR MOVING TEXT DOWN INSTEAD OF UP JNZ DLIN0 BOTTOM LINE NOT LAST LINE IN FILE CALL DFLNP * DLIN0 PUSH PSW PUSH CONDITION FOR LATER TEST LHLD CFLNP DELETE LINE FROM FILE MOV A,M CMA INR A CALL EXPN POP PSW RECOVER ABOVE CONDITION STATE JNZ WPAG LHLD CFLNP UP CURSOR IF LAST LINE DELETED MOV A,M CPI EOF JZ UCUR JMP WPAG * * PUT INPUT CHARACTER INTO FILE * CHAR MOV C,A LDA IMODF ORA A JNZ INSC NZ means insert mode is on * REPLACE CHARACTER OF CURRENT CURSOR WITH CHAR IN C CALL CPHL MOV M,C * * RIGHT CURSOR * RCUR CALL CCCUR MOV A,B INR A JMP LCUR1 * * INSERT CHARACTER IN C AT CURRENT CURSOR POSITION * MOVING REST OF LINE TO RIGHT, RIGHTMOST CHARACTER IS LOST * INSC CALL CPHL MOV A,C ORI 80H MOV C,A PUSH B INSC1 MOV A,M MOVE CHAR ONE TO RIGHT ANI 7FH CLEAR CURSOR BIT MOV M,C MOV C,A INX H INR B MOV A,B CPI 80 TEST IF END OF LINE JNZ INSC1 POP B JMP RCUR * * DELETE CHARACTER AT CURRENT POSITION AND MOVE * REST OF LINE LEFT * DELC CALL CPHL LDA CCP CPI 80-1 JC DELC0 MVI M,SPACE+80H CURSOR AND SPACE RET * DELC0 MOV E,L Save old CCP addr LDA CLN Get line number MVI B,79 Set CCP at rt margin CALL CLNA Get EOL addr MOV A,E A has CCP MVI C,BLANK * Move the line over DELC1 MOV B,M MOVE CHAR LEFT DELC2 MOV M,C MOV C,B DCX H CMP L JNZ DELC1 LOOP UNTIL FOUND * DELC3 MOV A,B DELC4 ORI 80H TURN ON CURSOR MOV M,A RET * * INSERT BLANK LINE BEFORE CURRENT LINE * INSL MVI A,2 CALL EXPN MAKE SPACE FOR LINE LHLD CFLNP MVI M,2 SET CHAR COUNT INX H MVI M,CR SET CARRIAGE RETURN RET * * INCREMENT LINE POINTER ADDRESSED BY HL BY ONE LINE * RET CARRY=0 IF HIT EOF, DOES NOT CLOBBER BC * RET DE IS NEW POINTER VALUE * ILLNP LXI H,LFLNP SPECIAL ENTRY POINT FOR LFLNP ILNP MOV E,M INX H MOV D,M LDAX D XCHG CALL DADD XCHG LDAX D DCR A TEST FOR END OF FILE RZ . CARRY IS ZERO IF RET * ILNP1 MOV M,D PUT POINTER BACK IN MEMORY DCX H MOV M,E RET * * DECREMENT LINE POINTER FFLNP * RET ZER0 SET IF HIT BEGINNING OF FILE * DFLNP LHLD FFLNP CALL BTEST RZ DLNP1 DCX H DLNP0 DCX H CALL BTEST JZ DLNP2 MOV A,M CPI CR JNZ DLNP0 DCX H MOV A,M CPI CR JZ DUPLI INX H DUPLI INX H DLNP2 INR A SHLD FFLNP RET * * COMPARE H,L AGAINST BEGINNING OF FILE * BTEST LDA BFP SUB L LDA BFP+1 SBB H RNZ LDA BFP SUB L ORA A CLEAR CARRY RET * * COPY MODIFIED CURSOR LINE BACK INTO TEXT FILE * UPDT CALL CCCUR LDA CLN GET LENGTH OF CURRENT LINE ON SCREEN CALL LEN INR C INR C MOV A,C * OVER LHLD CFLNP SUB M CALL EXPN MAKE ROOM FOR LINE EXACTLY RIGHT LHLD CFLNP COPY CHARACTER COUNT TO FILE MOV M,C DCR C DCR C INX H XCHG LDA CLN CALL CSTL COPY SCREEN TEXT TO FILE XCHG . D,E POINT AFTER TEXT OF LINE MVI M,CR COPY CARRIAGE RETURN TO FILE RET * * EXPAND FILE CONTRACT IF A NEG BY A BYTES FROM CFLNP * DOES NOT CLOBBER C, RESTARTS TXED IF FILE OVERFLOWS * EXPN MOV B,A ORA A RZ JM SQ * * SPREAD CASE * LHLD EFP SET UP DESTINATION ADDRESS CALL DADD LXI D,EOSP CALL DCMP JC TOOBG XCHG LHLD CFLNP DCX H PUT STOP MARKER TEMPORARILY IN FILE MVI M,EOF+80H LHLD EFP SETUP SOURCE ADDRESS * SPR0 MOV A,M CPI EOF+80H JZ SPR2 STAX D DCX H DCX D JMP SPR0 * SPR2 MVI M,CR PUT CR BACK IN PLACE OF STOP MARKER SPR1 LHLD EFP UPDATE END OF FILE POINTER MOV A,B CALL DADD SHLD EFP LHLD LFLNP UPDATE LAST LN PTR LXI D,CFLNP CALL DCMP RZ MOV A,B CALL DADD SHLD LFLNP RET * * SQUEEZE CASE * SQ CMA INR A LHLD CFLNP CALL DADD SETUP SOURCE ADDRESS XCHG LHLD CFLNP SETUP DESTINATION ADDRESS SQ0 LDAX D MOV M,A CPI EOF JZ SPR1 INX H INX D JMP SQ0 * * ADD A TO H,L, CLOBBERS A * DADD ORA A JM DADD1 ADD L MOV L,A RNC INR H RET * DADD1 ADD L MOV L,A MVI A,0FFH ADC H MOV H,A RET * * COMPARE H,L AGAINST VALUE ADDRESSED BY D,E * DCMP LDAX D SUB L INX D LDAX D SBB H DCX D RC RNZ LDAX D HIGH ORDER OK NOW TEST FOR ZERO SUB L ORA A CLEAR CARRY RET * * INITIALIZE SCREEN * INITS CALL INI1 CALL VDMOT MVI A,CR CALL CONOUT RET * INI1 LXI H,VDMBASE IL2 MVI M,BLANK INX H MOV A,H CPI 0FFH PAST END? (FF80) JNZ IL2 MOV A,L CPI 080H JNZ IL2 XRA A STA BOSL STA BOTL STA CCP MVI A,23 STA CLN RET . * * OUTPUT BOSL AND BOTL TO VDM * VDMOT LDA BOSL RLC RLC RLC RLC LXI H,BOTL ORA M OUT VDMDEV OUT 0FEH FOR SOL RET * * INCREMENT CHARACTER POSITION AND WRAP AROUND IF * NECESSARY EXPECTS ADDRESS IN H-L, CLOBBERS ACC * INCP INX H MOV A,D D has -CCP DCR A RNZ PUSH B LXI B,-80 Subtract a line DAD B POP B RET * * PUTS ADDRESS OF CURRENT POSITION IN HL * CPHL LDA CLN LXI H,CCP MOV B,M * * CONVERT LINE NUMBER A AND CHAR POS B TO ADDRESS IN HL * Must preserve BC * CLNA MOV L,A LDA BOTL LOAD THE OFFSET FOR LINE 0 ADD L Now A has line num CLNA1 CPI 24 JC CLNA2 SUI 24 JMP CLNA1 CLNA2 PUSH D LXI H,VDMBASE-80 LXI D,80 CLNA3 DAD D DCR A JP CLNA3 MOV E,B DAD D POP D RET * * COPY FILE LINE AT HL TO LINE A ON SCREEN * CFTS MOV C,M DCR C DCR C INX H XCHG * * COPY COUNT C CHARACTERS TO LINE A ON SCREEN FROM SOURCE * ADDRESS DE AND BLANK THE 80 MINUS COUNT CHRS * CLTS MVI B,0 CALL CLNA LEAVES ADDRESS IN HL MVI B,80 SET UP COUNT FOR FULL LINE CLTS0 XRA A ZERO ACC CMP C SEE IF NON-BLANK PART OF SCREEN IS DONE MVI A,BLANK IN CASE WE TAKE THE NEXT BRANCH JZ CLTS1 GO IF FILLING IN BLANKS LDAX D INX D INCREMENT SOURCE ADDRESS DCR C DECREMENT COUNT IF NON-BLANK PART * CLTS1 MOV M,A WRITE THE CHARACTER TO SCREEN INX H INCREMENT SCREEN ADDRESS DCR B DECREMENT TOTAL COUNT JNZ CLTS0 RET * * COPY COUNT C CHARACTERS FROM SCREEN LINE A TO DEST * ADDRESS DE C <=80 * CSTL MVI B,0 SET CHARACTER POSITION TO LEFT MARGIN CALL CLNA PUT SCREEN ADDRESS IN HL INR C CSTL0 DCR C RZ MOV A,M STAX D WRITE CHARACTER TO DEST ADDR INX H INX D JMP CSTL0 * * RETURN LENGTH OF SPECIFIED LINE A IN REGISTER C * LEN MVI B,80-1 CHARACTER POSITION OF RIGHT MARGIN CALL CLNA SCREEN ADDRESS IN HL MVI C,80 INITIALIZE COUNT TO BE RETURNED * LEN0 MOV A,M READ RIGHTMOST CHARACTER ANI 7FH CPI BLANK RNZ DCX H DECREMENT LINE ADDRESS DCR C DECREMENT CHARACTER COUNT JNZ LEN0 LOOP UNLESS WHOLE LINE HAD BLANKS RET * * CLEAR CURSOR FROM LINE A AND CHARACTER POSITION B * CCUR CALL CLNA MOV A,M ANI 7FH MOV M,A RET * * BLOT RECTANGLE WITH UPPER LEFT CORNER AT LN ACC, CHAR * POS DX H, DY L WITH CHARACTER C * BLOT XCHG . GET DX,DY TO D-E BLOT0 PUSH PSW SAVE THE LINE ADDRESS PUSH D SAVE DX,DY CALL CLNA COMPUTE VDMEMORY ADDRESS TO HL BLOT1 MOV M,C COPY CHARACTER TO MEMORY CALL INCP DCR D JNZ BLOT1 POP D GET NEW COPY OF DX,DY POP PSW GET LINE NO BACK IN ACC DCR E DECREMENT DY RZ INR A INCREMENT LINE NO JMP BLOT0 * SCCUR LDA CCP SCUR1 MOV B,A LDA CLN * * * SET CURSOR TO LINE A AND CHARACTER POSITION B * SCUR CPI 24 JC SCU1 XRA A SCU1 STA CLN CALL CLNA MOV A,B STA CCP MOV A,M JMP DELC4 * * CLEAR CURRENT CURSOR, LEAVE HL WITH ADDR OF CCP * CCUR0 STA CURF CCCUR LXI H,CCP MOV B,M LDA CLN CALL CCUR DOESN'T CLOBBER B LXI H,CCP RET * * * FIND FOR EDITOR * * ENTRY CALL INITS CLEAR THE SCREEN CALL PROMPT GET SEARCH CHRS LXI SP,AREA+18 LHLD BFP START AT BEGINNING JMP EOVE1 * * LOOP THROUGH FILE * EOVEP LXI SP,AREA+18 LHLD CFLNP HL-> current line's length byte. MOV A,M CALL ADR Set HL=HL+length. MOV A,M Get next line's length byte. CPI EOF Were we on the last line? JZ EDIT1 Yep -- present start of file. EOVE1 CALL SEARCH CPI EOF END OF FILE? JZ EDIT1 YES, PRESENT START OF FILE * NOW CLEAR SCREEN AND RETURN CALL INITS MVI B,0 MVI A,5 Ret with cur at line 6 CALL SCUR LHLD ATEMP SHLD FFLNP MVI A,5 EOVE2 PUSH PSW CALL DFLNP Ret with found string on line 6 POP PSW DCR A JNZ EOVE2 JMP REENT * * PRINT PROMPT AND GET INPUT LINE * PROMPT MVI A,':' CALL CONOUT MVI E,0 LXI H,IBUF * NEXT2 CALL CONIN MOV B,A CPI 7FH Delete? JNZ CRTS MOV A,E ORA A JZ NEXT2 DCR E DCX H MVI A,5FH * ECHO CALL CONOUT JMP NEXT2 * CRTS CPI 0DH JNZ CHR MOV A,E ORA A JZ NEXT2 * PUT MOV M,B CRLF MVI A,0DH CALL CONOUT MVI A,0AH CALL CONOUT MOV A,E Get length of input line. RET * CHR CPI 20H JC NEXT2 INR E MOV M,B INX H JMP ECHO * * Routine to map lower case letters to upper case. * The character in question comes in A and is mapped * into A. Everything else is unchanged on return. * MAP CPI 'a' 'a'<=A? RM Nope. No map necessary. CPI 'z'+1 A<='z'? RP Nope. No map necessary. SUI 32 'a'=>'A', etc. RET * * SEARCH ROUTINE * UPUP INX H BUMP POINTER * SEARCH SHLD ATEMP SAVE START OF LINE MVI C,0 INITIALIZE CHR COUNT * NFNXT LXI D,IBUF SEARCH 'FOR' STRING MOV A,M CPI EOF TEST FOR END OF FILE RZ * FNEXT INX H INR C LDAX D CMP M INX D JZ FYES CPI 0DH RZ MOV A,M CPI 0DH JZ UPUP * FBKUP DCR C JZ NFNXT DCX H JMP FBKUP * FYES CPI 0DH RZ MOV A,M CPI 0DH JZ UPUP JMP FNEXT * * Print string pointed to by HL until zero byte or CR. * PRINT PUSH B PRNT1 MOV A,M INX H ORA A set flags JZ PRNT2 CPI CR JZ PRNT2 CALL CONOUT JMP PRNT1 PRNT2 POP B RET * * CHRR DS 1 BREAK CHARACTER STORAGE BOTL DS 1 BEGINNING OF TEXT LINE BOSL DS 1 BEGINNING OF SCREEN LINE CLN DS 1 CURSOR LINE NUMBER CLNSAV DS 1 TEMP STORAGE FOR CLN USED BY HIGFN CCP DS 1 CURRENT CURSOR POSITION CCPSAV DS 1 STORAGE FOR OLD CCP CURF DS 1 CURSOR DISPLAY FLAG IMODF DS 1 INSERT MODE FLAG LVLN DS 1 LAST VALUE OF LINE NUMBER FFLNP DS 2 FIRST FILE LINE POINTER LFLNP DS 2 LAST FILE LINE POINTER CFLNP DS 2 CURRENT FILE LINE POINTER BBUF DS 1 BFP DS 2 EFP DS 2 EOSP DS 2 CADDR DW TAB CUSTOM COMMAND ADDRESS BRK EQU CHRR DS 10 DS 25 AREA DS 18 ATEMP DS 2 IFNUM DB -1 SPSAFE DS 2 SAFE PLACE TO STORE SP IN INSERT FILE BUFNA DS 30 FOR INSERT FILE * * * * BLANK EQU SPACE VDMDEV EQU 0C8H CR EQU 0DH EOF EQU 1 GARB EQU 35 * * *