; ******** SOLOS OPERATING SYSTEM ******** ; ; PROCESSOR TECHNOLOGY CORP. ; EMERYVILLE, CALIFORNIA ; ; ; VERSION 1.3 ; RELEASE 3/27/77 ; ; ; ; ; ; THIS 2048 BYTE PROGRAM IS THE STANDARD SOL STAND ; ALONE OPERATING SYSTEM. IT IS CONFIGURED TO OPTIMIZE ; THE CONVENIENCE AND POWER OF THE SOL-20 AND ONE OR TWO ; CASSETTE RECORDERS IN STAND ALONE COMPUTER APPLICATIONS. ; ; ;COMMANDS: ; TE TERMINAL MODE ; DU SSSS EEEE DUMP (START ADDR END ADDR) ; EN SSSS ENTER HEX TO MEMORY ; EX SSSS EXECUTE ; GE FILENAME/U GET (U=TAPE UNIT 0 OR 1, DFLT=1) ; SA FNAME/U SSSS EEEE SAVE ON TAPE (UNIT 0 OR 1) ; XE FILENAME/U AUTO LOAD/EXECUTE ; CA CATALOG OF TAPE FILES ; CU LL SSSS CUSTOM COMMAND (LL=LABLE) ; SET TA N SET TAPE SPEED (N:0=FAST,1=SLOW) ; SET S=NN SET DISPLAY SPEED (O-->FF) ; SET I=N SET IN PSEUDO PORT (N=0 - 3) ; SET O=N SET OUT PSEUDO PORT (N=0 - 3) ; SET N=NN SET NULLS (N=0 - FF) ; SET CI SSSS SET CUSTOM INPUT DRIVER ADDR ; SET CO SSSS SET CUSTOM OUTPUT DRIVER ADDR ; SET XE SSSS SET AUTO-EXECUTE ADDRESS FOR TAPE SAVE ; SET TY NN SET FILE TYPE FOR TAPE HEADER ; SET CR NN OVERRIDE CRC ERRORS (FF=IGNORE ERRORS) ; ; ; PSEUDO PORTS: 0 = KEYBOARD/VIDEO ; 1 = SERIAL PORT ; 2 = PARALLEL PORT ; 3 = USER DEFINED (SET CI, SET CO) ; ; ; ; ORG 0C000H ; ; ; ; AUTO-STARTUP CODE ; START: DB 0 INIT: JMP STRTA ;SYSTEM RESTART ENTRY POINT ; ; ; ENTRY POINTS ; ; THESE JUMP POINTS ARE PROVIDED TO ALLOW COMMON ENTRY ; LOCATIONS FOR ALL VERSIONS OF SOLOS. THEY ARE USED ; EXTENSIVLY BY SOL SYSTEM PROGRAMS AND IT IS RECOMMENDED ; THAT USER ROUTINES ACCESS SOLOS THROUGH THESE POINTS. ; RETRN: JMP COMND ;RETURN TO SYSTEM ENTRY POINT IF STD FOPEN: JMP BOPEN ;FILE OPEN ENTRY FCLOS: JMP PCLOS ;FILE CLOSE ENTRY RDBYT: JMP RTBYT ;CASSETTE READ BYTE ENTRY WRBYT: JMP WTBYT ;CASSETTE WRITE BYTE ENTRY ENDF IF EXT FOPEN: CALL CASEXT FCLOS: CALL CASEXT RDBYT: CALL CASEXT WRBYT: CALL CASEXT ENDF RDBLK: JMP RTAPE ;CASSETTE READ BLOCK ENTRY WRBLK: JMP WTAPE ;CASSETTE WRITE BLOCK ENTRY ; ; ; SYSTEM I/O ENTRY POINTS ; ; THESE ROUTINES PERFORM SYSTEM I/O ; THERE ARE TWO ENTRY TYPES: ; SINP/SOUT REG "A" WILL BE SET TO THE STANDARD ; SYSTEM PSEUDO PORT. ; AINP/AOUT REG "A" MUST BE SET BY THE USER AND ; WILL SPECIFY THE DESIRED PSEUDO PORT. ; ; THE FOLLOWING ARE THE PSEUDO PORTS: ; PORT DESCRIPTION ; ---- -------------------------------- ; 0 KEYBOARD WHEN INPUT, AND VDM WHEN OUTPUT ; 1 SERIAL I/O PORT ; 2 PARALLEL I/O PORT ; 3 USER DEFINED I/O PORT ; SOUT: LDA OPORT ;SOUT ENTRY POINT AOUT: JMP OUTPR ;AOUT ENTRY POINT SINP: LDA IPORT ;SINP ENTRY POINT IF STD AINP: EQU $ ;AINP ENTRY POINT ENDF IF EXT AINP: JMP AINP1 ENDF ; ADDITIONAL ENTRY POINTS IF EXT JMP CRLF JMP HEOUT JMP HBOUT JMP BOUT JMP ADOUT AINP1: EQU $ ENDF ; ;******** END OF SYSTEM ENTRY POINTS ********* PUSH H ;THIS IS ACTUALLY AINP LXI H,ITAB ; ; ; THIS ROUTINE PROCESSES THE I/O REQUESTS BY DISPATCHING ; TO THE DRIVER REQUESTED IN REGISTER "A". ON ENTRY HL ; HAS THE PROPER DISPATCH TABLE. ; IOPRC: ANI 3 ;KEEP REGISTER "A" TO FOUR VALUES RLC ;COMPUTE ENTRY ADDRESS ADD L MOV L,A ;WE HAVE ADDRESS JMP DISPT ;DISPATCH TO IT ; ; ; ***** SOL SYSTEM I/O ROUTINES ***** ; ; ; THIS ROUTINE IS A MODEL OF ALL INPUT ROUTINES WITHIN ; SOLOS. EACH ROUTINE FIRST TESTS THE STATUS INPUT FOR ; DATA AVAILABLE. IF NO CHARACTERHAS BEEN RECEIVED THE ; ROUTINE RETURNS WITH THE ZERO FLAG SEG. OTHERWISE THE ; CHARACTER IS INPUT AND A RETURN MADE WITH THE CHARACTER ; IN THE ACCUMULATOR AND THE ZERO FLAG RESET. ; ; ; KEYBOARD INPUT DRIVER ; KSTAT: IN STAPT ;GET STATUS WORK CMA ;INVERT IT FOR PROPER RETURN ANI KDR ;TEST KEYBOARD BIT RZ ;ZERO IS NO CHARACTER RECEIVED ; IN KDATA ;GET CHARACTER RET ;GO BACK WITH IT ; ; ; THIS JUMP IS PART OF THE AUTO START UP CODE ; DB 0 ;VERIFY ADDR=C037 JMP INIT ;THIS SHOULD BE C038 ; ; ; JMP TABLE OUTPUT ROUTINES ; ; THIS ROUTINE SETS UP THE DISPATCH TABLE FOR OUTPUT ; ROUTINES. THE CHARACTER FOR OUTPUT IS IN REGISTER "B". ; OUTPUT IS MADE TO THE DRIVER POINTED TO BY THE REGISTER ; "A". THE DEVICE DRIVERS ARE DEFINED AS FOLLOWS: ; ; 0 - DISPLAY SCREEN ; 1 - SERIAL OUTPUT PORT ; 2 - PARALLEL OUTPUT PORT ; 3 - USER DEFINED OR ERROR FLAG ; ; ENTRY AT: SOUT SELECTS CURRENT OUTPUT DEVICE ; AOUT SELECTS DEVICE IN REGISTER "A" ; OUTPR: PUSH H LXI H,OTAB ;POINT TO OUTPUT TABLE JMP IOPRC ;AND DISPATCH TO OUTPUT ROUTINE ; ; ; ; SERIAL INPUT DRIVER ; SSTAT: IN SERST ;GET SERIAL STATUS WORD ANI SDR ;TEST FOR SERIAL DATA READY RZ ;FLAGS ARE SET ; IN SDATA ;GET DATA BYTE RET ;WE HAVE IT ; ; ; SERIAL DATA OUTPUT ; SDROT: IN SERST ;GET PORT STATUS RAL ;PUT HIGH BIT IN CARRY JNC SDROT ;LOOP UNTIL TRANSMITTER BUFFER IS EMPTY MOV A,B ;GET THE CHARACTER BACK OUT SDATA ;SEND IT OUT RET ;AND WE'RE DONE ; ; ; ; ; VIDEO DISPLAY ROUTINES ; ; ; THESE ROUTINES ALLOW FOR STANDARD VIDEO TERMINAL ; OPERATIONS. ON ENTRY, THE CHARACTER FOR OUTPUT IS IN ; REGISTER B AND ALL REGISTERS EXCEPT "A" AND FLAGS ARE ; UNALTERED ON RETURN. ; ; VDMOT: PUSH H ;SAVA MOST REGISTERS PUSH D PUSH B ; ; TEST IS ESC SEPUENCE HAS BEEN STARTED ; LDA ESCFL ;GET ESCAPE FLAG ORA A JNZ ESCS ;IF NON-ZERO GO PROCESS THE REST ; ; CHPCK: MOV A,B ;SAVE IN B...STRIP PARITY BEFORE SCREEN! ANI 7FH ;CLR PARITY TO LOCATE IN TBL MOV B,A ;KEEP IT W/OUT PARITY IN B TOO JZ GOBK ;DO A QUICK EXIT IF A NULL LXI H,TBL ;POINT TO SPECIAL SHARACTER TABLE CALL TSRCH ;GO PROCESS ; GOBACK: CALL VDADD ;GET SCREEN ADDRESS MOV A,M ;GET PRESENT CURSOR CHARACTER ORI 80H MOV M,A ;CURSOR IS BACK ON LHLD SPEED-1 ;GET DELAY SPEED INR L ;MAKE SURE IT IS NON-ZERO XRA A ;DELAY WILL END WHEN H=0 TIMER: DCX H ;TIMER DELAYS HERE CMP H ;DONE WITH DELAY YET JNZ TIMER ;KEEP DELAYING IF EXT CALL SINP ;CHARACTER WAITING? JZ GOBK ;NOPE CPI ESC JZ COMND ;RETURN TO SOLOS ON ESCAPE CPI ' ' ;IS IT SPACE? JNZ VDEL1 VDEL0: CALL SINP ;WAIT FOR NEXT CHARACTER JZ VDEL0 VDEL1: CPI '0' ;GO BACK IF NOT 0-9 JC GOBK CPI '9'+1 JNC GOBK ANI 0FH ;KEEP LOWER NIBBLE JZ SESPD MOV C,A MVI A,1 ;SET BIT SPDLP: DCR C JZ SESPD RLC . ;MOVE IT OVER JC STSLO ;9 IS SLOWEST JMP SPDLP STSLO: MVI A,-1 SESPD: STA SPEED ;SET NEW SPEED ENDF GOBK: POP B POP D ;RESTORE REGISTERS POP H RET ;EXIT FROM VDMOT ; NEXT: INX H INX H ; ; ; THIS ROUTINE SEARCHES THROUGH A SINGLE CHARACTER ; TABLE FOR A MATCH TO THE CHARACTER IN "B". IF FOUND ; A DISPATCH IS MADE TO THE ADDRESS FOLLOWING THE MATCHED ; CHARACTER. IF NOT FOUND THE CHARACTER IS DISPLAYED ON ; THE MONITOR. ; TSRCH: MOV A,M ;GET CHR FROM TABLE ORA A IF STD JZ CHAR ;ZERO IS THE LAST ENDF IF EXT JZ OCHAR ;ZERO IS THE LAST ENDF CMP B ;TEST THE CHR INX H ;POINT FORWARD JNZ NEXT PUSH H ;FOUND ONE...SAVE ADDRESS CALL CREM ;REMOVE CURSOR XTHL ;GET DISPATCH ADDRESS TO HL JMP DISPT ;DISPATCH NOW ; ; PUT CHARACTER TO SCREEN ; IF STD CHAR: MOV A,B ;GET CHARACTER CPI 7FH ;IS IT A DEL? RZ ;GO BACK IF SO ENDF ; ; ; OCHAR: EQU $ ;ACTUALLY PUT CHAR TO SCREEN NOW CALL VDADD ;GET SCREEN ADDRESS MOV M,B ;PUT CHR ON SCREEN ; LDA NCHAR ;GET CHARACTER POSITION CPI 63 ;END OF LINE? JC OK LDA LINE CPI 15 ;END OF SCREEN? JNZ OK ; ; END OF SCREEN...ROLL UP ONE LINE ; SCROLL: XRA A STA NCHAR ;BACK TO FIRST CHAR POSITION SROL: MOV C,A CALL VDAD ;CALCULATE LINE TO BE BLANKED XRA A CALL CLIN1 ;CLEAR IT LDA BOT INR A ANI 0FH JMP ERAS3 ; ; INCREMENT LINE COUNTER IF NECESSARY ; OK: LDA NCHAR ;GET CHR POSITION INR A ANI 3FH ;MOD 64 AND WRAP STA NCHAR RNZ ;DIDN'T HIT END OF LINE, OK PDOWN: EQU $ ;CURSOR DOWN ONE LINE HERE LDA LINE ;GET THE LINE COUNT INR A CURSC: ANI 0FH ;STORE THE NEW CUR: STA LINE ;STORE THE NEW RET ; ; ERASE SCREEN ; PERSE: LXI H,VDMEM ;POINT TO SCREEN MVI M,80H+' ' ;THIS IS THE CURSOR ; INX H ;BUMP 1ST ERAS1: EQU $ ;LOOPS HERE TO ERASE SCREEN MVI M,' ' ;BLANK IT OUT INX H ;NEXT MOV A,H ;SEE IF END OF SCREEN YET CPI 0D0H JC ERAS1 ;NO--KEEP BLANKING STC ;CARRY WILL SAY COMPLETE ERASE ; PHOME: MVI A,0 ;RESET CURSOR--CARRY=ERASE, ELSE HOME STA LINE ;ZERO LINE STA NCHAR ;LEFT SIDE OF SCREEN RNC ;IF NO CARRY, WE ARE DONE WITH HOME ; ERAS3: OUT DSTAT ;RESET SCROOL PARAMETERS STA BOT ;BEGINNING OF TEXT OFFSET RET ; ; CLINE: CALL VDADD ;GET CURRENT SCREEN ADDRESS LDA NCHAR ;CURRENT CURSOR POSITION CLIN1: CPI 64 ;NO MORE THAN 63 RNC ;ALL DONE MVI M,' ' ;ALL SPACED OUT INX H INR A JMP CLIN1 ;LOOP TO END OF LINE ; ; ; ROUTINE TO MOVE THE CURSOR UP ONE LINE ; PUP: LDA LINE ;GET LINE COUNT DCR A JMP CURSC ;MERGE TO HANDLE CURSOR ; ; MOVE CURSOR LEFT ONE POSITION ; PLEFT: LDA NCHAR DCR A PCUR: EQU $ ;CURSOR ON SAME LINE ANI 3FH ;LET CURSOR WRAP STA NCHAR ;UPDATED CURSOR RET ; ; CURSOR RIGHT ONE POSITION ; PRIT: LDA NCHAR INR A JMP PCUR ; ; ROUTINE TO CALCULATE SCREEN ADDRESS ; ; ENTRY AT: RETURNS: ; ; VDADD CURRENT SCREEN ADDRESS ; VDAD2 ADDRESS OF CURRENT LINE, CHAR "C" ; VDAD LINE "A", CHARACTER POSITION 'C' ; VDADD: LDA NCHAR ;GET CHARACTER POSITION MOV C,A ;'C' KEEPS IT VDAD2: LDA LINE ;LINE POSITION VDAD: MOV L,A ;INTO 'L' LDA BOT ;GET TEXT OFFSET ADD L ;ADD IT TO THE LINE POSITION RRC ;TIMES TWO RRC ;MADES FOUR MOV L,A ;L HAS IT ANI 3 ;MOD THREE FOR LATER ADI RETURN ABSOLUTE SCREEN ADDRESS ; ARET: MOV B,H MOV C,L ;PRESENT SCREEN ADDRESS TO BC FOR RETURN ; ARET1: POP H ;RETURN ADDRESS POP D ;OLD B PUSH B PUSH H XRA A ARET2: STA ESCFL RET ; ; ; RETURN PRESENT SCREEN PARAMETERS IN "BC" ; CURET: LXI H,NCHAR MOV B,M ;CHARACTER POSITION INX H MOV C,M ;LINE POSITION JMP ARET1 ; ; ; ***** START UP SYSTEM ***** ; ; CLEAR SCREEN AND THE FIRST 256 BYTES OF GLOBAL RAM ; THEN ENTER THE COMMAND MODE ; IF STD STRTA: XRA A MOV C,A ENDF IF EXT STRTA: LDA IGNCR+1 ;CHECK SYSTEM RAM ORA A ;ASSUME POWER-UP NON-ZERO MVI A,0 JNZ STRT1 MVI A,3CH ;CLEAR C800 - C83B ONLY STRT1 MOV C,A XRA A ENDF LXI H,SYSRAM ;CLEAR THR FIRST PAGE ; CLERA: MOV M,A INX H DCR C ;ORIGINAL INR C **** JNZ CLERA ; LXI SP,SYSTP ;SET UP THE STACK FOR CALL CALL PERSE COMN1: XRA A OUT STAPT ;BE SURE TAPES ARE OFF STA OPORT STA IPORT ; ; ; ; ***** COMMAND MODE ***** ; ; ; THIS ROUTINE GETS AND PROCESSES COMMANDS ; COMND: LXI SP,SYSTP ;SET STACK POINTER LDA OPORT ;GET PORT PUSH PSW XRA A STA OPORT ;FORCE SCREEN OPERATIONS CALL PROMPT ;PUT PROMPT ON SCREEN CALL GCLIN ;GET COMMAND LINE POP PSW STA OPORT ;RESTORE DEFAULT PORT CALL COPRC ;PROCESS THE LINE JMP COMND ;OVER AND OVER ; ; ; ; THIS ROUTINE READS A COMMAND LINE ; FROM THE SYSTEM KEYBOARD ; ; C/R TERMINATES THE SWQUENCE ERASING ALL ; CHARS TO THE RIGHT OF THE CURSOR ; L/F TERMINATES THE SEQUENCE ; MODE RESTARTS THE COMMAND LINE ; GCLIN: CALL SINP ;READ INPUT DEVICE JZ GCLIN ANI 7FH ;CLEAR PARITY BIT JZ COMN1 ;THIS WAS A MODE (OR EVEN CTRL-@) MOV B,A CPI CR ;CARRIAGE RETURN JZ CLINE ;YES--DONE WITH LINE CPI LF ;LINE FEED RZ ;YES--DONE WITH LINE, LEAVE AS IS CPI 7FH ;DELETE CHR? JNZ CONT IF STD MVI B,BACKS ;REPLACE IT ENDF IF EXT MVI B,07FH ;REPLACE IT ENDF ; CONT: CALL SOUT JMP GCLIN ; ; ; FIND AND PROCESS COMMAND ; COPRC: CALL CREM ;REMOVE THE CURSOR MVI C,1 ;SET FOR CHARACTER POSITION CALL VDAD2 ;GET SCREEN ADDRESS XCHG LXI H,START ;MAKE SURE HL PT TO SOLOS START PUSH H ;SAVE IT FOR LATER DISPT CALL SCHR ;SCAN PAST BLANKS JZ ERR1 ;NO COMMAND? XCHG ;HL HAS FIRST CHR ; LXI D,COMTAB ;POINT TO COMMAND TABLE CALL FDCOM ;SEE IF IN PRIMARY COMMAND TABLE IF STD CZ FDCOU ;IF NOT, TRY CUSTOM TABLE NEXT ENDF IF EXT CZ FDCOE ;SCAN EXTENSION TABLE, THEN CUSTOM ENDF DISPO: EQU $ ;HERE TO SEE IF ERROR OR DISP JZ ERR2 ;NOT VALID, ERROR INX D ;BUMP TO PTR OF RTN XCHG ;HL PT TO RTN ADDR ; ; ; THIS IS THE DISPATCH ROUTINE ; HL PT TO RTN ADDRESS, HL WILL BE RESTORED FROM STACK ; SO THAT HL ARE RESTORED BEFORE DISPATCH. ; DISPT: EQU $ ;OFF TO A ROUTINE MOV A,M ;LO ADDR INX H MOV H,M ;HI ADDR MOV L,A ;HL NOW COMPLETE DISP1: EQU $ ;HERE TO GO OFF TO HL XTHL ;XCHG HL W/HL ON STACK MOV A,L ;ALSO COPY HERE FOR SETS RET ;AND GO OFF TO THE RTN ; ; CHECKS FOR PRESENCE OF EXTENSION TABLE ; IF EXT CKEXT: LDA SOLEXT CPI 0C3H RET ENDF ; ; ; THIS ROUTINE SEARCHES THROUGH A TABLE, POINTED TO ; BY 'DE', FOR A DOUBLE CHARACTER MATCH OF THE 'HL' ; MEMORY CONTENT. IF NO MATCH IS FOUND THE SCAN ENDS ; WITH HL POINTING TO ORIGINAL VALUE AND ZERO FLAG SET. ; IF EXT FDCOE: CALL CKEXT ;CHECK FOR EXTENSION JNZ FDCOU ;NOT THERE LXI D,EXTCT ;POINT TO EXTENDED COMMAND TABLE CALL FDCOM ;SCAN EXT JZ FDCOU ;NOT FOUND, SCAN CUST RET ENDF ; FDCOU: LXI D,CUTAB ;HERE TO SCAN CUSTOM TBL ONLY ; IF STD FDCOM: LDAX D ORA A ;TEST FOR TABLE END RZ ;NOT FOUND..COMMAND ERROR PUSH H ;SAVE START OF SCAN ADDRESS CMP M ;TEST FIRST CHR INX D JNZ NCOM ; INX H LDAX D CMP M ;NOW SECOND CHARACTER JNZ NCOM ;GOODNESS ENDF ; IF EXT FDCOM: MOV A,M ;GET CHARACTER CPI 61H ;LOWER CASE? JC FDCO1 ;NO ANI 5FH ;MAKE IT UPPER CASE FDCO1: MOV C,A ;SAVE IN C LDAX D ;GET TABLE CHARACTER ORA A ;TEST FOR TABLE END RZ . ;NOT FOUND. COMMAND ERROR PUSH H CMP C INX D JNZ NCOM ;NOT FOUND INX H MOV A,M ;GET SECOND CHARACTER CPI 61H JC FDCO2 ANI 5FH ;U.C. FDCO2: MOV C,A LDAX D CMP C JNZ NCOM ENDF ; POP H ;RESTORE ORIGINAL SCAN ADDR ORA A ;SET NON-ZERO FLAG SAYING FOUND RET ;WITH NON-ZERO SET ; ; NCOM: INX D ;GO TO NEXT ENTRY INX D INX D POP H ;GET BACK ORIGINAL ADDRESS JMP FDCOM ;CONTINUE SEARCH ; ; ; ***** COMMAND TABLE ***** ; ; THIS TABLE DESCRIBES THE VALID COMMANDS FOR SOLOS ; COMTAB EQU $ IF STD ASC 'TE' ;TERMINAL MODE DW TERM ENDF ASC 'DU' ;DUMP DW DUMP ASC 'EN' ;ENTER DW ENTER ASC 'EX' ;EXECUTE DW EXEC ASC 'GE' ;GET A FILE DW TLOAD ASC 'SA' ;SAVE A FILE DW TSAVE ASC 'XE' ;AUTO-EXECUTE A FILE DW TXEQ ASC 'CA' ;CATALOG OF TAPE FILES DW TLIST ASC 'SE' ;SET COMMAND DW CSET ASC 'CU' ;CUSTOM COMMAND DW CUSET IF EXT ASC 'BO' ;DOS BOOTS DW DOS ENDF DB 0 ;END OF TABLE MARK ; ; ; DISPLAY DRIVER COMMAND TABLE ; ; THIS TABLE DEFINES THE CHARACTERS FOR SPECIAL ; PROCESSING. IF THE CHARACTER IS NOT IN THE TABLE IT ; GOES TO THE SCREEN. ; TBL: DB CLEAR-80H ;CLEAR SCREEN DW PERSE DB UP-80H ;UP CURSOR DW PUP DB DOWN-80H ;DOWN CURSOR DW PDOWN DB LEFT-80H ;LEFT CURSOR DW PLEFT DB RIGHT-80H ;RIGHT CURSOR DW PRIT DB HOME-80H ;HOME CURSOR DW PHOME IF EXT DB BELL ;BELL DW PBELL DB CEOL ;CLEAR TO EOL DW CLINE ENDF DB CR ;CARRIAGE RETURN DW PCR DB LF ;LINE FEED DW PLF IF STD DB BACKS ;BACKSPACE ENDF IF EXT DB 07FH ;BACKSPACE ENDF DW PBACK DB ESC ;ESCAPE KEY DW PESC DB 0 ;END OF TABLE ; ; ; OUTPUT DEVICE TABLE ; OTAB: DW VDMOT ;VDM DRIVER DW SDROT ;SERIAL OUTPUT DW PROUT ;PARALLAL OUTPUT DW ERROT ;ERROR OR USER DRIVER HANDLER ; ; ; INPUT DEVICE TABLE ; ITAB: DW KSTAT ;KEYBOARD INPUT DW SSTAT ;SERIAL INPUT DW PASTAT ;PARALLEL INPUT DW ERRIT ;ERROR OR USER DRIVER HANDLER ; ; ; SECONDARY COMMAND TABLE FOR SET COMMAND ; SETAB: ASC 'TA' ;SET TAPE SPEED DW TASPD ASC 'S=' ;SET DISPLAY SPEED DW DISPD ASC 'I=' ;SET INPUT PORT DW SETIN ASC 'O=' ;SET OUTPUT PORT DW SETOT IF STD ASC 'N=' ;SET NULLS DW SETNU ENDF ASC 'CI' ;SET CUSTOM DRIVER ADDRESS DW SETCI ASC 'CO' ;SET CUSTOM OUTPUT DRIVER ADDRESS DW SETCO ASC 'XE' ;SET HEADER XEQ ADDRESS DW SETXQ ASC 'TY' ;SET HEADER TYPE DW SETTY ASC 'CR' ;SET CRC TO ALLOW IGNORING OF CRC ERRORS DW SETCR DB 0 ;END OF TABLE MARK ; ; ; SOLOS PORT ERROR HANDLER ; ERRIT: PUSH H ;SAVE HL ONCE AGAIN LHLD UIPRT ;GET USER INPUT PORT ADDRESS JMP ERRO1 ;AND GO PROCESS ; ERROT: PUSH H LHLD UOPRT ;GET USER OUTPUT PORT ADDRESS ERRO1: MOV A,L ;TEST HL FOR ZERO ORA H JZ COMN1 ;IF ZERO RETURN TO COMMAND MODE XTHL ;ADDRESS TO STACK...OLD HL TO HL RET ;GO TO THE DRIVER