* * File Name: PAS.IO:S * * This is an I/O routine for use with North * Star Pascal Version One. * * Written by Stephen Maguire July, 1980 * * P.O. Box 3742 DT * Anchorage, AK 99510 * * It provides the following support: * * a) It correctly interprets and performs * the GOTOXY procedure that comes with * the system so that BINDER need never * be used. This allows instant cursor * positioning without the need to write * the "necessary" GOTOXY procedure de- * scribed in the manual. * * * b) It supports PRINTER: so that output * can be printed out. The routine is * Written for a Spinwriter, but will * work for any printer if wired * according to protocol shown below. * * Spinwriter pin Sol Serial port pin * * TX DATA 2 3 RX DATA * RX DATA 3 2 TX DATA * GND 7 7 GND * CTS 5| * DSR 6| 20 DTR | denotes a common * CD 8| connection * |6 DSR * DTR 20 |8 CD * REV CHA 19 5 CTS See Note below: * * Note: In this driver, the Reverse Channel line of * the Spinwriter is used in the active "LOW" mode by * setting contact 5 of SW1 to "ON" (up) on the control * panel circuit board. (G9BNF) This results in a high * signal to the Sol when characters can be accepted. * If the printer becomes disconnected for any reason * or is turned off, the Sol still sees a high (because * of its own internal circuitry) and will continue * sending characters. This prevents a program hang * (and possibly a crash) if the printer is not * available. * * * c) If input is asked of the printer, input * from the keyboard is checked for instead. * * * d) If a control-p is sent to CONSOLE:, output * to CONSOLE: is sent to PRINTER: instead. * This continues until another control-p is * encountered. (The control-p may be typed * at the keyboard or output in a program.) * * * e) On boot-up initialization, the memory is sized * and then waits for either a carriage return (which * uses the calculated memory size) or accepts a hex * value and uses that value instead. This allows * the user to "protect" high memory if necessary. * * * f) It is now possible to print the underline character * in the PASCAL system in order to facilitate compatability * with other systems. * * * g) Control-L will erase to the end of the line. * * * h) The bell character is absorbed and sent to PRINTER: * instead of to CONSOLE:. * * * 2400H is origin for SYSTEM.NSTAR2 (memory starts at 2000H) * 400H is origin for SYSTEM.NSTAR0 (memory starts at 0000H) * ORG 400H * TRUE EQU 0FFH FALSE EQU 0 * CHBEL EQU 07H The bell CHLFE EQU 0AH Linefeed CHCLR EQU 0BH The CLEAR screen character CHFFD EQU 0CH Formfeed CHCR EQU 0DH Carriage return CHOME EQU 0EH The HOME CURSOR character CHDLE EQU 10H Control-p CHESC EQU 1BH The ESCAPE character CHUND EQU 5FH The underline character CHDEL EQU 7FH The DEL character ASCII EQU 7FH The larget ASCII character * * * Equates determined by STANDARD SOLOS * SOLOUT EQU 0C019H Solos output routine OCHAR EQU 0C098H Routine to print an underline CLINE EQU 0C0F4H Routine to erase to end of the line VDADD EQU 0C11CH Routine to calculate screen address SHEX EQU 0C340H Routine to convert ASCII hex to binary HEOUT EQU 0C40BH Routine to print register A in ASCII NCHAR EQU 0C808H X coordinate of cursor LINE EQU 0C809H Y coordinate of cursor BOT EQU 0C80AH Text offset * * * CONSOLE: device (keyboard) * CSTAT EQU 0FAH Keyboard status port CDATA EQU 0FCH Keyboard data port CRDYINP EQU 1 * CRDYOUT EQU 2 (Not used) * * * PRINTER: device (input not supported -- CONSOLE: input * is used instead if the request is made.) * PSTAT EQU 0F8H Printer status port PDATA EQU 0F9H * PRDYINP EQU 2 (Not used since PRINTER: input not supported) PRDYOUT EQU 0A0H Checks for TBE and "high" on CTS pin * * * REMOTE: device (not supported) * * RSTAT EQU 6 (For use with an extra device. Values * RDATA EQU 0 given are taken from the example I/O * RRDYINP EQU 2 routine given in the manual. This device * RRDYOUT EQU 1 could be used for tape routines if the * RSTROBE EQU 80H neccessary routines are written.) * RPOFLG EQU 20H * * NOTRDY EQU 9 Not-ready value DCTRLB EQU 0E8H High byte of controller board location DDENS EQU 80H Double density SDENS EQU 0 Single density ONESIDE EQU 0 For single sided drives TWOSIDE EQU 40H For double sided drives (Quad capacity) SBLKTRK EQU 5 Number of blocks/track in a single-density drive DBLKTRK EQU 10 Number of blocks/track with double-density * CHARACS EQU TWOSIDE+DDENS+DBLKTRK (Quad-capacity) * NSJTST EQU $ STRTSR EQU NSJTST+512 * * * CONSOLE: routine addresses * CONOCL JMP ONLINE The keyboard will always be "ready" JMP CONINP Keyboard in CONESC JMP CONOUT Video out JMP CONST * * * PRINTER: routine addresses * PTRONL JMP ONLINE The keyboard will always be "ready" JMP CONINP If input wanted, go to CONSOLE: in JMP PRNT2 * * * REMOTE: routine addresses * REMONL JMP OFFLIN This device is offline (not supported) JMP REMINP JMP REMOUT * JMP NSMSIZ How much memory is available? JMP OFFLIN There is no system clock, it is offline JMP MACINT The bootup initialization routine * DV4CHR DB CHARACS Device characteristics DV5CHR DB CHARACS All drives are defined above as Quad-capacit DV9CHR DB CHARACS DV10CHR DB CHARACS * EXPANSN DW 0 For future use * * * CONSOLE: input (PRINTER: input) * CONINP IN CSTAT Has a key been typed? CMA . Inverse the value ANI CRDYINP Strip the value for checking JZ CONINP No, keep waiting IN CDATA Yes, get the character CPI CHDLE Has a control-p been entered RNZ . ORI 80H Send all cntrol-p's out with the high bit set RET . * * * CONSOLE: output * CONOUT MOV A,C Get the character for checking ANI ASCII MOV C,A Save the stripped value * CPI CHBEL If it is the bell, send it to the printer JZ PRNT2 * CPI CHESC Escape says it is the GOTOXY procedure calling JNZ CON0 CALL VDADD MOV A,M Remove the cursor ADI 80H MOV M,A MVI A,1 Set this flag to indicate so JMP GOTO3 * CON0 CPI CHDLE If it is ctrl-p, then toggle the printer on/off JNZ CON1 LDA TOGGLE Get the switch ADI 80H Now flip it STA TOGGLE XRA A RET * CON1 LDA XYDATA Is the GOTOXY procedure in process? ORA A JZ CON2 Yes, it is * * * The GOTOXY Translates "ESC","=",y,x into a screen address * GOTOXY CPI 1 If we got here, ESCAPE has been recieved, JNZ GOTO0 Now we must check for the "=" sign MOV A,C CPI '=' JZ GOTO2 Yes, it is the "=" sign XRA A There is an error, abort GOTOXY procedure STA XYDATA JMP CONOUT And output the Character * GOTO0 CPI 2 Calculate the row value JNZ GOTO1 MOV A,C Get the row value SBI 32 Subtract 20H to get the correct value ANI 0FH Make sure the value is in range STA LINE JMP GOTO2 * GOTO1 MOV A,C Calculate the column value SBI 32 Subtract the offset ANI 3FH Make sure the value is in range STA NCHAR Store the value CALL VDADD Calculate the screen address MOV A,M Get the character where the cursor is to be ORI 80H Put the cursor there MOV M,A This does it * LDA TOGGLE If the print toggle is on, then output CR/LF ORA A CNZ PRNT0 * GOTO2 LDA XYDATA Increment the pointer so that we INR A know which argument that we are to recieve next ANI 3 This statement will eventually turn off the routine * GOTO3 STA XYDATA Save the value XRA A RET . * * All done with the GOTOXY procedure * * CON2 LDA TOGGLE If the PRINTER: is toggled on, ORA A send output to the printer instead JNZ PRINT * MOV A,C CPI CHFFD Is it the formfeed character? JNZ CON3 No, so go print the character PUSH H HL cannot be destroyed CALL VDADD PUSH H Save this screen address CALL CLINE Call the SOLOS erase-to-end-of-line routine POP H Get it back MVI M,0A0H Put on the cursor POP H XRA A (CON3 can be omitted if extended-SOLOS is being used) RET . * CON3 CPI CHDEL If it is a delete, send cursor-left instead JNZ CON4 MVI A,1 * CON4 CPI CHUND This allows the underline to be printed JNZ CON5 PUSH H Save these registers PUSH B MOV B,A Put the character in B CALL OCHAR Output the character CALL VDADD Now, put on the cursor MOV A,M Do it now ORI 80H MOV M,A JMP CON6 Exit gracefully * CON5 PUSH H Save all registers, PUSH B MOV B,A Put the character in B CALL SOLOUT Now, put it to the screen * CON6 POP B Restore the registers POP H XRA A RET * * * CONSOLE: input status * CONST IN CSTAT CMA . ANI CRDYINP MVI A,FALSE RZ . Return now if "not ready" MVI A,TRUE * * * REMOTE: not implemented so a simple RETURN is used * REMIN EQU $ REMOUT RET . * * * PRINTER: output (via control-p toggle) * PRINT MOV A,C Get the character to be sent CPI CHCR JZ PRNT2 CPI CHLFE JZ PRNT2 CPI CHOME Home prints as a carriage return/linefeed JZ PRNT0 CPI CHCLR Clear also JNZ PRNT1 * PRNT0 MVI C,CHCR Print the carriage return/linefeed CALL PRINT MVI C,CHLFE JMP PRINT * PRNT1 CPI 20H JC ONLINE If it is a control character, ignore it * * * PRINTER: output (standard output routine) * PRNT2 IN PSTAT ANI PRDYOUT CPI PRDYOUT JNZ PRNT2 Loop until ready MOV A,C ANI ASCII OUT PDATA * ONLINE XRA A RET . * OFFLIN MVI A,NOTRDY RET * NSMSIZ LHLD MEMORY Get the memory size XTHL PCHL Return now * * * Boot-up initialization * MACINT LXI H,MES1 Print the starting message CALL PRASC * LXI H,ENDMARK Start sizing at the end of this program. MVI A,0AAH (AAH is not the Start of SOLOS, CUTER, etc.) SIZE MOV B,M Save the value of this memory location MVI M,0AAH Put the value in that location CMP M Is it there? (If not, then it is ROM or no memory) MOV M,B Put the old value back too INX H Move to the next location before answering JZ SIZE Now, if so then try this new location * DCX H Point to the last good location DCX H MOV A,L Be sure that HL contains an even number ANI 0FEH MOV L,A XCHG . DE now has the last good memory location * LXI H,MES2 Print this message CALL PRASC CALL PRHEX Now, print the value MVI C,' ' Print a following blank CALL CONOUT * CALL VDADD Get the current cursor address PUSH H Save this -- it points the the value to be entered MVI B,0 So far, no characters have been entered DIFSIZE CALL CONIN Check for input JZ DIFSIZE None yet CPI CHCR Carriage return? JZ DIF4 Terminate input CPI CHDEL Delete? JNZ DIF3 No, much be a hex number * MOV A,B If no characters have been typed, ORA A JZ DIFSIZE Then don't back up DCR B Else adjust character count DCR B (for later adjustment) MVI A,CHDEL-20H Output the back-up character * DIF3 INR B CALL CON5 (This allows a normal delete to be printed) JMP DIFSIZE Go get more input * DIF4 CALL VDADD Get the cursor location MVI M,' ' Erase the cursor POP H Get the start location of the hex value MOV A,B Have any numbers been entered? ORA A JZ DIF5 If not, then use the calculated value XCHG . Otherwise, CALL SHEX Call the ASCII to binary conversion routine MOV A,L Make sure the value is even ANI 0FEH MOV L,A XCHG . Put the value in DE * DIF5 XCHG . This put DE in HL SHLD MEMORY Save it for later RET . * * * A routine that prints messages * HL points to the memory image * PRASC XRA A This is the end-of-message tester CMP M Are we at the end? RZ . If so, return immediately MOV C,M Get the character CALL CONOUT Send it out INX H Bump the pointer to the next character JMP PRASC+1 keep looping * * * PRHEX print the 16 bit value of DE as four ASCII digits * PRHEX MOV A,D Print D CALL HEOUT MOV A,E Print E JMP HEOUT * * * Messages and data storage * MES1 DB CHCLR ASC 'UCSD Pascal for Solos' DB CHCR,CHLFE,CHLFE ASC 'Sizing memory' DB CHCR,CHLFE,0 * MES2 ASCZ 'Memory available to address: ' * MEMORY DW 0 XYDATA DB 0 TOGGLE DB 0 * ENDMARK EQU $ * END *