; ; ; ; ***** * ; * * ; * * * ** * ; * * * * ; ***** ** ****** ; ; SYSTEM SOLFTWARE ; ; ; <<>> CONSOL <<>> ; ; ; VERSION: 1.0:5 ; RELEASE: 10.11.76 ; ; ; ; THIS PROGRAM IS THE MINIMUM SoL OPERATING SYSTEM. ; IT PROVIDES ALL NECESSARY DISPLAY ROUTINES ALONG WITH ; STANDARDIZED CALLING POINTS FOR INPUT/OUTPUT OPERATIONS. ; ; COMMANDS ARE ALSO AVAILABLE TO ENTER DATA TO MEMORY ; AND TO DISPLAY MEMORY DATA ON THE SCREEN. AN EXECUTE ; COMMAND IS PROVIDED TO ALLOW PROGRAM EXCUTION OUTSIDE ; OF THE CONSOL PROM AND PROVISION IS MADE FOR CASSETTE ; TAPE LOAD OF PROGRAMS OR DATA. ; ; ; NOTE: CONSOL,SOLOS AND SOLED ARE REGISTERED TRADEMARKS ; OF: ; PROCESSOR TECHNOLOGY CORP. ; EMERYVILLE,CALIF ; ; THE FOLLOWING CODE IS THE PROPERTY OF PROCESSOR ; TECHNOLOGY CORP. IT IS DISTRIBUTED ON A 'PERSONAL USE ; BASIS FOR THE BENIFIT OF SoL SYSTEM OWNERS. ALL FORMS ; OF THE CODE ARE COPYRIGHT 1976 BY PROCESSOR TECHNOLOGY ; AND ALL RIGHTS THERIN ARE RESERVED. ; ; ORG 0C000H ; START OF PROM AREA ; ; ; AUTO-STARTUP CODE ; DB 0 ; FOUR PHASE WONDER BGIN JMP STRTA ; ; ; ; ----= SoL SYSTEM I/O ROUTINES =----- ; ; THE FOLLOWING CODE IS STANDARDIZED FOR ALL SoL SYSTEM ; SOLFTWARE IT PROVIDES COMMON ENTRY POINTS FOR INPUT AND ; OUTPUT OPERATIONS. CONSOL DOES NOT HAVE PROVISION FOR ; PARALLEL I/O OPERATIONS BECAUSE OF SPACE LIMITATIONS. ; ; ; ; ; JUMP TABLE INPUT/OUTPUT ROUTINES ; ; THIS ROUTINE OUTPUTS THE CHARACTER IN REGISTER 'B' TO ; THE OUTPUT DEVICE POINTED TO BY THE CURRENT OUTPUT SELECT ; REGISTER. THE DEVICES ARE DEFINED AS FOLLOWS: ; ; 0 - VDM SCREEN ; 1 - SERIAL OUTPUT PORT ; 2 - PARALLEL OUTPUT PORT (NOT AVAILABLE ON CONSOL) ; 3 - ERROR HANDLER ; ; ENTRY AT: SOUT SELECTS CURRENT OUTPUT DEVICE ; AOUT SELECTS DEVICE IN REGISTER 'A' ; SOUT LDA OPORT ; GET PORT NUMBER FROM MEMORY LOCATION AOUT ANI 3 ; KEEP IT IN CONTROL PUSH H ; WE'LL RESTORE IT LATER LXI H,OTAB ; POINT TO TABLE RLC ; COMPUTE ADDRESS ADD L MOV L,A ; WE HAVE IT JMP DISPT ; GO TO HL.... ; ; ; ; THIS ROUTINE INPUTS A CHARACTER TO REGISTER 'A' FROM ; THE CURRENT INPUT DEVICE POINTED TO BY THE CURRENT INPUT ; SELECT REGISTER. ; ; ENTRY POINTS ARE DEFINED: ; ; 0 - KEYBOARD INPUT ; 1 - SERIAL INPUT ; 2 - PARALLEL INPUT (NOT AVAILABLE ON CONSOL) ; 3 - ERROR HANDLER ; SINP LDA IPORT ; GET PORT NUMBER FROM MEMORY LOCATION AINP ANI 3 ; WE MUST BE REASONABLE PUSH H ; SAVE H&L LXI H,ITAB ; POINT TO TABLE RLC ; THE MATH ADD L MOV L,A ; DONE JMP DISPT ; WE HAVE THE ADDRESS ... GO TO HEAVEN ; ; ; KEYBOARD INPUT STATUS CHECK ; ; THIS ROUTINE TESTS THE KEYBOARD STATUS AND RETURNS ; WITH THE TEST BITS SET. ; KSTAT IN STAPT ; GET STATUS WORD ANI KDR ; TEST KEYBOARD BIT RET ; FLAGS ARE SET ; ; ; KEYBOARD DATA INPUT ; ; THIS ROUTINE, ENTRY AT KREAD, GETS THE DATA FROM THE ; KEYBOARD. ON RETURN THE CHARACTER IS IN REGISTER 'A'. ; KREA1 POP H ; JUMP TABLE ENTRY POINT KREAD CALL KSTAT ; CHECK STATUS JNZ KREAD ; WAIT FOR INPUT IN KDATA ; GET DATA RET ; GO BACK WITH IT ; ; ; SERIAL INPUT STATUS CHECK ; SSTAT IN SERST ; GET SERIAL STATUS WORD ANI SDR ; TEST FOR SERIAL DATA READY RET ; FLAGS ARE SET ; ; ; SERIAL DATA INPUT ; SREA1 POP H ; RESTORE HL FROM JUMP TABLE ENTRY SREAD CALL SSTAT ; NORMAL ENTRY POINT JZ SREAD ; WAIT FOR INPUT IN SDATA ; GET DATA BYTE RET ; WE HAVE IT ; ; ; SERIAL DATA OUTPUT ; SEROT POP H ; JUMP TABLE ENTRY POINT 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 DRIVER ROUTINES ; ; ; THESE ROUTINES ALLOW FOR STANDARD VIDEO TERMINAL ; OPERATIONS. ON ENTRY, THE CHARACTER FOR OUTPUT IS IN ; REGISTER B AND ALL REGISTERS ARE UNALTERED ON RETURN. ; ; THE 'CONSOL' VERSION OF THIS ROUTINE IS A MINIMUM ; IMPLEMENTATION OF ROUTINES ORIGINATED BY: ; ; IAN KETTLEBOROUGH ; OF ; COLLEGE STATION, TEXAS ; ; SOLOS AND SOLED CONTAIN THE ESC SEQUENCES AND OTHER ; FULL IMPLEMENTATION FEATURES. ; VDMOT PUSH H ; SAVE EVERYBODY VDMO1 PUSH D ; ENTRY FROM DEVICE SELECT PUSH B PUSH PSW MOV A,B ; SAVE IN B...STRIP PARITY BEFORE SCREEN! LXI H,TBL CALL TSRCH ; GO PROCESS ; GOBACK CALL VDADD ; GET SCREEN ADDRESS MOV A,M ORI 80H MOV M,A ; CURSOR IS BACK ON GOBK POP PSW POP B POP D ; RESTORE ALL REGISTERS POP H RET ; EXIT FROM VDMOT ; ; TSRCH MOV A,M ; GET CHR FROM TABLE ORA A JZ CHAR ; 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 POP H ; ; ; THIS ROUTINE DISPATCHES TO THE ADDRESS POINTED TO ; BY THE HL REGISTER PAIR. THE RETURN ADDRESS IS THE ; LAST ENTRY ON THE STACK. ; DISPT MOV A,M ; GET LOW BYTE INX H MOV H,M ; AND THE HIGH MOV L,A ; WE HAVE PLACED THEM BOTH PCHL ; GO TO IT ; ; NEXT INX H ; GO TO NEXT INX H JMP TSRCH ; ; CHAR MOV A,B ; GET CHARACTER ORA A RZ ; RETURN IF A NULL CPI 7FH ; IS IT A DEL? RZ ; GO BACK IF SO ; ; ; OCHAR CALL VDADD ; GET SCREEN ADDRESS MOV A,B ; GET CHARACTER FOR OUTPUT ANI 7FH ; NO HIGH BITS GO PAST HERE MOV M,A ; 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 STA NCHAR ; STORE THE NEW CPI 64 RC XRA A ; WE'RE PAST THE END... REWIND THE COUNT STA NCHAR LDA LINE ; GET THE LINE COUNT INR A ANI 0FH ; MOD 15 INCREMENT CUR STA LINE ; STORE THE NEW RET ; ; ERASE SCREEN ; PERSE LXI H,VDMEM ; POINT TO SCREEN MVI M,80H+' ' ; THIS IS THE CURSOR ; ERAS1 INX H ; BUMP THE COUNT MOV A,H ; GET HIGH ORDER CPI 0D0H ; THE TOP JNC ERAS2 MVI M,' ' ; PUT IN A BLANK JMP ERAS1 ; ERAS2 XRA A STA LINE ; ZERO LINE STA NCHAR ; LEFT SIDE OF SCREEN ; 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 64 ; NO MORE THAN 63 RNC ; ALL DONE MVI M,' ' ; ALL SPACED OUT INX H INR A JMP CLIN1 ; LOOP TO END OF LINE ; ; HOME CURSOR ; PHOME XRA A STA NCHAR JMP CUR ; ; MOVE CURSOR DOWN ONE LINE ; PDOWN LDA LINE CPI 15 RZ ; HOW FAR IS DOWN? INR A JMP CUR ; ; ROUTINE TO MOVE THE CURSOR UP ONE LINE ; PUP LDA LINE ; GET LINE COUNT ORA A RZ ; DON'T GO MORE UP THAN UP DCR A JMP CUR ; ; MOVE CURSOR LEFT ONE POSITION ; PLEFT LDA NCHAR ORA A RZ ; DON'T GO MORE BACK THAN BACK DCR A PCUR STA NCHAR RET ; ; CURSOR RIGHT ONE POSITION ; PRIT LDA NCHAR CPI 63 RZ ; HOW RIGHT CAN WE BE? 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 ; IC' 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 ; MAKES FOUR MOV L,A ; L HAS IT ANI 3 ; MOD THREE FOR LATER MOV D,A MVI A,VDMEM SHR 8 ; LOW SCREEN OFFSET ADD D MOV H,A ; NOW H IS DONE MOV A,L ; TWIST L'S ARM ANI 0C0H ADD C MOV L,A RET ; H & L ARE NOW PERVERTED ; ; ROUTINE TO REMOVE CURSOR ; CREM CALL VDADD ; GET CURRENT SCREEN ADDRESS MOV A,M ANI 7FH ; STRIP OFF THE CURSOR MOV M,A RET ; ; ROUTINE TO BACKSPACE ; PBACK CALL PLEFT CALL VDADD ; GET SCREEN ADDRESS MVI M,' ' ; PUT A BLANK THERE RET ; ; ROUTINE TO PROCESS A CARRIAGE RETURN ; PCR CALL CLINE ; CLEAR FROM CURRENT CURSOR TO END OF LINE XRA A ; REWIND IT JMP PCUR ; AND STORE THE NEW VALUE ; ; ROUTINE TO PROCESS LINEFEED ; PLF LDA LINE ; GET LINE COUNT CPI 15 ; ARE WE AT THE BOTTOM? JNC SC INR A JMP CUR ; ONE MORE LINE UP ; SC XRA A JMP SROL ; ; ; ; THIS TABLE DEFINES THE CHARACTERS FOR SPECIAL ; PROCESSING. IF THE CHARACTER IS NOT IN THE TABLE IT ; GOES TO THE SCREEN. ; TBL DB CLEAR ; SCREEN DW PERSE DB UP ; CURSOR DW PUP DB DOWN DW PDOWN DB LEFT DW PLEFT DB RIGHT DW PRIT DB HOME DW PHOME DB CR ; CARRIAGE RETURN DW PCR DB LF ; LINE FEED DW PLF DB BACKS ; BACK SPACE DW PBACK DB MODE ; MODE KEY DW COMND DB 0 ; END OF TABLE ; ; OUTPUT DEVICE TABLE ; OTAB DW VDMO1 ; VDM DRIVER DW SEROT ; SERIAL OUTPUT DW ERROT ; ERROR HANDLER (FOR CONSOL) DW ERROT ; ERROR HANDLER ; ; INPUT DEVICE TABLE ; ITAB DW KREA1 ; KEYBOARD INPUT DW SREA1 ; SERIAL INPUT DW ERROT ; ERROR HANDLER (FOR CONSOL) DW ERROT ; ERROR HANDLER ; ; ; COMMAND TABLE ; ; THIS TABLE DESCRIBES THE VALID COMMANDS FOR CONSOL ; COMTAB DW 'TE' DW TERM DW 'DU' DW DUMP DW 'EN' DW ENTER DW 'EX' DW EXEC DW 'TL' DW TLOAD DW 'BA' ; SPECIAL COMMAND TO EXECUTE 0 DW 0 DB 0 ; END OF TABLE MARK ; ; ; CONSOL PORT ERROR HANDLER ; ERROT XRA A STA IPORT ; DEFAULT TO SCREEN STA OPORT ; DEFAULT TO SCREEN ; ; ; ; ; =-- COMMAND MODE --= ; ; ; THIS ROUTINE GETS AND PROCESSES COMMANDS ; COMND LXI SP,SYSTP ; SET STACK POINTER CALL PROMPT ; PUT PROMPT ON SCREEN CALL GCLIN ; GET COMMAND LINE CALL COPRC ; PROCESS THE LINE JMP COMND ; OVER AND OVER ; ; ; ; THIS ROUTINE READS A COMMAND LINE FROM THE SYSTEM ; KEYBOARD AND PROCESSES IT TO THE SCREEN. ; ; C/R TERMINATES THE SEQUENCE ERASING ALL CHARS TO THE ; RIGHT OF THE CURSOR ; L/F TERMINATES THE SEQUENCE ; MODE RESTARTS THE COMMAND LINE. ; GCLIN CALL KREAD ; READ KEYBOARD CPI 20H MOV B,A JC PROCS ; PROCESS CONTROL CHARACTER CONT CALL VDMOT JMP GCLIN ; ; PROCESS CONTROL KEYS ; PROCS CPI CR JZ CRPRC ; ERASE THE REMAINING LINE PRIOR TO RETURN CPI LF RZ ; IF SO GO PROCESS JMP GCLIN ; NO CONTROL CHARS TO SCREEN ; ; CRPRC CALL CLINE ; CLEAR REMAINING LINE RET ; NOW PROCESS ; ; ; FIND AND PROCESS COMMAND ; COPRC CALL CREM ; REMOVE THE CURSOR MVI C,1 ; SET FOR CHARACTER POSITION CALL VDAD2 ; GET SCREEN ADDRESS XCHG CALL SCHR ; SCAN PAST BLANKS JZ ERR1 ; NO COMMAND? XCHG ; HL HAS FIRST CHR LXI D,COMTAB ; POINT TO COMMAND TABLE ; ; 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 ; BY PLACING A QUESTION MARK WITHIN THE SEARCH STRING. ; FDCOM LDAX D ORA A ; TEST FOR TABLE END JZ ERR2 ; 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 ; POP B ; CLEAR THE STACK XCHG ; DE HAS SCAN ADDRESS INX H ; HL HAS COMMAND ADDRESS JMP DISPT ; DISPATCH TO IT ; ; NCOM INX D ; GO TO NEXT ENTRY INX D INX D POP H ; GET BACK ORIGINAL ADDRESS JMP FDCOM ; CONTINUE SEARCH ; ; ; OUTPUT A CRLF FOLLOWED BY A PROMPT ; ( WITH CONSOL ALL OPERATIONS ARE ON THE SCREEN) ; PROMPT CALL CRLF MVI B,'>' ; THE PROMPT JMP VDMOT ; PUT IT ON THE SCREEN ; CRLF MVI B,LF ; LINE FEED CALL VDMOT MVI B,CR ; CARRIAGE RETURN JMP VDMOT ; PUT IT OUT AND RETURN ; ; ; SCAN OVER UP TO 12 CHARACTERS LOOKING FOR A BLANK ; SBLK MVI C,12 ; MAXIMUM COMMAND STRING SBLK1 LDAX D CPI BLANK JZ SCHR ; GOT A BLANK NOW SCAN PAST IT INX D DCR C ; NO MORE THAN TWELVE JNZ SBLK1 RET ; GO BACK WITH ZERO FLAG SET ; ; ; SCAN PAST UP TO 10 BLANK POSITIONS LOOKING FOR ; A NON BLANK CHARACTER. ; SCHR MVI C,10 ; SCAN TO FIRST NON BLANK CHR WITHIN 10 SCHR1 LDAX D ; GET NEXT CHARACTER CPI SPACE RNZ ; WE'RE PAST THEM INX D ; NEXT SCAN ADDRESS DCR C RZ ; COMMAND ERROR JMP SCHR1 ; KEEP LOOPING ; ; THIS ROUTINE SCANS OVER CHARACTERS, PAST BLANKS AND ; CONVERTS THE FOLLOWING ADDRESS TO HEX. ERRORS RETURN TO ; THE ERROR HANDLER. ; SCONV CALL SBLK JZ ERR1 ; ; THIS ROUTINE CONVERTS ASCII DIGITS INTO BINARY FOLLOWING ; A STANDARD HEX CONVERSION. THE SCAN STOPS WHEN AN ASCII ; SPACE IS ENCOUNTERED. PARAMETER ERRORS REPLACE THE ERROR ; CHARACTER ON THE SCREEN WITH A QUESTION MARK. ; SHEX LXI H,0 ; CLEAR H & L SHE1 LDAX D ; GET CHARACTER CPI 20H ; IS IT A SPACE? RZ ; IF SO ; HCONV DAD H ; MAKE ROOM FOR THE NEW ONE DAD H DAD H DAD H CALL HCOV1 ; DO THE CONVERSION JNC ERR1 ; NOT VALID HEXIDECIMAL VALUE ADD L MOV L,A ; MOVE IT IN INX D ; BUMP THE POINTER JMP SHE1 ; HCOV1 SUI 48 ; REMOVE ASCII BIAS CPI 10 RC ; IF LESS THAN 9 SUI 7 ; IT'S A LETTER?? CPI 10H RET ; WITH TEST IN HAND ; ; ; SYSTEM START UP, CLEAR PART OF RAM AND SET STACK ; POINTER, FALLING THROUGH TO TERMINAL MODE. ; STRTA XRA A MOV C,A ; WE CLEAR THE FIRST 256 BYTES LXI H,SYSRAM ; POINT TO SYSTEM RAM ; CLERA MOV M,A INX H INR C JNZ CLERA ; CLEAR FIRST 256 BYTES ; ; ; ; TERM COMMAND ; ; THIS ROUTINE GETS CHARACTERS FROM THE SYSTEM KEYBOARD ; AND OUTPUTS THEM TO THE SERIAL OUTPUT PORT. IT IS ; INTENDED TO CONFIGURE THE SoL AS A STANDARD VIDEO ; TERMINAL. COMMAND KEYS ARE NOT OUTPUT TO THE OUTPUT ; PORT BUT ARE INTERPRETED AS DIRECT SoL COMMANDS. ; THE MODE COMMAND, RECEIVED BY THE KEYBOARD, PUTS THE ; SoL IN THE COMMAND MODE. ; ; TERM LXI SP,SYSTP ; SET STACK POINTER CALL TOFF ; SLOW DOWN THE TAPES CALL PERSE ; CLEAR THE SCREEN ; KIN CALL KSTAT ; IS THERE ONE WAITINGI JNZ TIN IN KDATA ; GET THE CHARACTER MOV B,A ANI 80H ; COMMAND KEY? JZ TOUT CALL VDMOT ; PROCESS IT JMP TIN ; TOUT CALL SDROT ; OUTPUT IT TO THE SERIAL PORT TIN CALL SSTAT ; GET SERIAL STATUS JZ KIN ; LOOP IF NOT IN SDATA ; GET DATA ANI 7FH ; NO HIGH BITS FROM HERE MOV B,A ; IT'S OUTPUT FROM 'B' CALL VDMOT ; PUT IT ON THE SCREEN JMP KIN ; LOOP OVER AND OVER ; ; ; ; DUMP COMMAND ; ; THIS ROUTINE DUMPS CHARACTERS FROM MEMORY TO THE ; CURRENT OUTPUT DEVICE. (WITH CONSOL ALL OUTPUT GOES TO ; THE SCREEN). ALL VALUES ARE DESPLAYED AS ASCII HEX. ; ; THE COMMAND FORM IS AS FOLLOWS: ; ; DUmp addr1 addr2 ; ; THE VALUES FROM ADDR1 TO ADDR2 ARE THEN OUTPUT TO THE ; OUTPUT DEVICE. IF ONLY ADDR1 IS SPECIFIED THEN THE ; VALUE AT THAT ADDRESS IS OUTPUT. ; DUMP CALL SCONV ; SCAN TO FIRST ADDRESS AND CONVERT IT PUSH H ; SAVE THE VALUE CALL SCHR ; GET THE NEXT POP H JZ POVER ; NO SECOND VALUE PUSH H CALL SHEX ; GET SECOND POP D ; THIS IS THE FIRST JMP NPASS ; MIND BENDERS ; POVER MOV D,H ; NO SECOND PARAMETER COPY FIRST TO DE MOV E,L NPASS XCHG ; HL HAS START, DE HAS END ; DLOOP CALL CRLF IN KDATA CPI MODE ; MODE KEY' WILL ESCAPE THE DUMP JZ COMND CALL ADOUT ; OUTPUT ADDRESS CALL BOUT ; ANOTHER SPACE TO KEEP IT PRETTY MVI C,16 ; VALUES PER LINE ; DLP1 MOV A,M ; GET THE CHR PUSH B ; SAVE VALUE COUNT CALL HBOUT ; SEND IT OUT WITH A BLANK CALL ACOMP ; COMPARE ADDRESSES JNC COMND ; ALL DONE POP B ; VALUES PER LINE INX H DCR C ; BUMP THE LINE COUNT JNZ DLP1 ; NOT ZERO IF MORE FOR THIS LINE JMP DLOOP ; DO A LFCR BEFORE THE NEXT ; ; OUTPUT HL AS HEX 16 BIT VALUE ; ADOUT MOV A,H ; H FIRST CALL HEOUT MOV A,L ; THEN L FOLLOWED BY A SPACE ; HBOUT CALL HEOUT BOUT MVI B,' ' JMP VDMOT ; CONSOL PUTS IT ON THE SCREEN ; HEOUT MOV C,A ; GET THE CHARACTER RRC RRC ; MOVE THE HIGH FOUR DOWN RRC RRC CALL HEOU1 ; PUT THEM OUT MOV A,C ; THIS TIME THE-LOW FOUR ; HEOU1 ANI 0FH ; FOUR ON THE FLOOR ADI 48 ; WE WORK WITH ASCII HERE CPI 58 ; 0-9? JC OUTH ; YUPI ADI 7 ; MAKE IT A LETTER OUTH MOV B,A ; OUTPUT IT FROM REGISTER 'B' JMP VDMOT ; ; COMPARE DE AND HL ; ACOMP MOV A,L SUB E MOV A,H SBB D RET ; FLAGS ARE SET ; ; ; ENTER COMMAND ; ; THIS ROUTINE GETS VALUES FROM THE KEYBOARD AND ENTERS ; THEM INTO MEMORY. THE INPUT VALUES ARE SCANNED FOLLOWING ; A STANDARD 'GCLIN' INPUT SO ON SCREEN EDITING MAY TAKE ; PLACE PRIOR TO THE LINE TERMINATOR. A BACK SLASH '/' ; ENDS THE ROUTINE AND-RETURNS CONTROL TO THE COMMAND MODE. ; ENTER CALL SCONV ; SCAN OVER CHARS AND GET ADDRESS PUSH H ; SAVE ADDRESS ; ENLOP CALL CRLF MVI B,':' CALL CONT ; GET LINE OF INPUT CALL CREM ; REMOVE THE CURSOR MVI C,1 ; START SCAN CALL VDAD2 ; GET ADDRESS XCHG ; ....TO DE ; ENLO1 MVI C,3 ; NO MORE THAN THREE SPACES BETWEEN VALUES CALL SCHR1 ; SCAN TO NEXT VALUE JZ ENLOP ; LAST ENTRY FOUND START NEW LINE ENLO2 LDAX D ; GET THE CHR CPI '/' ; COMMAND TERMINATOR? JZ COMND ; IF SO... CALL SHEX ; CONVERT VALUE MOV A,L ; GET LOW PART AS CONVERTED POP H ; GET MEMORY ADDRESS MOV M,A ; PUT IN THE VALUE INX H PUSH H ; BACK GOES THE ADDRESS JMP ENLO1 ; CONTINUE THE SCAN ; ; ; ; EXECUTE COMMAND ; ; THIS ROUTINE GETS THE FOLLOWING PARAMETER AND DOES A ; PROGRAM JUMP TO THE LOCATION GIVEN BY IT. IF PROPER ; STACK OPERATIONS ARE USED WITHIN THE EXTERNAL PROGRAM ; IT CAN DO A STANDARD 'RET'URN TO THE CONSOL COMMAND MODE. ; ; EXEC CALL SCONV ; SCAN PAST BLANKS AND GET PARAMETER PCHL ; GO ........ (AMD TAKE NOTE) ; ; ; ; TAPE LOAD COMMAND ; ; THIS ROUTINE READS FROM EITHER TAPE UNIT PLACING ; THE READ DATA INTO MEMORY. WHILE SPACE WITHIN CONSOL ; DOES NOT ALLOW FOR 'STANDARD' TAPE ROUTINES THIS ; COMMAND WILL LOAD SoL- BASIC5 AND OTHER STANDARD SoL ; SYSTEM SOLFTWARE FOR DIRECT EXECUTION. ; ; TLOAD CALL SBLK ; SCAN TO SPEED PARAMETER JZ DFLT ; DEFAULT TO HIGH SPEED IF NONE CALL SHEX ; CONVERT IT MOV A,L ; GET VALUE ANI 1 ; ONLY BIT ZERO COUNTS MVI A,32 ; PRETEND ITS SLOW JNZ SETSP ; DFLT XRA A ; MAKE IT FAST SETSP ORI TAPE1+TAPE2 ; CONSOL STARTS BOTH TAPES OUT STAPT ; START TAPES AND SELECT SPEED CALL DELAY ; WAIT WHILE THE TAPE UNIT WINDS UP IN TDATA ; CLEAR THE UART FLAGS ; TLOD1 CALL RHEAD ; READ PAST HEADER JNZ TLOD1 ; IF ERROR START OVER ; LHLD BLOCK ; GET BLOCK SIZE XCHG ; ...TO DE LHLD LOADR ; GET LOAD ADDRESS ; LOLOOP MOV A,D ; GET COUNT ORA E JZ TOFF ; COUNT IS ZERO-TURN OFF TAPE AND RETURN LXI B,-256 ; THIS MANY PRIOR TO CRC TEST XCHG ; COUNT TO HL DAD B ; A LITTLE MATH JNC LBLK ; NO CARRY, IT'S THE LAST BLOCK MVI B,0 ; 256 TO READ ; RDBLK MVI C,0 ; ZERO THE CRC XCHG ; ROUND ROBIN RTBYT CALL TAPIN ; GET CHARACTER MOV M,A ; STORE IT INX H ; BUMP MEMORY LOCATION XRA C ; UPDATE THE CRC CMA SUB C MOV C,A ; STORE THE NEW DCR B ; COUNT DOWN JNZ RTBYT ; STILL MORE IF NOT ZERO ; CALL CRCCK ; CHECK CRC AND FALL THROUGH TO ERROR IF NO GOOD JZ LOLOOP ; TEST OK ; TERR MVI B,'G'-40H ; BELL CHARACTER CALL VDMOT ; PUT IT ON THE SCREEN JMP COMND ; ; ; CONSOL ERROR HANDLER ; ERR1 XCHG ; GET SCAN ADDRESS ERR2 MVI M,'?' ; PUT A QUESTION MARK THERE JMP COMND ; AND GO TO COMMAND MODE ; ; READ THE HEADER ; RHEAD MVI B,10 ; FIND 10 NULLS RHEA1 IN STAPT ; GET A BYTE ANI TDR JZ RHEA1 IN TDATA ; IGNORE ERROR CONDITIONS ORA A ; ZERO? JNZ RHEAD DCR B JNZ RHEA1 ; LOOP UNTIL 10 IN A ROW ; ; WAIT FOR THE START CHARACTER ; SOHL CALL TAPIN DCR A JNZ SOHL ; WAIT FOR A '1' ; ; NOW GET THE HEADER ; LXI H,THEAD ; POINT TO BUFFER LXI B,HLEN*256 ; LENGTH OF HEADER IN 'B',C> ; ; ; VDM PARAMETERS ; VDMEM EQU 0CC00H ; VDM SCREEN MEMORY ; ; ; KEYBOARD SPECIAL KEY ASSIGNMENTS ; DOWN EQU 9AH UP EQU 97H LEFT EQU 81H RIGHT EQU 93H LOADK EQU 8CH ; LOAD KEY MODE EQU 80H CLEAR EQU 8BH HOME EQU 08EH BACKS EQU 5FH ; BACKSPACE LF EQU 10 CR EQU 13 BLANK EQU ' ' SPACE EQU BLANK CX EQU 'X'-40H ; ; PORT ASSIGNMENTS ; STAPT EQU 0FAH ; STATUS PORT GENERAL SERST EQU 0F8H ; SERIAL STATUS PORT SDATA EQU 0F9H ; SERIAL DATA TDATA EQU 0FBH ; TAPE DATA KDATA EQU 0FCH ; KEYBOARD DATA PDATA EQU 0FDH ; PARALLEL DATA DSTAT EQU 0FEH ; VDM DISPLAY PARAMETER PORT SENSE EQU 0FFH ; SENSE SWITCHES ; ; ; ; BIT ASSIGNMENT MASKS ; SCD EQU 1 ; SERIAL CARRIER DETECT SDSR EQU 2 ; SERIAL DATA SET READY SPE EQU 4 ; SERIAL PARITY ERROR SFE EQU 8 ; SERIAL FRAMING ERROR SOE EQU 16 ; SERIAL OVERRUN ERROR SCTS EQU 32 ; SERIAL CLEAR TO SEND SDR EQU 64 ; SERIAL DATA READY STBE EQU 128 ; SERIAL TRANSMITTER BUFFER EMPTY ; KDR EQU 1 ; KEYBOARD DATA READY PDR EQU 2 ; PARALLEL DATA READY PXDR EQU 4 ; PARALLEL DEVICE READY TFE EQU 8 ; TAPE FRAMING ERROR TOE EQU 16 ; TAPE OVERFLOW ERROR TDR EQU 64 ; TAPE DATA READY TTBE EQU 128 ; TAPE TRANSMITTER BUFFER EMPTY ; SOK EQU 1 ; SCROLL OK FLAG ; TAPE1 EQU 64 ; TAPE ONE 'ON' BIT TAPE2 EQU 128 ; TAPE TWO ; ; ; ; ; SoL SYSTEM GLOBAL AREA ; ORG 0C800H ; START OF 1K RAM AREA ; SYSRAM EQU $ ; START OF SYSTEM RAM SYSTP EQU $+1024 ; STACK IS AT THE TOP ; ; ; CONSOL PARAMETER AREA ; NCHAR DS 1 ; CURRENT CHARACTER POSITION LINE DS 1 ; CURRENT LINE POSITION BOT DS 1 ; BEGINNING OF TEXT DISPLACEMENT OPORT DS 1 ; OUTPUT PORT IPORT DS 1 ; INPUT PORT ; ; ; THEAD DS 5 ; NAME DS 1 ; THIS BYTE MUST BE ZERO HTYPE DS 1 ; TYPE BLOCK DS 2 ; BLOCK SIZE LOADR DS 2 ; LOAD ADDRESS XEQAD DS 2 ; AUTO EXECUTE ADDRESS HSPR DS 3 ; SPARES ; HLEN EQU $-THEAD ; LENGTH OF HEADER ; ; END