; ; ******** SOLOS OPERATING SYSTEM ******** ; For McVideo Module ; Mod (2.1) Modified: Mar, 1983 ; ; ; ; AUTO-STARTUP CODE ; START: DB 0 ;USED IN 4 PHASE WONDER INIT: JMP STRTA ;COLD START ENTRY POINT RETRN: JMP COMND ;WARM START ENTRY POINT MSGV: JMP MEMT9 ;OUTPUT MESSAGE UNTIL '00' PIN: JMP SSTAT ;SERIAL INPUT POUT: JMP SDROT ;SERIAL PRINTER OUTPUT JMP HEOUT ;OUTPUT 'A' IN HEX JMP ADOU1 ;OUTPUT 'HL' IN HEX JMP DUMP1 ;DUMP MEMORY SOUT: JMP VDMOT ;VDM OUTPUT JMP CRLF ;CRLF OUT SINP: JMP KSTAT ;INPUT HANDLER JMP EXDEP ;MEMORY EDITOR JMP ENTR1 ;BYTE ENTER ROUTINE JMP ZIP4 ;MEMORY FILL ROUTINE JMP SERCH ;MEMORY SEARCH ; ; KEYBOARD INPUT DRIVER ; KSTAT: IN STAPT ;GET STATUS WORD CMA . ;INVERT IT FOR PROPER RETURN ANI KDR ;TEST KEYBOARD BIT RZ . ;ZERO IS NO CHARACTER RECEIVED IN KDATA ;GET CHARACTER RET . ; ; ROUTINE TO BACKSPACE ; PBACK: CALL PLEFT CALL VDADD ;GET SCREEN ADDRESS MVI M,' ' ;PUT A BLANK THERE RET . ; ; SERIAL DATA OUTPUT ; SDROT: IN SERST ;Get port status ANI 0A0H ;Mask off all but CTS and TBE bits CPI 0A0H ;Check if bits present JNZ SDROT ;If missing, go back MOV A,B ;Move in char CPI 7FH ;Deletes get an underline JNZ SDRO3 MVI A,BACKS SDRO3: OUT SDATA ;Send it out RET ; ; VIDEO DISPLAY ROUTINES ; VDMOT: PUSH H ;SAVE MOST REGISTERS PUSH D PUSH B ; CHPCK: LDA PRTOG ;GET FLAG BYTE MOV C,A RRC . ;PRINT WANTED? JNC CHPC0 MOV A,C ANI 80H ;WHICH PRINTER? PUSH PSW ; IF EPSON CZ PROUT ;OUT PARALLEL PORT POP PSW CNZ SDROT ;OUT SERIAL PORT ENDF ; IF TI810 CZ SDROT POP PSW CNZ PROUT ENDF ; CHPC0: MOV A,B ;REJECT NULLS ANI 7FH MOV B,A JZ GOBK ; CHPC4: LXI H,TBL ;POINT TO SPECIAL CHARACTER TABLE CALL TSRCH ;GO PROCESS ; GOBACK: CALL VDADD ;GET SCREEN ADDRESS MOV A,M 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 ; VDEL0: CALL KSTAT ;CHARACTER WAITING? JZ GOBK ;NOPE ; VDEL1: CPI ESC ;RETURN TO SOLOS ON ESCAPE JZ COMND ; VDEL2: EQU $ VDEL3: CPI '1' ;GO BACK IF NOT 1-9 JC GOBK CPI '9'+1 JNC GOBK ANI 0FH ;KEEP LOWER NIBBLE JZ SESPD MOV C,A XRA A STC . ;SET BIT SPDLP: DCR C JZ SESPD RAL . ;MOVE IT OVER JMP SPDLP ; SESPD: STA SPEED ;SET NEW SPEED GOBK: POP B POP D ;RESTORE REGISTERS POP H RET . ;EXIT FROM VDMOT ; ; 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 ; NEXT: INX H INX H ; TSRCH: MOV A,M ;GET CHR FROM TABLE ORA A JZ OCHAR ;ZERO IS THE LAST 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 ; ; THIS ROUTINE READS A COMMAND LINE FROM KEYBOARD ; GCLIN: CALL SINP ;READ INPUT DEVICE JZ GCLIN ANI 7FH ;CLEAR PARITY BIT CPI ESC JZ COMN1 ;ABORT LINE 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 CONT: CALL SOUT JMP GCLIN ; ; ROUTINE TO CALCULATE SCREEN ADDRESS ; 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 POSITIIN VDAD0: CPI NLINES JC VDAD1 SUI NLINES JMP VDAD0 ; VDAD1: PUSH D LXI H,VDMEM-LLGTH LXI D,LLGTH VDAD3: DAD D DCR A JP VDAD3 MOV E,C DAD D POP D RET . ; ; ROUTINE TO REMOVE CURSOR ; CREM: CALL VDADD ;GET CURRENT SCREEN ADDRESS MOV A,M ANI 7FH ;STRIP OFF THE CURSOR MOV M,A RET ; ; PUT CHARACTER TO SCREEN ; 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 LLGTH-1 ;END OF LINE? JC OK LDA LINE CPI NLINES-1 ;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 LDA BOT ;DO THE HARDWARE SCROLL INR A CPI NLINES JNZ SROLX XRA A SROLX: CALL ERAS3 XRA A ;CLEAR THE LINE JMP CLIN1 ; ; INCREMENT LINE COUNTER IF NECESSARY ; OK: LDA NCHAR ;GET CHR POSITION INR A CPI LLGTH STA NCHAR RNZ . ;DIDN'T HIT END OF LINE, OK XRA A STA NCHAR ; PDOWN: EQU $ ;CURSOR DOWN ONE LINE HERE LDA LINE ;GET THE LINE COUNT INR A CURSC: CPI NLINES JNZ CUR XRA A CUR: STA LINE ;STORE THE NEW COUNT RET ; ; ERASE SCREEN ; PERSE: LXI H,VDMEM ;POINT TO SCREEN MVI M,0A0H ;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 VDMEM+1920 JNZ ERAS1 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 SCROLL PARAMETERS STA BOT ;BEGINNING OF TEXT OFFSET RET ; CLINE: CALL VDADD ;GET CURRENT SCREEN ADDRESS LDA NCHAR ;CURRENT CURSOR POSITION CLIN1: CPI LLGTH 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 JP CURSC MVI A,NLINES-1 JMP CURSC ;MERGE TO HANDLE CURSOR ; ; MOVE CURSOR LEFT ONE POSITION ; PLEFT: LDA NCHAR DCR A JP PCUR MVI A,LLGTH-1 PCUR: EQU $ ;CURSOR ON SAME LINE CPI LLGTH JNZ PCUR1 XRA A PCUR1: STA NCHAR ;UPDATED CURSOR RET . ; ; CURSOR RIGHT ONE POSITION ; PRIT: LDA NCHAR INR A JMP PCUR ; ; ROUTINE TO PROCESS A CARRIAGE RETURN ; PCR: EQU $ CALL CLINE ;CLEAR THE LINE XRA A JMP PCUR ;STORE NEW LINE VALUE ; ; ROUTINE TO PROCESS A LINEFEED ; PLF: LDA PRTOG ;SEE IF SPACE BAR HALT OK ANI 8 JNZ PLF2 ;NOT YET IN KDATA ;LOOK AT KEYBOARD PORT CPI ' ' ;SPACE BAR TYPED? JNZ PLF2 ;NZ SAYS NO ; PLF1: CALL KSTAT ;WAIT FOR ANOTHER KEY JZ PLF1 ; PLF2: LDA LINE ;GET LINE COUNT INR A CPI NLINES JNZ PLF3 ;NO--NO NEED TO SCROLL XRA A JMP SROL ;YES--THEN SCROLL ; PLF3: STA LINE JMP PCR ; ; ***** START UP SYSTEM ***** ; STRTA XRA A MVI C,48 ;Clear only what's necessary LXI H,SYSRAM ;Point to start of RAM ; CLERA: MOV M,A INX H DCR C JNZ CLERA IN STAPT IN KDATA ;CLEAR INPUT GARBAGE LXI SP,SYSTP ;SET UP THE STACK FOR CALL CALL PERSE COMN1: XRA A 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 LDA PRTOG ;GET FLAG BYTE PUSH PSW ORI 8 STA PRTOG ;NO SPC/BAR HALT YET CALL PROMPT ;PUT PROMPT ON SCREEN POP PSW STA PRTOG ;SPC/BAR OK NOW CALL GCLIN ;GET COMMAND LINE POP PSW STA OPORT ;RESTORE DEFAULT PORT CALL COPRC ;PROCESS THE LINE JMP COMND ;OVER AND OVER ; ; 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 ; 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 ; DISPT: EQU $ ;OFF TO A ROUTINE MOV A,M ;LO ADDR INX H MOV H,M ;HI ADDR MOV L,A ;HL NOW CGMPLETE 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 ; ; 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. ; FDCOM: LDAX D ORA A ;TEST FOR TABLE END RZ . ;NOT FOUND. COMMAND ERROR PUSH H CMP M INX D JNZ NCOM ;NOT FOUND INX H LDAX D CMP M JNZ NCOM 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 $ ASC 'DU' ;DUMP DW DUMP ASC 'EN' ;ENTER DW ENTER ASC 'EX' ;EXECUTE DW EXEC ASC 'SE' ;SET COMMAND DW CSET ASC 'CM' ;COMPARE MEMORY DW COMPM ASC 'BO' ;PTDOS BOOT DW DOS ASC 'NS' ;NORTHSTAR BOOT DW 0E800H ASC 'ED' ;EDIT DW EXDEP ASC 'MM' ;MOVE MEMORY DW MOVE ASC 'ZI' ;ZIP OR FILL MEMORY DW ZIP ASC 'SM' ;SEARCH MEMORY DW SERCH ASC 'HM' ;HEX MATH DW HMATH ASC 'TM' ;TEST MEMORY DW MEMT ; DB 0 ;END OF TABLE MARK ; ; DISPLAY DRIVER COMMAND TABLE ; 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 DB CEOL ;CLEAR TO EOL DW CLINE DB CR ;CARRIAGE RETURN DW PCR DB LF ;LINE FEED DW PLF DB BACKS ;BACKSPACE DW PBACK DB 7FH ;DELETE DW PBACK DB 'P'-40H ;TOGGLE PRINTER DW PRINT DB 7 DW BELL ; DB 0 ;END OF TABLE ; ; SECONDARY COMMAND TABLE FOR SET COMMAND ; SETAB: EQU $ ; ASC 'M=' ;SET MODE BYTE DW SETMD ASC 'C=' ;SET MOVE COUNT DW SETMOV DB 0 ;END OF TABLE MARK ; DHLOP LDAX D CMP M RNZ DCR B RZ INX H INX D JMP DHLOP ; BELL: MOV A,B OUT KDATA RET . ; PRINT: LDA PRTOG XRI 1 STA PRTOG RET . ;