;USER AREA FOR CP/M2 ON NORTH STAR ;VERSION 3.4 OF OCT 7, 1980 ;COPYRIGHT (C) 1980 LIFEBOAT ASSOCIATES ;THIS USER AREA IS IDENTICAL TO THAT PRODUCED BY ;CONFIG.COM VER 3.X USING CONFIGURATIONS 0 THRU 8. ;IT MAY BE USED AS IS OR AS A PROTOTYPE FOR ;YOUR OWN DRIVERS. TWO PAGES (512 BYTES) ARE ;AVAILABLE FOR YOUR CUSTOM I/O ROUTINES. ;THE USER AREA CONTAINS A STANDARD CONSOLE DRIVER ;AND A PRINTER DRIVER WITH A CHOICE OF HANDSHAKING. ;HANDSHAKING MAY BE ETX/ACK, XON/XOFF OR NONE. ;PRINTER MAY SEND 0-256 NULLS AFTER CARRIGE RETURN. ;THE PUNCH AND READER ROUTINES GO TO THE CONSOLE. ;THE SPECIFIC CONSOLE PORTS AND INITIALIZATION STRINGS ;WILL DEPEND ON THE TERMINAL NUMBER SELECTED. ;TERMINALS 0 THRU 7 ARE FOR SPECIFIC I/O BOARDS. ;CONFIG TERMINAL #8 WILL CONFIGURE FOR NON STANDARD ;CONSOLE PORTS WHEN THE VALUES FOR EQUATES "1" THRU "8" ;ARE PLACED IN THE DATA TABLE AT 130H TOGETHER WITH ;INITIALIZATION STRING IF NEEDED AT "S" AND LENGTH AT "L". ;TYPE "CONFIG P" AND ANSWER CONSOLE QUESTIONS TO ;INSTALL PRINTER EQUATES "9" THRU "J" AND INIT STRING "S". ;CHANGE MSIZE TO THE DESIRED CP/M MEMORY SIZE IN K. 0018 = MSIZE EQU 24 ;DISTRIBUTION SIZE ;THE FOLLOWING EQUATES ARE AUTOMATICALLY CHANGED BY MSIZE. 5300 = BIOS EQU 5300H+(MSIZE-24)*1024 3D00 = CCP EQU BIOS-1600H 4500 = BDOS EQU CCP+800H 5A00 = USER EQU BIOS+700H ;FOR DOUBLE/QUAD DENSITY ;USER EQU BIOS+500H ;FOR SINGLE DENSITY CD00 = OFFSET EQU 2000H-BIOS ;TO OVERLAY SYSGEN IMAGE 0003 = IOBYT EQU 3 ;STORAGE LOCATION ;HARDWARE EQUATES FOR ALTAIR SIO (REV NON-ZERO) WITH ;ACTIVE LOW HARDWARE AS USED IN CONFIG.COM TERMINAL #2. ;CHANGE TO THE APPROPRIATE VALUES FOR YOUR I/O HARDWARE. ;SEE THE INSTRUCTIONS ACCOMPANYING YOUR I/O BOARD FOR ;THE CORRECT PORTS, FLAGS, INITIALIZATION AND DRIVER CODE. ;SET HARDWARE SENSE FLAGS XXXFLG AS FOLLOWS: ; ACTIVE HIGH BITS TO 1, ACTIVE LOW TO 0. ; USUALLY XXXFLG = XXXMSK IF ACTIVE HIGH. ; XXXFLG = 0 IF ACTIVE LOW. ;HARDWARE EQUATES FOR CONSOLE INPUT (TTY). 0000 = TISPT EQU 0 ;"1" TTY INPUT STATUS PORT 0001 = TDAMSK EQU 1 ;"2" DATA AVAILABLE MASK 0000 = TDAFLG EQU 0 ;"3" HARDWARE SENSE ACTIVE LOW 0001 = TDIPT EQU 1 ;"4" TTY DATA INPUT PORT ;HARDWARE EQUATES FOR CONSOLE OUTPUT (TTY). 0000 = TOSPT EQU 0 ;"5" TTY OUTPUT STATUS PORT 0080 = TBEMSK EQU 80H ;"6" TX BUFFER EMPTY MASK 0000 = TBEFLG EQU 0 ;"7" HARDWARE SENSE ACTIVE LOW 0001 = TDOPT EQU 1 ;"8" TTY DATA OUTPUT PORT ;HARDWARE EQUATES FOR PRINTER OUTPUT (PTR). 0000 = POSPT EQU 0 ;"9" PTR OUTPUT STATUS PORT 0080 = PBEMSK EQU 80H ;"A" TX BUFFER EMPTY MASK 0000 = PBEFLG EQU 0 ;"B" HARDWARE SENSE ACTIVE LOW 0001 = PDOPT EQU 1 ;"C" PTR DATA OUTPUT PORT ;HARDWARE EQUATES FOR PRINTER HANDSHAKING (PTR INPUT). ;USUALLY SAME PORTS AS PRINTER OUTPUT WITH DIFFERENT MSK. 0000 = PISPT EQU 0 ;"D" PTR INPUT STATUS PORT 0001 = PDAMSK EQU 1 ;"E" DATA AVAILABLE MASK 0000 = PDAFLG EQU 0 ;"F" HARDWARE SENSE ACTIVE LOW 0001 = PDIPT EQU 1 ;"G" PTR INPUT DATA PORT ;HANDSHAKING EQUATES. 0003 = ETX EQU 'C'-40H ; SEND ETX AFTER A BUFFER 0006 = ACK EQU 'F'-40H ; AND WAIT FOR PRINTERS ACK 007F = BUFLEN EQU 127 ; BUFFER LENGTH FOR ETX/ACK 0013 = XOFF EQU 'S'-40H ; PRINTER SAYS STOP 0011 = XON EQU 'Q'-40H ; PRINTER READY FOR DATA ;HAND IS TYPE OF HANDSHAKING WHICH CAN BE 0FFH FOR NONE, ;6 (ACK) FOR ETX/ACK OR 11H (XON) FOR XON/XOFF. 00FF = HAND EQU 0FFH ;"H" TYPE OF HANDSHAKING ;DEFIOB IS INITIAL IOBYT IF USED. ;80H SETS PRINTER TO LPT: DEVICE, 0 SETS TO TTY:. ;STAT.COM CAN MODIFY IOBYT IN RUNNING CP/M. 0000 = DEFIOB EQU 0 ;"I" DEFAULT IOBYT ;NULLS IS NUMBER OF NULLS SENT AFTER CARRIGE RETURN ;TO ALLOW PRINTER TIME TO RETURN TO LEFT MARGIN. 0000 = NULLS EQU 0 ;"J" PRINTER NULLS 5A00 ORG USER ;START OF USER AREA ;JUMP TABLE - JUMPS MUST REMAIN HERE IN SAME ORDER. 5A00 C3555B CINIT JMP CINITR ;COLD BOOT INIT 5A03 C3515B WINIT JMP WINITR ;WARM BOOT INIT 5A06 C3235A CONST JMP UCONST ;CONSOLE STATUS 5A09 C3315A CONIN JMP UCONIN ;CONSOLE INPUT 5A0C C33F5A CONOUT JMP UCONOUT ;CONSOLE OUTPUT 5A0F C34D5A LIST JMP ULIST ;PRINTER OUTPUT 5A12 C33F5A PUNCH JMP UCONOUT ;PUNCH OUTPUT TO CONSOLE 5A15 C3315A READER JMP UCONIN ;READER INPUT TO CONSOLE 5A18 C35D5A LISTST JMP ULISTST ;PRINTER STATUS ;THIS 8 BYTE DATA AREA USED EXTERNALLY MUST REMAIN. 5A1B 6901 LENUA: DW USRLEN ;LENGTH OF USER AREA 5A1D 00 USRIOB: DB DEFIOB ;"I" INITIAL IOBYT 5A1E FF HSTYPE: DB HAND ;"H" HANDSHAKING TYPE 5A1F 00 NULLOC: DB NULLS ;"J" PRINTER NULLS 5A20 000000 DB 0,0,0 ;RESERVED ;THESE ROUTINES USE IOBYT TO SELECT CP/M CONSOLE AND LIST. UCONST: ;SELECT CP/M CONSOLE STATUS ROUTINE. 5A23 3A0300 LDA IOBYT 5A26 CD6D5A CALL DEVSEL ;SELECT DEVICE FROM TABLE. 5A29 7A5A DW TTYIST ;TTY: 5A2B 7A5A DW TTYIST ;CRT: 5A2D 7A5A DW TTYIST ;BAT: 5A2F BE5A DW PTRIST ;UC1: UCONIN: ;SELECT CP/M CONSOLE INPUT ROUTINE. 5A31 3A0300 LDA IOBYT 5A34 CD6D5A CALL DEVSEL ;SELECT DEVICE FROM TABLE 5A37 865A DW TTYIN ;TTY: 5A39 865A DW TTYIN ;CRT: 5A3B 865A DW TTYIN ;BAT: 5A3D CA5A DW PTRIN ;UC1: UCONOUT: ;SELECT CP/M CONSOLE OUTPUT ROUTINE. 5A3F 3A0300 LDA IOBYT 5A42 CD6D5A CALL DEVSEL ;SELECT DEVICE FROM TABLE 5A45 9E5A DW TTYOUT ;TTY: 5A47 9E5A DW TTYOUT ;CRT: 5A49 9E5A DW TTYOUT ;BAT: 5A4B B45A DW PTROUT ;UC1: ULIST: ;SELECT CP/M LIST OUTPUT ROUTINE. 5A4D 3A0300 LDA IOBYT 5A50 07 RLC ;ROTATE LIST SELECTION 5A51 07 RLC ;BITS TO 0,1 5A52 CD6D5A CALL DEVSEL ;SELECT DEVICE FROM TABLE. 5A55 9E5A DW TTYOUT ;TTY: 5A57 9E5A DW TTYOUT ;CRT: 5A59 215B DW LPTOUT ;LPT: 5A5B 9E5A DW TTYOUT ;UL1: ULISTST: ;SELECT CP/M LIST STATUS ROUTINE. 5A5D 3A0300 LDA IOBYT 5A60 07 RLC ;ROTATE LIST SELECTION 5A61 07 RLC ;BITS TO 0,1 5A62 CD6D5A CALL DEVSEL ;SELECT DEVICE FROM TABLE. 5A65 925A DW TTYOST ;TTY: 5A67 925A DW TTYOST ;CRT: 5A69 EE5A DW LPTST ;LPT: 5A6B 925A DW TTYOST ;UL1: DEVSEL: ;SELECT ROUTINE FROM TABLE OF CALLER. 5A6D E603 ANI 3 ;MASK IOBYT AND 5A6F 07 RLC ;MULT TIMES 2. 5A70 5F MOV E,A ;PUT INDEX INTO 5A71 1600 MVI D,0 ;DE REGISTER. 5A73 E1 POP H ;GET ADDR OF TABLE 5A74 19 DAD D ;AND ADD INDEX. 5A75 5E MOV E,M ;GET ADDR OF ROUTINE 5A76 23 INX H ;INTO 5A77 56 MOV D,M ;DE FIRST, 5A78 EB XCHG ;THEN PUT INTO HL 5A79 E9 PCHL ;AND TRANSFER CONTROL. ;CONSOLE PHYSICAL DRIVERS TTYIST: ;CONSOLE INPUT STATUS ROUTINE. ;RETURN 0FFH IF CHAR READY, 0 IF NOT. 5A7A AF XRA A 5A7B DB00 IN TISPT ;"1" READ STATUS PORT 5A7D 2F CMA ;ADJUST SENSE 5A7E E601 ANI TDAMSK ;"2" MASK STATUS BITS 5A80 EE00 XRI TDAFLG ;"3" HARDWARE SENSE 5A82 C8 RZ ;NO KEY WAS PRESSED 5A83 3EFF MVI A,0FFH ;CHAR IS READY 5A85 C9 RET TTYIN: ;CONSOLE INPUT CHAR TO REGISTER A. 5A86 CD7A5A CALL TTYIST ;IS CHAR READY? 5A89 CA865A JZ TTYIN ;NOT YET 5A8C AF XRA A 5A8D DB01 IN TDIPT ;"4" READ DATA PORT 5A8F E67F ANI 7FH ;STRIP PARITY 5A91 C9 RET TTYOST: ;CONSOLE OUTPUT STATUS ROUTINE. ;RET 0FFH IF READY FOR OUTPUT, 0 IF NOT. 5A92 AF XRA A 5A93 DB00 IN TOSPT ;"5" READ STATUS PORT 5A95 2F CMA ;ADJUST SENSE 5A96 E680 ANI TBEMSK ;"6" MASK STATUS BITS 5A98 EE00 XRI TBEFLG ;"7" HARDWARE SENSE 5A9A C8 RZ ;READY TO OUTPUT 5A9B 3EFF MVI A,0FFH ;NOT READY 5A9D C9 RET TTYOUT: ;CONSOLE OUTPUT CHAR FROM REGISTER C. 5A9E CD925A CALL TTYOST ;READY TO OUTPUT? 5AA1 CA9E5A JZ TTYOUT ;WAIT UNTIL NOT BUSY 5AA4 79 MOV A,C ;CHAR INTO ACCUMULATOR 5AA5 D301 OUT TDOPT ;"8" OUTPUT CHAR 5AA7 C9 RET ;PRINTER PHYSICAL DRIVERS PTROST: ;PRINTER OUTPUT STATUS ROUTINE. ;RETURN 0FFH IF READY, 0 IF BUSY. 5AA8 AF XRA A 5AA9 DB00 IN POSPT ;"9" READ STATUS PORT 5AAB 2F CMA ;ADJUST SENSE 5AAC E680 ANI PBEMSK ;"A" MASK STATUS BITS 5AAE EE00 XRI PBEFLG ;"B" HARDWARE SENSE 5AB0 C8 RZ ;PRINTER BUSY 5AB1 3EFF MVI A,0FFH ;READY TO PRINT 5AB3 C9 RET PTROUT: ;PRINTER OUTPUT CHAR FROM REGISTER C. 5AB4 CDA85A CALL PTROST ;READY TO PRINT? 5AB7 CAB45A JZ PTROUT ;WAIT UNTIL NOT BUSY 5ABA 79 MOV A,C ;CHAR INTO ACCUMULATOR 5ABB D301 OUT PDOPT ;"C" OUTPUT CHAR 5ABD C9 RET PTRIST: ;PRINTER INPUT (ACK) STATUS. ;RETURN 0FFH IF READY, 0 IF BUSY. 5ABE AF XRA A 5ABF DB00 IN PISPT ;"D" READ STATUS PORT 5AC1 2F CMA ;ADJUST SENSE 5AC2 E601 ANI PDAMSK ;"E" MASK STATUS BITS 5AC4 EE00 XRI PDAFLG ;"F" HARDWARE SENSE 5AC6 C8 RZ ;NO CHAR AVAIL 5AC7 3EFF MVI A,0FFH ;READY TO GET ACK 5AC9 C9 RET PTRIN: ;PRINTER INPUT ACK CHAR TO REGISTER A. 5ACA CDBE5A CALL PTRIST ;IS CHAR READY? 5ACD CACA5A JZ PTRIN ;NOT YET 5AD0 AF XRA A 5AD1 DB01 IN PDIPT ;"G" READ DATA PORT 5AD3 E67F ANI 7FH ;STRIP PARITY 5AD5 C9 RET NULLOUT: ;NULL HANDLER FOR PRINTER OUTPUT. 5AD6 CDB45A CALL PTROUT ;PRINT THE CHAR. 5AD9 FE0D CPI 0DH ;WAS IT A CR? 5ADB C0 RNZ ;FINISHED IF NOT. 5ADC 3A1F5A LDA NULLOC ;GET NR OF NULLS TO SEND 5ADF 47 MOV B,A ;INTO B REG TO COUNT. 5AE0 B7 ORA A ;WE ARE FINISHED 5AE1 C8 RZ ;IF NULLS = 0. 5AE2 0E00 MVI C,0 ;THIS IS A NULL. NLOOP: 5AE4 CDB45A CALL PTROUT ;PRINT A NULL, 5AE7 05 DCR B ;DECREMENT COUNT 5AE8 C2E45A JNZ NLOOP ;AND LOOP UNTIL 0. 5AEB 0E0D MVI C,0DH ;RESTORE CR TO C. 5AED C9 RET ;LPT LOGICAL PRINTER DRIVER DOES HANDSHAKING ;AND CALLS PTR PHYSICAL DRIVERS. REG C PRESERVED. LPTST: ;LPT LOGICAL STATUS ROUTINE. ;RETURN 0FFH IF READY, 0 IF BUSY. 5AEE CDA85A CALL PTROST ;IS HARDWARE BUSY? 5AF1 C8 RZ ;YES 5AF2 3A1E5A LDA HSTYPE ;SHOULD BE 0FFH, ACK OR XON 5AF5 47 MOV B,A ;SAVE TYPE. 5AF6 FE06 CPI ACK ;ETX/ACK? 5AF8 CA005B JZ PROTO ;YES, ON TO HANDLER 5AFB FE11 CPI XON ;XON/XOFF? 5AFD 3EFF MVI A,0FFH ;NO HANDSHAKING IN USE 5AFF C0 RNZ ;AND HARDWARE IS READY. PROTO: ;MARK READY IF ACK RVCD WHEN ETX/ACK IN USE ;OR RESPOND TO XON/XOFF. 5B00 CDBE5A CALL PTRIST ;IS HS CHAR READY? 5B03 C4CA5A CNZ PTRIN ;YES, GET IT. 5B06 B8 CMP B ;PROPER GO AHEAD CHAR? 5B07 CA1A5B JZ READY ;YES, MUST BE ACK OR XON. 5B0A FE13 CPI XOFF ;XOFF RCVD? 5B0C C2155B JNZ NLEGAL ;NO, IGNORE CHAR. 5B0F 04 INR B ;MAKE XON 5B10 04 INR B ;INTO XOFF TO MAKE SURE 5B11 B8 CMP B ;XON/OFF IN USE. 5B12 CA4A5B JZ BUSY ;XOFF PROPERLY RCVD. NLEGAL: 5B15 3A505B LDA LPTFLG ;NOT LEGAL HS CHAR SO 5B18 B7 ORA A ;RETURN WITH PREV STATUS. 5B19 C9 RET READY: 5B1A 3EFF MVI A,0FFH ;MARK READY 5B1C 32505B STA LPTFLG ;AT SOFTWARE FLAG 5B1F B7 ORA A ;AND RETURN NZ. 5B20 C9 RET LPTOUT: ;LPT OUTPUT ROUTINE FROM REGISTER C. 5B21 CDEE5A CALL LPTST ;GET STATUS 5B24 CA215B JZ LPTOUT ;WAIT UNTIL READY 5B27 CDD65A CALL NULLOUT ;THEN PRINT CHAR 5B2A 3A1E5A LDA HSTYPE ;LOAD PROTOCOL TYPE 5B2D FE06 CPI ACK ;USING ETX/ACK? 5B2F C0 RNZ ;NO, EXIT. ;PROCESS ETX/ACK PROTOCOL HERE. ;CHECK FOR ESCAPE SEQUENCE FIRST. 5B30 214F5B LXI H,BUFCNT 5B33 79 MOV A,C ;WAS LAST CHAR 5B34 FE1B CPI 1BH ;AN ESCAPE? 5B36 C2415B JNZ ETXOUT ;NO 5B39 7E MOV A,M ;GET ETX COUNT 5B3A FE04 CPI 4 ;IF OVER 3 LEFT 5B3C D2415B JNC ETXOUT ;PROCESS NORMALLY. 5B3F 3603 MVI M,3 ;SEND 3 CHAR BEFORE ETX. ETXOUT: ;COUNT DOWN UNTIL BUFLEN CHARACTERS SENT, ;THEN SEND ETX AND WAIT FOR PRINTERS ACK. 5B41 35 DCR M ;COUNT DOWN BUT 5B42 C0 RNZ ;DO NOTHING UNTIL 0 5B43 367F MVI M,BUFLEN ;THEN RESET COUNT 5B45 0E03 MVI C,ETX ;AND SEND ETX 5B47 CDB45A CALL PTROUT ;TO PRINTER. BUSY: 5B4A AF XRA A ;MARK BUSY 5B4B 32505B STA LPTFLG ;AT SOFTWARE FLAG 5B4E C9 RET ;AND RET Z SET. ;HANDSHAKING VARIABLES 5B4F BUFCNT: DS 1 ;ETX/ACK BUFFER COUNT. 5B50 LPTFLG: DS 1 ;LPT STATUS FLAG. ;READY=0FFH, BUSY=0 WINITR: ;ANY WARM BOOT INITIALIZATION GOES HERE. 5B51 000000 DB 0,0,0 ;PATCH ROOM 5B54 C9 RET CINITR: ;HARDWARE INITIALIZATION ON COLD BOOT GOES ;HERE IF NEEDED. MAKE SURE IT ENDS WITH A RET. 5B55 3EFF MVI A,0FFH ;MARK PRINTER READY 5B57 32505B STA LPTFLG ;AT SOFTWARE FLAG. 5B5A 3E7F MVI A,BUFLEN ;INITIALIZE 5B5C 324F5B STA BUFCNT ;BUFFER COUNT. 5B5F 3A1D5A LDA USRIOB ;LOAD INITIAL IOBYT 5B62 320300 STA IOBYT ;AND STORE. 5B65 000000 DB 0,0,0 ;PATCH ROOM ;INITIALIZATION STRING FOR TERMINAL #8 ;OF LENGTH "L" BEGINS AT "S" BELOW. STRING: ;"S" 5B68 C9 RET 0001 = STRLEN EQU $-STRING ;"L" 0169 = USRLEN EQU $-CINIT ;LENGTH OF USER AREA