.SBTTL **** CONSOLE COMMANDS AS IMPLIMENTED **** .SBTTL *** "EB" CMD *** ;THIS CODE PERFORMS THE "EXAMINE BUS" CONSOLE FUNCTION. EBCMD: MVI A,01 ;FIRST CLR "R CLK ENB" OUT BUSCTL ;***** I/O WRT 210/001 ***** CALL RDATT ;***** I/O RD "0,1,2,3,103" (READ BITS 0-35) ***** .ADDR EMBUF ;PLACE BITS 0-35 INTO RAM BUFFER AREA "EMBUF" ;READ THE REST OF THE I/O REGISTERS AND SAVE IN THE RAM LXI H,RM100 ;GET BEGINNING ADDRESS OF RAM BUFFER AREA LXI D,IORGS ;D,E WILL POINT TO SOURCE OF REGS TO BE READ MVI B,8 ;THERE ARE 8 REGISTERS TO BE READ EB.RDIN: LDAX D ;FETCH UP FIRST REGISTER TO BE READ CALL ER.UTL ;CALL ER COMMAND MOV M,A ;COPY RESULTS OF READ INTO THE RAM SPACE INX D ;UPDATE SOURCE POINTER INX H ;UPDATE DESTINATION POINTER DCR B ;DOWN THE COUNTER JP EB.RDIN ;CONTINUE LOOP XRA A ;CLR ACCUM MUST SET "R CLK ENB" OUT BUSCTL ;***** I/O WRT 210/0 ***** PLINE EBHED ;EB CMD HEADER MSG CALL DECNET ;PRINT THE HEADING CALL P36. ;GO PRINT IT PCRLF ;AND A CALL DECNET ;AND MAKE SURE THIS GETS SENT LXI H,IORGS ;"H,L" NOW PNTS TO LIST OF I/O REGISTER NAMES LXI D,RM100 ;"D,E" NOW PNTS TO CORRESPONDING LIST OF DATA FOR I/O REG MVI B,8 ;ACCUM NOW CONTAINS A COUNT OF 8 (FOR 8 I/O REGS) EB1: CALL P8BIT ;PRINT FIRST REG NAME INX H ;BUMP TO NEXT PSLASH ;PRINT "1" XCHG ;SWAP SO "H,L" POINTS TO DATA CALL P8BIT ;PRINT DATA FOR THAT REG INX H ;BUMP TO NEXT XCHG ;SWAP BACK-"H,L" POINTS TO NAME AGAIN PSPACE ;SPACE OVER DCR B ;DOWN COUNT JNZ EB1 ;CONTINUE TILL DONE ALL EIGHT REGS PCRLF CALL DECNET ;AND FINALLY MAKE SURE LAST THING GETS SENT ENDCMD ;END-OF-COMMAND ;END THIS CODE WITH A 6 BYTE BUFFER OF THE I/O REGS NAMES, IN BINARY IORGS: .BYTE ^O100 ;FIRST REG NAME IN BINARY .BYTE ^O101 ;2ND .BYTE ^O102 ;3RD .BYTE ^O103 ;4TH .BYTE ^O300 ;5TH .BYTE ^O301 ;6TH .BYTE ^O302 ;7TH .BYTE ^O303 ;8TH .SBTTL *** "DB" CMD *** ;THIS CODE PERFORMS THE "DEPOSIT BUS" CONSOLE FUNCTION DBCMD: RUN.. ;IS CPU RUNNING?? JC DB1 ;SKIP CODE IF AT END OF COMMAND ARG36 ;IF NOT, GO ASSEMBLE ARG. .ADDR BUSAD ;AND PUT INTO BUFFER "BUS AD" DB1: CALL ADATT ;***** I/O WRT TO R DATA 0-35 DATA REG(ODDS) ***** .ADDR BUSAD ;BUFFER ADDRESS OF SOURCE OF DATA XRA A ;CLR ACCUM SO CAN CLR I/O REG 115 OUT BUSARB ;***** I/O WRT 115/0 ***** MVI A,^O141 ;BITS TO SET "CONSOLE REQ" & "T ENB FOR COM/ADR" OUT BUSCTL ;***** I/O WRT 210/141 ***** BUSRESP ARBRESP ;***** I/O READ 301 ***** JNZ NOARB ;IF NO ARB RESPONSE WITH "BUS REQ", ABORT CALL DBRDIN ;GO READ RESULTS, AND DO A 36-BIT COMPARE JNZ DBERR ;IF "Z-BIT" NOT SET REPORT MISCOMPARE & ABORT ;SECOND HALF OF COMMAND CALL ADATT ;CLR OUT OLD CRUD .ADDR MAD000 ;WITH ALL ZEROES CALL WDATT ;***** I/O WRT DATA 0-35 ADDR REG(EVENS) ***** .ADDR BUSAD ;BUFFER ADDRESS OF SOURCE OF DATA MVI A,01 ;BITS TO SET "DATA CYCLE" OUT ^O114 ;***** I/O WRT 114/1 ***** MVI A,^O363 ;BITS FOR "CONSOLE REQ", "TENB FOR COM/AD R" ;"T ENB FOR DATA CYCLE","LATCH DATA SENT" OUT BUSCTL ;***** I/O WRT 210/363 ***** BUSRESP ARBRESP ;***** I/O RD 301 ***** JNZ NOARB ;IF NO ARB RESP, ABORT WITH 2ND HALF MESSAGE BUSRESP DATACK ;HOW ABOUT DATA ACKNOWLEDGE?? JZ NOACK ;JUMP IF NONE CALL DBRDIN ;GO READ IN RESULTS AND COMPARE RESULT RZ ;IF Z-BIT, THEN OK TO EXIT ;ELSE FALL INTO THIS CODE IF A MISCOMPARE PCHAR DCHR ;PRINT "D" JMP DBCOM ;AND NOW THE ERR FINISHES UP LIKE THE 1ST HALF ;COMMON SUBROUTINE TO READ IN THE CONTENTS OF THE KS10 BUS & COMPARE AGAINST ;THE DATA WHICH WAS PUT ONTO THE BUS DBRDIN: CALL RDATT ;***** I/O RD 0,1,2,3,103 ***** .ADDR TMPB2 ;PLACE TO PUT RDATA 0-35 CALL CMP36 ;CHECK DATA JUST READ VS. DATA SENT .ADDR BUSAD ;SENT DATA .ADDR TMPB2 ;RECEIVED DATA RET ;DONE ;"DB" COMMAND CODE FOR THE CASES WHERE DATA DEPOSITED ON THE ;BUS IS NOT THE SAME AS THE DATA READ BACK FROM THE BUS.. ;...BY THE WAY..RIGHT NOW THIS IS PRETTY SLOPPY CODE.... DBERR: PCHAR CCHR ;PRINT A "C" DBCOM: PLINE MSG10 ;"?C CYC" LXI H,BUSAD ;ADDR OF 36-BIT DATA CALL P36 ;NOW PRINT THAT DATA PLINE DRCVD ;"RECEIVED DATA" LXI H,TMPB2 ;THIS IS ADDR OF RECEIVED DATA CALL P36 ;PRINT THAT 36-BIT DATA PCRLF ;AND CR-LF LXI H,4 ;PASS ERROR CODE BEFORE EXIT JMP ERRRTN ;GO FINISH WITH THE ERROR CODE .SBTTL *** "EM" CMD *** ;THIS IS THE ACTUAL "EM" COMMAND CODE EMCMD: JC EM1 ;SKIP CODE IF AT END OF COMMAND CALL LACMD ;GO FETCH UP AN ADDRESS TO EXAMINE EM1: XRA A ;CLEAR ACCUM STA ENEXT ;AND SET SO "EN " CMD WILL KNOW WHAT TO DO EM2: LXI D,MEMAD ;ADDRESS FOR MEMORY LOC. EMINT: MVI A,04 ;BIT TO SAY "READ FUNCTION" EN2ND: MOV B,A ;SAVE FUNCTION DATA XCHG ;DATA POINTER TO "H,L" SHLD AM.AI ;STORE FOR LATER USE BY COMMON CODE XCHG ;RESTORE "D,E" CALL ADATP ;***** I/O WRT 103,105,107,111,113 ***** MOV A,B ;GET FUNCTION EM.CRM: OUT A0003 ;***** I/O WRT 113/4 ***** ;NOW SET "COM/ADR" CYCLE MVI A,^O04 ;BIT TO SET COM/ADR CYC OUT BUSARB ;***** I/O WRT 115/4 ***** ;CHECK IF DOING EI OR EM LDA EIFLAG ;GET THE EI FLAG ANA A ;SET CODES, IF .NE. 0, THEN IT IS AN EI CODE JNZ EMCONT ;AND IF WAS EI, GO DO IT ;OTHERWISE JUST FALL THRU AND USE THE DM CODES MVI A,^O343 ;BITS FOR "CHECK NXM","CONSOLE REQ","T ENB FOR COM/ADR" ;"LATCH DATA SENT"," R CLK DISABLE" EMCONT: OUT BUSCTL ;***** I/O WRT 210/343 ***** XRA A ;CLEAR THE ACCUM STA EIFLAG ;CLEAR FLAG ON THE WAY OUT BUSRESP ARBRESP ;***** I/O RD 301 ***** JNZ NOARB ;IF GET NO "BUS REQ", ARB FAILED SO ABORT BUSRESP NONXMEM ;***** I/O RD 301 ***** JNZ NIXOM ;JUMP IF NON-EXISTANT MEM FLAG IS SET ;NOW MUST WAIT FOR "DATA ACKNOWLEDGE" FROM MEMORY BUSRESP DATACK ;***** I/O RD 301 ***** JZ NOACK ;JMP IF NO "DATA ACK"(BUS HAS 15 MIC. SEC TO RESP) ;HERE IF "DATA ACKNOWLEDGE" RECEIVED..GET RESULTS & PRINT LXI D,EMBUF ;PLACE TO PUT RECEIVED DATA CALL RDATP ;***** I/O RD 0,1,2,3,103 ***** XRA A ;SET ACCUM .EQ. 0 FOR "R CLK ENABLE" OUT BUSCTL ;***** I/O WRT 210/0 ***** LDA NOPNT ;GET THE PRINT FLAG ANA A ;SET CONDITION CODES RNZ ;AND DONT WASTE TIME IF NOT PRINTING LHLD AM.AI ;GET POINTER TO MEM ADDR JUST EXAMINED CALL P36 ;PRINT IT PSLASH ;PRINT "/" CALL P36. ;AND PRINT IT PCRLF ;CR-LF ENDCMD ;ALL DONE .SBTTL *** "EN" CMD *** ;ACTUAL CODE FOR "EN" CMD ENEM: CALL INC36 ;ADD 1 TO 36-BIT BUFFER .ADDR MEMAD ;THIS IS THE BUFFER TO INCREMENT JMP EM1 ;AND NO GO PROCESS JUST LIKE "EM" CMD .SBTTL *** "EN" CND *** ;EXAMINE NEXT WILL DO THE NEXT, SAME AS THE LAST ENCMD: LHLD ENEXT ;GET INDEX FOR WHICH EXAMINE IS NEXT LXI D,ENLST ;GET PNTR TO DISPATCH LIST DAD D ;AND NOW ADD "WHICH" EXAMINE MOV E,M ;GET LO ORDER PIECE INX H ;UPDATE MEM PNTR MOV D,M ;GET HI ORDER PIECE XCHG ;PUT THIS NEW ADDR INTO "H,L" PCHL ;AND TAKE THE DISPATCH ENLST: .ADDR ENEM ;DISPATCH FOR EXAM MEM CMD .ADDR ENEI ;DISPATCH FOR EXAM I/O .ADDR ENEK ;DISPATCH FOR EXAM KONSOL .ADDR ENEC ;DISPATCH FOR EXAMINCRAM .SBTTL *** "DM" CMD *** ;DEPOSIT MEMORY ACTUAL COMMAND CODE .SBTTL *** "DN" CMD *** DNDM: CALL INC36 ;INCREMENT MEMORY ADDRESS .ADDR MEMAD ;HERE IS CURRENT MEMORY ADDRESS DMCMD: ARG36 ;OTHERWISE, ASSEMBLE THE ARG .ADDR DMDAT ;PLACE TO PUT ASSEMBLED DATA DM1: XRA A ;0 IS THE INDEX FOR MEM NEXT CMDS STA DNEXT ;SAVE SO "NEXT" COMMAND WILL KNOW WHAT TO DO DM2: LXI D,MEMAD ;PNTR TO SM10 MEMORY ADDRESS DMINT: MVI A,02 ;BIT TO SAY "WRITE FUNCTION" DN2ND: MOV B,A ;SAVE FUNCTION STATUS CALL ADATP ;***** I/O WRT 103,105,107,111,113 ***** MOV A,B ;GET FUNCTION DATA OUT A0003 ;***** I/O WRT 113 ***** MVI A,04 ;BIT INTO ACCUM FOR "COM/ADR CYCLE" OUT BUSARB ;***** I/O WRT 115/4 ***** CALL WDATT ;***** I/O WRT 102,104,106,110,112 ***** .ADDR DMDAT ;PLACE TO GET DATA FOR DEPOSIT MVI A,01 ;BIT INTO ACCUM FOR "DATA CYCLE" OUT DTARB ;***** I/O WRT 114/1 ***** ;CHECK TO SEE IF DOING DI OR DM LDA DIFLAG ;GET THE FLAG ANA A ;SET THE CONDITION CODES JNZ DMCONT ;IF .NE. 0, THEN YOU GOT THE CODE FOR A DI ;OTHERWISE, FALL THRU TO DO A DM DMGO: MVI A,^O362 ;BITS FOR "CHECK NXM","CONSOLE REQ","T ENB FOR COM/ADR" ;"T ENB FOR DATA CYCLE"(LATCH DATA SENT PREVENTS FALSE PAR ERR) DMCONT: OUT BUSCTL ;*****I/O WRT 210/362 ***** XRA A ;CLEAR THE ACCUM STA DIFLAG ;AND CLEAR THE FLAG BUSRESP ARBRESP ;***** I/O RD 301 ***** JNZ NOARB ;IF NO "BUS REQ", ARB FAILED, SO ABORT ;IF THAT WAS OK, CHECK FOR NON-EXISTANT MEMORY BUSRESP NONXMEM ;***** I/O RD 301 ***** JNZ NIXOM ;IF FLAG SAYS NXM, THEN WE JUMP ;ELSE ALL OK.... ENDCMD .SBTTL *** "DN" CMD *** ;ROUTINE WILL DEPOSIT NEXT, JUST AS THE LAST DNCMD: LHLD DNEXT ;GET CODE FOR WHICH DEPOSIT IS NEXT LXI D,DNLST ;PNTR TO DISPATCH LIST DAD D ;ADD GIVES PNTR TO WHICH IS NEXT MOV E,M ;LO ORDER PIECE TO REG INX H ;UPDATE MEM PNTR MOV D,M ;HI ORDER PIECE TO REG XCHG ;NOW THE DISPATCH GOES TO "H,L" PCHL ;AND DISPATCH DNLST: .ADDR DNDM ;DISPATCH FOR DEP NEXT TO MEM .ADDR DNDI ;FOR DEPOSIT NEXT TO I/O .ADDR DNDK ;FOR DEPOSIT NEXT TO KONSOLE .ADDR DNDC ;FOR DEPOSIT NEXT CRAM .SBTTL *** "EI" CMD *** EICMD: RUN.. ;ILLEGAL COMMAND IF CPU RUNNING JC EI1 ;SKIP CODE IF AT END OF COMMAND CALL LICMD ;FETCH UP THE DESIRED I/O ADDRESS EI1: MVI A,2 ;DISP CODE FOR EXAMINE NEXT.. STA ENEXT ;TELL EXAMINE NEXT TO COME HERE LXI D,IOAD ;"H,L" GETS PNTR TO ADDR BUFFER MVI A,^O143 ;SPECIAL CODE FOR WHEN DOING DI STA EIFLAG ;PASS IT TO ROUTINE MVI A,^O14 ;BITS FOR "I/O FUNC" & "READ FUNC" JMP EN2ND ;JUMP TO COMMON CODE ;EXAMINE I/O ENTRY PNT FOR EXAMINE NEXT SITUATION ENEI: CALL IO.INC ;GO INCREMENT I/O ADDRESS TWICE JMP EI1 ;THEN ON TO COMMON CODE .SBTTL *** "DI" CMD *** .SBTTL *** "DN" CMD *** DNDI: CALL IO.INC ;GO INCREMENT THE I/O ADDRESS TWICE DICMD: ARG36 ;OTHERWISE GO ASSEMBLE THE ARG .ADDR DMDAT ;AND STORE IT HERE DI1: MVI A,02 ;SET WORD THAT SAYS DEP NEXT WILL BE DI STA DNEXT ;AND SAVE FOR "DN" CMD LXI D,IOAD ;PNTR TO ADDRESS DATA TO USE MVI A,^O160 ;SET CODE FOR USE BY DI COMMAND STA DIFLAG ;AND PASS IT TO ROUTINE MVI A,^O012 ;BITS TO SAY "I/O FUNC" & "WRITE FUNC" JMP DN2ND ;AND JUMP TO COMMON CODE IO.INC: CALL INC36 ;NOW INCREMENT I/O ADDRESS .ADDR IOAD ;ITS RIGHT HERE CALL INC36 ;NOW INCREMENT I/O ADDRESS .ADDR IOAD ;ITS RIGHT HERE RET ;AND BACK .SBTTL *** "EK" CMD *** ;ROUTINE EXAMINES 8080 LOCATIONS EKCMD: JC EK1 ;IF NOT, NO ARG TO BE ASSEMBLED ;OTHERWISE, MUST ASSEMBLE ARG ARG16 ;GO GET 16 BIT ADDR TO EXAMINE .ADDR C80AD ;AND PUT INTO CURRENT ADDR BUFFER EK1: MVI A,04 ;INDEX SAYS EK IS NEXT STA ENEXT ;SAVE IN THE RAM LXI H,C80AD ;GET CURRENT ADDR CALL P16 ;AND PRINT IT AS IS PSLASH ;NOW A "/" LHLD C80AD ;GET ADDR JUST PRINTED MOV A,M ;PASS ARG TO PRINT IN THE ACCUM JMP P8CRLF ; AND PRINT DATA PLUS CRLF, FOR FREE .SBTTL *** "EN" CMD *** ENEK: LHLD C80AD ;GET CURRENT 8080 ADDRESS INX H ;UPDATE SHLD C80AD ;PUT IT BACK JMP EK1 ;COMMON CODE .SBTTL *** "LA" CMD *** LACMD: ARG36 ;OTHERWISE, GET ARG & PUT IN 36-BIT BUFFER .ADDR MEMAD ;PLACE TO PUT DATA ENDCMD ;AND DONE .SBTTL *** "LI" CMD *** LICMD: ARG36 ;GET ARG AND PUT INTO A TEMP BUFFER .ADDR IOAD ;THIS TEMP BUFFER ENDCMD ;AND DONE .SBTTL *** "LK" CMD *** ;ROUTINE SETS CURRENT 8080 ADDRESS INTO RAM.. ;IF USER TRIES TO DEPOSIT PROM, TOO BAD. HE SHOULD KNOW BETTER LKCMD: ARG16 ;IF OK, GO ASSEMBLE 16 BIT ARG .ADDR C80AD ;THIS IS A GOOD PLACE TO KEEP IT ENDCMD ;AND END .SBTTL *** "DN" CMD *** DNDK: LHLD C80AD ;GET 8080 ADDRESS INX H ;INCREMENT BY 1 SHLD C80AD ;PUT IT BACK ;FALL INTO THE "DK" COMMAND .SBTTL *** "DK" CMD *** ;CODE TO DEPOSIT INTO 8080 RAM.. IF U TRY TO DEPOSIT PROM ;ITS YOUR OWN FAULT DKCMD: CALL ARG16. ;OK, NOW GO ASSEMBLE 16 BITS OF DATA MOV A,L ;GET DATA FROM LOC LHLD C80AD ;AND CURRENT ADDRESS TO "H,L" MOV M,A ;WRITE THE 8-BIT DATA MVI A,04 ;GET CODE THAT SAYS EXAMINE NEXT SHOULD BE "KONSOLE" STA DNEXT ;AND SAVE IN RAM ENDCMD ;ALL DONE .SBTTL *** "CP" CMD *** ;COMMAND TO SINGLE PULSE THE SM10 CPU CLK CPCMD: JC CP1 ;IF NO ARG, ONLY GIVE SINGLE CPU CLK CALL ARG16. ;ELSE GET ARG ;NOW GIVE NUMBER OF CLKS REQUESTED CPMLT: MOV A,L ;LO ORDER PIECE INTO ACCUM ORA H ;ADD THE HI ORDER PIECE RZ ;ALL DONE IF DOWN TO ZERO CALL CP1 ;OTHERWISE, GIVE CLOCK DCX H ;DECREMENT JMP CPMLT ;AND CONTINUE TILL DONE ALL CP1: MVI A,^O010 ;SET BIT FOR "SS MODE" OUT CRMCTL ;*****I/O WRT 204/010 ***** MVI A,2 ;SET BIT FOR "SINGLE CLK" OUT CLKCTL ;***** I/O WRT 206/2 ***** ENDCMD ;DONE.. .SBTTL *** "ER" CMD *** ;COMMAND TO EXAMINE ONE OF THE 8080 INTERNAL REGISTER, AND DISPLAY ;THE CONTENTS OF THAT REGISTER. ERCMD: JC ER1 ;IF NO ARG, GO USE THE ONE ALREADY IN THE RAM CALL ARG16. ;ELSE, PICK UP THE ARG THAT WAS TYPED ;FALL TO HERE IF ARG OK.. MOV A,L ;GET ACTUAL ARG INTO THE ACCUM STA ERADDR ;WELL, BEST SAVE THIS THING IN THE RAM ER1: LDA ERADDR ;COMMON TYPE CODE.. A NO-OP IF ARG WAS TYPED PUSH PSW ;NOW SAVE ACCUM PLEASE CALL P8BITA ;PRINT NAME OF THE 8080 REG THAT IS BEING EXAMINED PSLASH ;AND SEPARATE FROM ITS CONTENTS WITH A SLASH POP PSW ;RESTORE ACCUM PLEASE CALL ER.UTL ;EXECUTE THE INSTR PAIR FROM THE RAM SPACE ;BACK HERE AND THE DATA IS IN THE ACCUM CALL P8CRLF ;PRINT THE RESULTS RET ;AND DONE ;ROUTINE TO EXECUTE AN "IN" OR "OUT" FROM THE 8080 RAM SPACE RAMXCT: SHLD ER.LOC ;THE "IN/OUT" AND THE REG NUMBER INTO RAM SPACE PUSH PSW ;SAVE ACCUM, IN CASE ROUTINE IS AN "OUT" MVI A,.RET ;A "RETURN" INTO ACCUM STA ER.LOC+2 ; AND THEN THE RETURN GETS PUT INTO RAM SPACE POP PSW ;RESTORE ACCUM, ANYWAY CALL ER.LOC ;GO EXECUTE THE RAM LOC CMA ;FIX HARDWARE INVERSION RET ;BACK TO CALLER ;ROUTINE ER.UTL.. DOES AN EXAMINE REGISTER, INTERNAL TYPE FORMAT. ;NO PRINTING, JUST THE EXAMINE ;PASS DESIRED I/O REG ADDRESS IN ACCUM. ;ACCUM GETS THE RESULTS OF THE READ. ER.UTL: PUSH H ;SAVE H,L PAIR MOV H,A ;NOW, THE NUMBER THAT WAS TYPED IS PUT INTO HI HALF MVI L,.IN ;AND AN "IN" INSTR GOES LO HALF CALL RAMXCT ;NOW ACTUALLY EXECUTE THE CODE TO DO THE READ POP H ;FIX H,L RET ;OUT .SBTTL *** "LR" CMD *** ;COMMAND TO SET INTO THE 8080 RAM, THE I/O REGISTER TO BE EITHER ;DEPOSITED OR EXAMINED LRCMD: CALL ARG16. ;FETCH IN THE NUMBER TYPED MOV A,L ;DESIRED REG TO ACCUM STA ERADDR ;PUT IN 8080 RAM RET ;AND OUT .SBTTL *** "DR" CMD *** ;COMMAND TO DEPOSIT A NUMBER INTO THE LAST SPECIFIED 8080 I/O REG. DRCMD: ARG16 .ADDR T80DT ;TAKE ARG AND PUT INTO RAM SPACE MVI L,.OUT ;"L" GETS THE OPERATION TYPE WE WILL PERFORM LDA ERADDR ;FETCH UP THE CURRENTLY SELECTED I/O REG MOV H,A ;AND PUT IT INTO THE "H" LDA T80DT ;NOW THE DATA TO BE WRITTEN GOES TO THE ACCUM CALL RAMXCT ;PERFORM THE OPERATION RET ;THATS ALL .SBTTL *** "LC" CMD *** ;COMMAND TO LOAD THE 8080 RAM CURRENT CRAM ADDRESS LCCMD: ARG16 ;OK, ASSEMBLE THE 16 BITS .ADDR CRMAD ;TEMP PLACE TO KEEP BITS ENDCMD ;DONE.. .SBTTL *** "CE" CMD *** ;COMMAND TO SET CACHE ENABLE ON THE CSL BOARD ; OR PERHAPS CLR CACHE ENABLE IF DESIRED CECMD: JC CEDIS ;IF NO ARG, DISPLAY "CACHE ENABLE" CALL ARG16. ;MUST ASSEMBLE ARG IF FALL THRU MOV A,L ;ARG TO ACCUM RAL ;BIT 0 TO 1 RAL ;BIT TO 2 RAL ;BIT TO 3 ANI ^O10 ;OFF ALL BITS BUT THE CACHE BIT MOV B,A ;SAVE RESULT IN "B" FOR A LITTLE WHILE LDA PARBT ;GET CURRENT PARITY BIT STATUS ANI ^O367 ;OFF THE CACHE BIT ;HERE IS SOME COMMON CODE, USEFUL BY ROUTINES WHICH MUST ADJUST ;THE DATA IN THE PARBT LOCATION ENACOM: ORA B ;ADD NEW DATA TO DEFAULTED "PARBT" KS.PAR: STA PARBT ;NOW SAVE THE NEW DEFAULT OUT RESET ;***** I/O WRT 100/STUFF ***** ENDCMD ;AND ALL DONE ;CODE ENTERED WHEN WE WANT TO DISPLAY THE CACHE ENABLE STATUS CEDIS: LDA PARBT ;GET CURRENT STATUS ANI ^O10 ;IS THE CACHE BIT SET?? CHOOSE: JNZ PNT.ON ;HERE IF YES PLINE OFFMSG ;OFF MESSAGE DEPENDING THINGS RET PNT.ON: PCHAR 'O ;PRINTING "ON" A CHAR AT A TIME SAVES 1 BYTE PCHAR 'N ;OVER PRINTING IT AS A STRING..SPACE IS A LITTLE TIGHT PCRLF RET .SBTTL *** "TE" CMD *** ;CONSOLE COMMAND TO ENABLE OR DISABLE THE 1 MSEC CLOCK TECMD: JC TEDIS ;IF NO ARG, DISPLAY CURRENT STATE CALL ARG16. ;OTHERWISE, GO FETCH THE ARG MOV A,L ;GET INFO JUST TYPED RAL ;BIT 0 TO 1 RAL ;BIT TO 2 ANI ^O4 ;OFF ALL BUT THE TIME BIT MOV B,A ;SAVE STUFF IN B LDA PARBT ;GET CURRENT DEFAULT ANI ^O373 ;OFF THE 1 MSEC CLOCK SIGNAL JMP ENACOM ;GO DO COMMON CODE ;THIS CODE ENTERED WHEN WE ONLY WANT TO DISPLAY CURRENT STATE OF 1 MSEC CLOCK TEDIS: LDA PARBT ;WE NEED TO REPORT STATE..GET DEFAULT ANI ^O4 ;IS THE BIT SET?? JMP CHOOSE ;GO TO A COMMON PLACE THAT CHOOSES "YES" OR "NO" .SBTTL *** "SC" CMD *** ;CODE TO TURN OFF OR ON, THE ABILITY TO RECOVER FROM SOFT CRAM ERRORS ;FLAG AT 0, MEANS TRY AND RECOVER, THEREFORE ITS THE DEFAULT ON ;MACHINE POWER ON... SCCMD: JC SCDIS ;IF NO ARG TYPED, GO DISPLY STATE OF THE THING CALL ARG16. ;ELSE GO GATHER UUP AN ARGUMENT MOV A,L ;ARG GOES INTO ACCUM ANA A ;SET 8080 FLAGS JZ SC.TOFF ;IF ZERO , TURN OFF SC SOFT CRAM RECOVERY ;FALL THRU IF TURNING ON SCE XRA A ;ZERO ACCUM STA SC.OFF ;SO THAT WE CAN SET THE APPROPRIATE FLAG ENDCMD ;THAT'S IT SC.TOFF: MVI A,-1 ;WANT TO TURN OFF SCE, NEED -1 TO DO IT STA SC.OFF ;ZAP ENDCMD ;AND OUT SCDIS: LDA SC.OFF ;GRAB THE FLAG CMA ;SINCE 0 .EQ. ON, WE MUST INVERT FLAVOR OF FLAG ANA A ;SET 8080 PROCESSOR FLAGS JMP CHOOSE ;AND GO PRINT THE RIGHT THING .SBTTL *** "TP CMD" *** ;CONSOLE COMMAND TO ENABLE OR DISABLE THE TEN STYLE TRAPS TPCMD: JC TPDIS ;GO DISPLAY CURRENT STATE IF NOTHING TYPED CALL ARG16. ;OTHERWISE, GO ASSEMBLE A NUMBER TYPED IN MOV A,L ;GET INFO THAT WAS TYPED RAL ;BIT 0 TO 1 RAL ;1 TO 2 RAL ;2 TO 3 RAL ;3 TO 4 ANI ^O20 ;OFF ALL BUT TRAP BIT JMP TP.SET ;JUMP TO PLACE THAT SETS TRAPS, AND SAVES DATA ;CODE TO DISPLAY CURRENT STATE OF SIGNAL TPDIS: LDA TRAPEN ;GET CURRENT STATE OF TRAPS BIT ANI ^O20 ;SET CONDITION CODES JMP CHOOSE ;AND GO DO IT .SBTTL *** "LT" CMD *** ;CONSOLE COMMAND TO TURN ON THE LIGHTS ON THE CONSOLE FRONT PANEL LTCMD: CLRB KLNKSW ;FORCE A FIXING OF THE LIGHTS MVI A,7 ;LOAD ACCUM WITH A BIT FOR EACH OF THE 3 LIGHTS OUT LIGHTS ;***** I/O WRT 101/7 ***** CALL LTDLY ;LEAVE LIGHTS ON FOR ABOUT A SECOND XRA A ;CLEAR ACCUM OUT LIGHTS ;***** I/O WRT 101/0 ***** ;FALL INTO CODE THAT WAITS A WHILE WITH THE LIGHTS OFF LTDLY: LXI H,300 ;DELAY ABOUT A SECOND AND A HALF LTLOOP: CALL DELAY. ;GO DO A LITTLE DELAY .BYTE -1 ;MAX COUNT DCX H ;DOWN THE COUNT MOV A,L ;GET PIECE OF THE COUNT ORA H ;THROW IN THE REST OF THE COUNT JNZ LTLOOP ;CONTINUE WAITING RET ; UNTIL ALL DONE .SBTTL *** "MM" CMD *** ;COMMAND TO PUT THE 8080 INTO MANUFACTURING MODE. ;SETS THE STATE FOR THE KLINIK LINE THEN SENDS A COMMUNICATIONS CLEAR ;TO WHATEVER IS AT THE OTHER END OF THE KLINIK LINE MMCMD: CALL SETM4 ;SET KLINIK LINE TO MODE 4 MVI A,^O41 ;WE MUST ALWAYS RESET THE MESSAGE NUMBERS STA LSTMSG ;THIS IS THE "RECEIVE" MESSAGE NUMBER STA ENVMNO ;AND THIS IS THE "SEND" MESSAGE NUMBER STA MMFLG ;SAY MANUFACTURING MODE HAS BEEN ENTERED CALL Z.TBUF ;CLEAR SOME COMMUNICATION DEC10 BUFFERS JMP DECEX2 ;CLEAR THE MAILING ENVELOPES ;**USING JMP USES OTHER GUY'S RETURN TO RETURN .SBTTL *** "SI" CMD *** ;COMMAND TO CAUSE SM10 TO EXECUTE A SINGLE INSTR. SICMD: IN RUNFP ;BEFORE CONTINUING,MUST READ MACHINE STATE ANI 4 ;IS THE RUN FLOP SET(IS IT ALREADY RUNNING??)(TRUE LO) JZ YSRUN ;IF YES, GO PRINT A MESSAGE TO THAT EFFECT & ABORT CMD MVI A,01 ;SET BIT FOR "CONTINUE" OUT CPUCTL ;***** I/O WRT 212/1 ***** CALL DNF ;CHECK THAT INSTR FINISHED JMP PCCOM ;AND GO TO TYPE OUT THE PC .SBTTL *** "CS" CMD *** ;COMMAND TO START THE SM10 CPU CLK RUNNING CSCMD: CALL SETRN ;SET CLK "RUNNING" FLAG XRA A ;CLR ACCUM TO CLR "SS MODE" OUT CRMCTL ;***** I/O WRT 204/0 ***** MVI A,03 ;SET BITS FOR "CLK RUN" & "SINGLE CLK" OUT CLKCTL ;***** I/O WRT 206/3 ***** ENDCMD ;DONE.. .SBTTL *** "CH" CMD *** ;COMMAND TO HALT THE SM10 CPU CLK CHCMD: CALL CLRRN ;CLEAR CLK "RUNNING" FLAG MVI A,^O010 ;SET BIT FOR "SS MODE" OUT CRMCTL ;***** I/O WRT 204/010 ***** XRA A ;CLR BITS FOR "SINGLE CLK" & "CLK RUN" OUT CLKCTL ;***** I/O WRT 206/0 ***** ENDCMD ;DONE.. .SBTTL *** "LF" CMD *** ;COMMAND TO "LOAD FUNCTION"..SPECIFIES WHICH DIAG FUNCTION WRITE ;TO DO ON THE NEXT "DF" COMMANDS LFCMD: CALL ARG16. ;GO ASSEMBLE 16 BIT ARG(WE ONLY NEED 4 BITS) SHLD CRMFN ;PERMANENT HOME FOR DATA ENDCMD ;DONE.. .SBTTL *** "DF" CMD *** ;ROUTINE WRITES THE DATA TYPED USING THE DIAG FUNCTION ;PREVIOUSLY SPECIFIED BY LF COMMAND DFCMD: RUN.. ;IS CPU RUNNING?? CALL ARG16. ;GO ASSEMBLE ARG ;NEXT ROUTINE DOES LOTS OF I/O WRTS TO SM10 CPU ;ALL WHILE TRYING TO WRITE DIAGNOSTIC ADDRESS REG FOR CRAM ;LOADING OR READING.. PUSH H ;SAVE DATA TO BE DEPOSITED CALL CRM.AD ;WRITE THE CRAM ADDRESS POP H ;GET DATA TO BE DEPOSITED WFUNC: MOV A,L ;GET DATA FOR BITS 28-35 INTO ACCUM OUT A2835 ;***** I/O WRT 103 ***** MOV A,H ;GET DATA FOR BITS 20-27 OUT A2027 ;***** I/O WRT 105 ***** WFNC1: XRA A ;CLR ACCUM OUT BUSARB ;***** I/O WRT 115/0 ***** MVI A,^O144 ;BITS FOR "CONS REQ","T ENB FOR COM/ADR","CRA R CLK" OUT BUSCTL ;***** I/O WRT 210/144 ***** LDA CRMFN ;GET DIAG FUNCTION OUT DIAG ;***** I/O WRT 205/FNC ***** ;NOTE THAT "TRAP EN" WAS JUST ZAPPED, BUT IT IS ONLY USEFUL IF THE ;MICRO-CODE IS RUNNING AND ANYTHING U DO TO GET THE MICRO-CODE RUNNING ;WILL RESTORE THE TRAP ENABLE..THIS KLUDGE SPEEDS UP MICRO-CODE LOAD MVI A,^O40 ;BIT FOR "CRAM WRT" OUT CRMCTL ;***** I/O WRT 204/40 XRA A ;BIT TO CLR "CRAM WRT" OUT CRMCTL ;***** I/O WRT 204/0 ***** ENDCMD ;DONE.. ;SIMPLE LITTLE ROUTINE TO SAVE SOME SPACE..USED IN SEVERAL PLACES CRM.AD: LHLD CRMAD ;LOAD DIAG ADDR TO BE WRITTEN ;ROUTINE COUNTS ON DATA IN "H,L"..DESTROYS "H,L"... CADWR: MVI A,01 ;BIT FOR CRAM RESET OUT CRMCTL ;***** I/O WRT 204/1 ***** XRA A ;CLR BIT TO CLR CRAM RESET OUT CRMCTL ;***** I/O WRT 204/0 ***** ;***** I/O WRT 103,105,107,111,113 ***** MOV A,L ;LO ORDER 8 BITS TO ACCUM OUT A2835 ;SET IN HARDWARE REG MOV A,H ;HI ORDER 4 BITS TO ACCUM OUT A2027 ;SET INTO HARDWARE REG XRA A ;CLR ACCUM OUT A1219 ;CLR OTHER HARDWARE REGS OUT A0411 OUT A0003 OUT BUSARB ;***** I/O WRT 115/0 ***** MVI A,^O144 ;BITS FOR "CONS REQ", "T ENB FOR COM/ADR","CRA R CLK" OUT BUSCTL ;***** I/O WRT 210/144 ***** MVI A,^O21 ;BIT FOR "CRM ADDR LOAD" OUT CRMCTL ;***** I/O WRT 204/21 XRA A ;BIT TO CLR CRAM ADDR LOAD OUT CRMCTL ;***** I/O WRT 204/0 ***** RET ;AND RETURN ;ROUTINE TO READ A SINGLE DIAG FUNC WORTH OF STUFF FROM ;THE CRA/CRM PROCESSOR BOARDS READC: MOV D,A ;SAVE DIAG FUNC FOR A SEC.. LDA TRAPEN ;GET CURRENT VALUE FOR TRAP ENABLES ORA D ;MIX TOGETHER OUT DIAG ;***** I/O WRT 205/FNC ***** MVI A,^O115 ;BITS "CONS REQ","CRA T CLK","R CLK ENB","CRA R CLK" OUT BUSCTL ;***** I/O WRT 210/115 ***** IN D2835 ;***** I/O RD 0 ***** CMA ;FIX INVERSION STA TMPB2 ;SAVE IN STANDARD BUFFER IN D2027 ;***** I/O RD 1 ***** CMA ;FIX INVERSION ANI ^O17 ;KEEP ONLY 12-8 STA TMPB2+1 ;SAVE IN STANDARD BUFFER XRA A ;CLR ACCUM OUT BUSCTL ;***** I/O WRT 210/0 ***** RET ;RETURN .SBTTL *** "RC" *** RCCMD: RUN.. ;IS CPU RUNNING?? RCINT: XRA A ;CLEAR ACCUM FOR USE AS A COUNTER LXI B,CRMBF+^D31 ;PNTR TO A BUFFER AREA TO SAVE THE "RC'S" AS READ RCLP: MOV E,A ;SAVE IN "E" REG CALL READC ;READ A DIAG FUNC FROM CRA/CRM BRD ;NOW PRINT WHAT WAS READ LDA NOPNT ;WE WILL MAKE IT QUICKER IF NOT PRINTING RESULTS ANA A ;SET FLAGS JNZ RCNOP ;IF NO PRINT, AVOID TYPING CODE MOV A,E ;PUT IN MEM FOR PRINT ROUTINE CALL P8BITA ;PRINT NAME OF THIS DIAG FUNC PSLASH ;AND "/" CALL P16. ;AND PRINT IT PCRLF PUSH B ;SAVE COUPLE REGS WHILE GO DECNET PUSH D CALL DECNET ;YES.. SEND THIS GROUP OF DATA DOWN THE KLINIK LINE POP D ;RETRIEVE THOSE REGISTERS POP B ;CODE FOR SAVING THE RESULTS OF THESE FUNCTION READS IN THE 8080 RAM SPACE ;FOR NOW WE WILL SAVE THE RESULTS IN THE PLACE WHERE CRAM DATA IS KEPT RCNOP: LHLD TMPB2 ;FETCH UP THE DATA THAT WAS ACTUALLY READ MOV A,H ;GET LO ORDER PIECE TO ACCUM STAX B ;STORE TO PLACE POINTED TO BY "D,E" DCX B ;UPDATE THE STORAGE POINTER MOV A,L ;GET HI ORDER PIECE OF CRAM DATA STAX B ;SAVE IN STORAGE AREA DCX B ;AGAIN DOWNDATE POINTER TO BEGINING OF ACTUAL INR E ;INCREMENT IT MOV A,E ;COPY CURRENT COUNT TO ACCUM FOR THE COMPARE CPI ^O20 ;REACHED MAX YET?? JNZ RCLP ;BACK IF NOT YET.. ;OTHERWISE ENDCMD ;DONE... .SBTTL *** "EJ" CMD *** ;CONSOLE COMMAND TO DISPLAY THE FLOW OF THE CONTROL STORE BY PRINTING ;OUT THE CURRENT "J-FIELD", "NEXT LOC", "SUBROUTINE RET REG", & "CURRENT ; LOCATION" EJCMD: RUN.. ;IS CPU RUNNING?? LXI H,EJLST ;FIRST GET A PNTR TO ASCII TEXT LXI B,^B10010000111 ;SET B=4 & C="10,00,01,11" EJLP: MOV A,C ;COPY DIAG FUNC STRING TO ACCUM ANI 3 ;STRIP ALL BUT LO ORDER 2 BITS EJ1: CALL READC ;GO READ DIAG FUNC AS GIVEN BY ACCUM CALL PLN1 ;PRINT ASCII IDENTIFIER FOR THIS FUNC PUSH H ;SAVE "H,L" CALL P16. ;AND GO PRINT IT AS 16 BIT OCTAL PCHAR SPACE PCHAR SPACE POP H ;GET "H,L" BACK MOV A,C ;GET FUNCTION PICKER RRC ;SHIFT FUNCTION LIST RRC ; 2 PLACES MOV C,A ;PUT BACK FUNCTION DCR B ;NOW DOWN THE COUNTER JNZ EJLP ;AND JUMP TO THE EXECUTING CODE PCRLF ;AND A CR-LF ;ELSE.. END OF COMMAND ENDCMD ;RETURN TO CALLER EJLST: .ASCIZ %CUR/% ;FUNC 03 IS CURRENT CRAM LOCATION .ASCIZ %NXT/% ;FUNC 01 IS NEXT LOC .ASCIZ %J/% ;FUNC 00 IS J-FIELD .ASCIZ %SUB/% ;FUNC 02 IS SUBROUTINE RETURN REG .SBTTL *** "TR" CMD *** ;THIS CONSOLE COMMAND TRACES THE FLOW OF THE MICRO-CODE BY TYPEING ;THE 4 KNOWN ADDRESSES FROM THE CONTROL RAM ADDRESS BRD, THEN ISSUEING ;A SINGLE CPU PULSE AND CONTINUING THIS UNTIL THE USER TYPES A ;CARRIAGE RETURN. TRCMD: JC TR1 ;IF NO ARG, GO LIKE NORMAL ARG16 ;IF WAS ARG, GO GET IT .ADDR BRKDT ;PLACE TO PUT IT MVI A,^O77 ;NOW ANY ARBITRARY,NON-ZERO VALUE STA BRKON ;TO SAY THAT BREAKING IS ON.. TR1: RUN.. ;IS CPU RUNNING?? CLRB RPEND ;SO CAN CLR CMD CNTR TR: LDA BRKON ;CHECK IF BREAK IS ON ANA A ;CHECK FLAG JZ TRLP ;IF ZERO,DONT LOOK AT BREAK STUFF LXI D,BRKDT ;PASS PNTR TO THE DESIRED STOPPING ADDRESS CALL BREAK ;IF FLAG SET, CALL TO CHECK ADDRESS RZ ;IF RETURN WITH Z-SET, WE ARE AT BREAK PLACE TRLP: CALL PULSE ;GIVE PULSE PCRLF ;CARRIAGE RETURN LINE FEED LDA RPEND ;GET CMD CNTR ANA A ;IS IT SET?? JZ TR ;WELL, CONT LOOP IF NOT YET ;OTHERWISE, END THE COMMAND CLRB BRKON ;AND CLR THE FLAG ENDCMD ;DONE.. .SBTTL *** "PM" CMD *** ;CONSOLE COMMAND TO "PULSE" "MICRO-CODE",..IE GIVE ;A SINGLE PULSE AND THEN AN "EJ" COMMAND.. ;COMMAND IS EQUIVILANT TO THE "TR" TRACE COMMAND, ;ONLY EXECUTING THE TRACE ONCE.. PMCMD: RUN.. ;IS CLK RUNNING?? PULSE: CALL CP1 ;GO DO A SINGLE CLOCK CALL EJCMD ;TYPE CONTROL STORE ADDRESSES & EXIT FROM THERE ENDCMD ;AND OUT .SBTTL *** "EC" CMD *** ;ROUTINE TO READ THE C-RAM AND TYPE IT OUT ECCMD: RUN.. ;IS CPU RUNNING?? JC EC2 ;IF NO ARG, DONT GO ASSEMBLE ONE CALL LCCMD ;FETCH UP DESIRED CRAM ADDRESS EC1: CLRRM TMPB2 ;ZAP A TEMPORARY BUFFER CALL CRM.AD ;NOW WRITE DESIRED CRAM ADDRESS CALL CP1 ;AND GIVE A SINGLE CLK PULSE TO LOAD CNTRL REG EC2: MVI A,06 ;SET UP "EXAMINE NEXT" TYPE COMMANDS STA ENEXT ;SAVE EXAMINE STUFF IN RAM ;NOW READY TO READ THE CONTROL REG LXI H,RDLST ;GET PNTR TO DIAG FUNCTIONS TO BE READ ECLP: MOV A,M ;GET DIAG FUNCTION TO ACCUM INX H ;UPDATE PNTR ANA A ;WAS FNC END-OF-LIST(YES IF WAS MINUS) JM ECBEE ;JMP IF WAS END OF LIST ;OTHERWISE, WE MUST DO A DIAG FUNCTION CALL READC ;GO READ THIS DIAG FUNC,DATA RETURNED IN "TMPB2" SHLD ECSAV ;NOW SAVE "H,L" FOR A MINUTE LXI H,TMPB2 ;POINTER TO DATA JUST READ CALL OCTAL ;NOW TURN DATA INTO ASCII OCTAL CHARS .BYTE 2 ;TWO BYTES RELEVANT DATA .BYTE 4 ;WANT 4 OCTAL CHARS LHLD ECSAV ;RESTORE THE "H,L" JMP ECLP ;AND CONTINUE TILL READ ALL DIAG FUNCS ;WHEN U GET TO HERE, YOU'VE READ ALL FUNCS, NOW READ & CMP A & B COPIES ECBEE: MOV A,M ;GET DIAG FUNC FOR AN "A" COPY INX H ;UPDATE MEM PNTR ANA A ;DID DIAG FUNC HAVE MINUS SIGN?? JM PCRAM ;DONE LIST, JMP IF WAS MINUS ;OTHERWISE, GO AND READ THE "A" COPY AGAIN CALL READC ;DATA RETURNED IN "TMPB2" MOV5B ;MOVE THAT DATA TO 2ND TMP BUFF .ADDR TMPB2 ;SRC OF DATA .ADDR TMPBF2 ; PLACE TO PUT IT MOV A,M ;GET DIAG FUNC FOR A "B" COPY INX H ;UPDATE PNTR CALL READC ;NOW READ A "B" COPY PUSH H ;SAVE "H,L" CALL CMP36 ;NOW COMPARE THE "A" AND "B" COPIES .ADDR TMPB2 ;"B" COPY .ADDR TMPBF2 ;"A" COPY POP H ;RESTORE "H,L" JZ ECBEE ;IF CHECKED OK, BACK TO READ NEXT "A/B" COPIES ;FALL THRU TO VERIFY ERROR IF "Z" NOT SET PLINE ECVER ;"?VERIFY ERR" JMP RCINT ;GO PRINT ALL CRAM REGS ;IF "A/B" COPIES VERIFIED, TIME TO PRINT C-RAM CONTENTS PCRAM: MVI A,03 ;DIAG FUNC TO READ "CURRENT CRAM LOCATION" CALL READC ;GO READ CURRENT CRAM LOC.. CALL P16. ;PRINT IT PSLASH ; AND "/" ;NOW PRINT THE 32 OCTAL CHARS....... MVI B,32. ;NUM CHARS TO PRINT PCRLP: POP PSW ;GET A CHAR CALL PCHR ;PRINT IT DCR B ;DOWN COUNT OF CHARS PRINTED JNZ PCRLP ;LOOP TILL DONE PCRLF ;NEED CR-LF ENDCMD ;THEN OUT RDLST: .BYTE ^O17 ;READ 84-95 .BYTE ^O16 ;READ 72-83 .BYTE ^O15 ;READ 60-71 .BYTE ^O14 ;READ 48-59 .BYTE ^O12 ;READ 36-47A .BYTE ^O5 ;READ 24-35A .BYTE ^O4 ;READ 12-23 .BYTE 0 ;READ 0-11 .BYTE ^O377 ;END BYTE .BYTE ^O12 ;READ 36-47A .BYTE ^O13 ;READ 36-47B .BYTE ^O5 ;READ 24-35A .BYTE ^O6 ;READ 24-35B .BYTE ^O377 ;END BYTE .SBTTL *** "EN" CMD *** ENEC: LHLD CRMAD ;GET CURRENT ADDRESS INX H ;UPDATE IT SHLD CRMAD ;PUT IT BACK JMP EC1 ;GO TO COMMON CODE .SBTTL *** "DC" CMD *** .SBTTL *** "DN TO DC" CMD *** ;CODE USED IN DEPOSIT NEXT FOR THE CRAM DNDC: LHLD CRMAD ;GET CURRENT ADDRESS INX H ;INCREMENT IT SHLD CRMAD ;PUT IT BACK DCCMD: RUN.. ;IS CPU RUNNING?? CALL ARG96 ;ASSEMBLE DATA TO DEPOSIT .ADDR CRMTM ;PLACE TO PUT IT LXI D,CRMBF ;PLACE TO PUT THE RESULTS OF THE CRAM SHUFFLE LXI H,CRMTM ;THE OLD 12-BYTE FORMAT WILL ALWAYS BE HERE MVI C,4 ;LOAD "C" WITH A 4 ;BEGIN THE UNPACKING GENLP: CALL PLACE ;LOCAL ROUTINE THAT TAKES 12 BITS OF 24. MVI A,3 ;A SHIFT 24 REQUIRES 3 BYTES OF DATA TO SHIFT CALL SHR24 ;SHIFT 12 BITS JUST PACKED INTO OUTER SPACE .BYTE 12. ;TELL ROUTINE 12 PLACES CALL PLACE ;NOW ROUTINE WILL GET 12 MORE BITS..12+12=24 INX H ;UPDATE PNTR 3-BYTES(IE 24 BITS) INX H INX H DCR C ;DOWN THE COUNTER(THERE ARE 4 GROUPS OF 24=96) JNZ GENLP ;CONTINUE TILL DONW THE 4 GROUPS CALL CRM.AD ;WRITE THE CRAM ADDRESS LXI H,CRMBF ;GET PLACE WHERE INFO WAS JUST PLACED MVI A,06 ;NUMBER FOR DEPOSIT NEXT TO USE STA DNEXT ;STANDARD PLACE TO KEEP IT INR A ;SET FUNCTION .EQ. 7(INR WORKS BY LUCK) LXI B,CRMFN ;SET AN ADDRESS INTO "B,C" REGISTER,TO USE AS A POINTER DCLP: STAX B ;SAVE IT IN THE RAM AT LOC "CRMFN" MOV E,M ;GET 8 BITS OF DATA INX H ;UPDATE PNTR MOV D,M ;GET 4 MORE BITS OF DATA INX H ;AND UPDATE PNTR AGAIN XCHG ;NOW "H,L" CONTAINS THE DATA & "D,E" THE PNTR CALL WFUNC ;AND DIAG FUNCTION WRT XCHG ;POINTER BACK TO "H,L" LDAX B ;GET PARTICULAR DIAG FUNC FROM RAM LOC DCR A ;DOWN TO NEXT JP DCLP ;AS LONG AS 0-7, KEEP GOING ENDCMD ;NOW ALL DONE .SBTTL *** "SM" CMD *** ;CODE TO START THE MICRO-CODE AT THE ADDRESS SPECIFIED.. ;DEFAULTS TO STARTING AT C-RAM LOC 0 IF NO ADDRESS IS ;GIVEN SMCMD: JC SM1 ;IF NO ARG, SUPPLY ADDRESS OF 0000 ;OTHERWISE MUST ASSEMBLE THE GIVEN ADDRESS CALL ARG16. ;ASSEMBLE 16-BITS OF ARGUMENT JMP SM1.5 ;OTHERWISE, CONTINUE NORMALLY SM1: LXI H,00 ;IF HERE, DESIRE ADDRESS OF 0000 SM1.5: SHLD T80DT ;SET ADDR CALL MRCMD ;RESET THE MACHINE MOV5B ;SET UP INITIAL DATA .ADDR ONES ;DATA TO BE IS ALL ONES .ADDR DMDAT ;PLACE WHERE IT GOES LXI D,MAD000 ;GET ADDRESS OF MEM LOC 0 CALL DMINT ;"DEPOSIT MEMORY" INTERNAL FORMAT LDA PARBT ;GET PARITY STUFF ANI ^O140 ;ONLY KEEP A LITTLE BIT OUT RESET ;AND TURN OF ALL PARITY STUFF WHILE WE DO THIS LHLD T80DT ;GET START ADDRESS OF MICRO-CODE TO "H,L" CALL CADWR ;WRITE THE DIAG ADDRESS REG CALL CSCMD ;START THE CPU CLK FREE RUN HLTCM: CALL DELAY. ;NOW WAIT FOR MICRO-CODE TO REACH HALT LOOP .BYTE -1 CALL CLRUSE ;EXIT FROM USER MODE IN RUNFP ;***** I/O RD 300 ***** CMA ;AND FIX INVERSION ANI ^O10 ;IS CPU IN THE HALT LOOP??? JNZ SMVER ;JUMP IF YES..APPEARED TO START OK ;FALL TO HERE IF SM10 DID NOT SET HALT LOOP FLAG PLINE SMERR ;PRINT ERR MESSAGE STC ;SET C-BIT TO INDICATE AN ERROR EXIT JMP SMFINI ;AND EXIT VIA RESTORE PARITY PATH SMVER: INTON ;SET INTERAL STATUS FOR THE EXAMINE EXAM 0 ;EXAMINE MEM LOC 0(MICRO-CODE STOP CODE) INTOFF ;TURN OFF INTERNAL STATUS ;IT DID SUCCEED IN SETTING HALT LOOP FLAG, SO MERELY PRINT HALTED ;AND THE DATA IN LOCATION 0.. ;****SUBROUTINE "STOP CODE" **** CALL SETRN ;JUST A LITTLE KLUDGE..CHEAP WAY TO FIX STATE LIGHT ; IF PROGRAM EXECUTED A "HALT" WHILE LITES WERE BLINKY PLINE HLTMS ;PRINT "HALTED" MESSAGE LXI H,EMBUF ;PNTR TO DATA IN LOC 0 CALL P18 ;PRINT RIGHT HALF OF 36-BIT DATA CLRB CHKHLT ;SET FLAG TO SAY WEVE TYPED HALTED ALREADY PSPACE ;PRINT A SPACE PSPACE ;AND ANOTHER PCCOM: INTON ;SET INTERNAL MODE EXAM 1 ;EXAMINE WORD WHICH HOLDS THE PC INTOFF ;CLR INTERNAL MODE PLINE PCMSG ;PRINT "PC/" CALL P36. ;AND PRINT THE PC PCRLF ;PRINT CARRIAGE RETURN LINE-FEED ANA A ;CLEAR THE C-BIT 'CAUSE ALL OK ;AND BEFORE WE LEAVE,RESTORE THE PARITY STUFF SMFINI: LDA PARBT ;GET CURRENT PARITY DEFAULTS OUT RESET ;RESTORE THE PARITY DETECTS RET ;AND OUT ZEROES: MAD000: D 0,0,,0,0 ;MEMORY ADDRESS 0 ; FROM MEMORY LOCATION 0 .SBTTL *** "PE" CMD *** ;COMMAND TO ENABLE VARIOUS PARITY CHECKS NORMALLY MADE BY THE 8080.. ;ACCEPTABLE PARITY COMMANDS ARE: ; PE 0 ;"DISABLE" ALL PARITY DETECTION ; PE 1 ;"ENALE" "DP" PARITY DETECT ; PE 2 ;"ENABLE" "CRM" PARITY DETECTION ; PE 4 ;"ENABLE" "PE" PARITY DET(CLK FREEZE ON PAR ERR) ; PE 7 ;"ENABLE" ALL ;BITS ARE WEIGHTED FOR THE THREE TYPES OF PARITY ERRORS PECMD: JC PARDIS ;COMMAND REQUIRES ARG CALL ARG16. ;ASSEMBLE TYPED ARG MOV A,L ;GET NUMBER TYPED INTO THE ACCUM ANI ^O7 ;KEEP ONLY APPROPRIATE BITS RAL ;BIT 0 INTO BIT1 RAL ;BIT 0 INTO BIT 2 RAL ; INTO BIT 3 RAL ; INTO BIT 4 MOV L,A ;SAVE IN L LDA PARBT ;NOW GET CURRENT STATUS ANI ^O217 ;OFF THE OLD CRUMMY PARITY ORA L ;THROW IN THESE NEW BITS JMP KS.PAR ;SAVE IN RAM PLACE & WRITE TO KS ;THIS IS THE CODE FOR IF WE WANT TO DISPLAY THE PARITY PARDIS: LDA PARBT ;GET THE CURRENT PARITY STATUS ANI ^O160 ;CLR CRUD, JUST SAVING PARITY BITS RAR ;ROTATE TO JUSTIFY THE BITS AT BIT 0 RAR RAR RAR P8CRLF: CALL P8BITA ;AND GO PRINT THOSE 8 BITS PCRLF ;TERMINATE ALL WITH A CR-LF ENDCMD ;ALL DONE .SBTTL *** "EX" CMD *** ;CONSOLE COMMAND TO EXECUTE A SINGLE SM10 "TEN ORDER" INSTRUCTION EXCMD: ARG36 ;GO ASSEMBLE THE INSTR TO BE EXECUTED .ADDR EMBUF ;PLACE TO PUT IT EXINTM: LXI D,EMBUF ;POINTER TO INSTR INTO "D,E" EXINT: CALL WDATP ;***** I/O WRT 102,104,106,101,112 ***** MVI A,2 ;SET BIT FOR "I/O DATA CYCLE" OUT DTARB ;***** I/O WRT 114/2 ***** MVI A,3 ;BITS FOR "EXECUTE" & "CONTINUE" OUT CPUCTL ;***** I/O WRT 212/3 ***** DNF: NOP NOP ;WAIT IN RUNFP ;***** I/O RD 300 ***** CMA ;FIX INVERSION ANI 1 ;IS CONTINUE STILL SET?? RZ ;IF CLR, WE ARE OK... ;IF CONT STILL SET, WE HAVE AN ERROR PLINE EXMS ;ERR MESSAGE "?DNF-DID NOT FINISH" CALL CLRUSE ;EXIT FROM USER MODE CMA ;ACCUM NOW .EQ. -1 ANA A ;SET FLAGS, SO "JNZ" WILL JUMP RET ;AND RETURN .SBTTL *** "ST" CMD *** ;CONSOLE COMMAND TO ISSUE A START TO THE CPU STCMD: CALL LACMD ;FIRST GO ASSEMBLE A LEGAL ADDRESS AT WHICH TO START MOV5B ;MOVE TO TMP BUFF SO DONT KILL "MEMAD" .ADDR MEMAD ;SRC .ADDR TMPBF2 ;TEMP PLACE TO KEEP IT STINT: CLRRM DMDAT ;MUST CLR COMM WORDS BEFORE WE START DEPOS 31 ;CLEAR LOC 31(KEEP ALIVE WORD) DEPOS 32 ;CLEAR LOC 32(THE TTY INPUT WORD) DEPOS 33 ;AND 33(THE TTY OUTPUT WORD) LXI H,^O2540 ;LOAD "H,L" WITH "JRST" OPCODE SHLD TMPBF2+3 ;AND PUT INTO THE BUFFER WHERE THE ADDR IS LXI D,TMPBF2 ;NOW SET POINTER TO THE INSTR CALL EXINT ;AND GO HANDLE JUST LIKE AN EXECUTE RNZ ;IF NON ZERO, THE EXECUTE FAILED LONG.DELAY 1 ;NOW WAIT ;AND NOW FALL INTO THE "CONTINUE" COMMAND .SBTTL *** "CO" CMD *** ;CONSOLE COMMAND TO ISSUE CONTINUE TO CPU COCMD: CALL SETUSE ;ENTER USER MODE MVI A,^O5 ;SET BITS FOR "CONTINUE" & "RUN" OUT CPUCTL ;***** I/O WRT 212/5 ***** COINT: STA CHKHLT ;AND GAURANTEE THAT ANY FAST HALTS WILL GET REPORTED PLINE KSPRMT ;WANT TO TELL USER WHEN WE SWITCH MODES PLINE U ;SAY "USER MODE" ;AND JUMP OFF TO COMMON CODE THAT CHECKS THE CONTINUE BIT ;AND ERRS IF CONTINUE HAS NOT BEEN CLEARED BY THE CPU JMP DNF ;GO.... .SBTTL *** "HA" CMD *** ;CONSOLE COMMAND TO HALT THE SM10 CPU..CPU MICRO-CODE SHOULD ENTER ;THE HALT LOOP HACMD: XRA A ;CLR ACCUM FOR "RUN","EXECUTE" & "CONTINUE" OUT CPUCTL ;*****I/O WRT 212/0 ***** JMP HLTCM ;AND FINISHES UP JUST LIKE "SM" COMMAND .SBTTL *** "SH" CMD *** ;COMMAND TO CAUSE THE TOPS20 MONITOR TO BEGIN AN ORDERLY SYSTEM SHUTDOWN SHCMD: MOV5B ;MOVE US SOME DATA .ADDR .DSBASE ;FROM HERE (0,,776700) .ADDR DMDAT ;TO HERE. PLACE FOR DEPOSIT TO FIND IT DEPOS 30 ;AND DO IT CALL SETUSE ;NOW BE SURE WE ENTER THE USER MODE AGAIN MVI B,^O200 ;SET SIGN BIT, CAUSES "KEEP-ALIVE" TO BE IGNORED CALL STATEM ;GO DO THE STUFF .BYTE ^O377 ;WITHOUT CHANGING THINGS JMP COINT ;AND GO BACK TO USER MODE TO WATCH MONITOR "SHUTDOWN" .SBTTL *** "KL" CMD *** ;KLINIK COMMAND KLCMD: JC KLDIS ;DISPLAY CURRENT STATE IF NOTHING TYPED ;ELSE ASSEMBLE THE TYPED IN ARG CALL ARG16. ;PERMIT 16 BIT WIDE TYPE IN ;NOW VERIFY THAT LOWER HALF IS A LEGAL NUMBER MOV A,L ;LO HALF TO ACCUM ANA A ;SET CONDITION CODES JZ KLOFF ;IF TYPED ZERO, GO TURN OFF KLINIK ;NOW FALL THRU HERE IF .EQ. 1, MUST TURN ON THE KLINIK STA KLLINE.ON ;SET BIT TO SAY THAT KLINIK IS ON RET ;AND OUT KLOFF: STA KLLINE.ON ;GET HERE IF ACCUM WAS ZERO.. ZAP THE KLINIK FLAG ;AND FALL INTO CODE TO SEE IF THE END OF KLINIK MUST FORCE A CHANGE IN THE ;STATE OF THE KLINIK LINE AND USER. IE IF IN MODE 3, WE MUST FORCE USER ;INTO MODE 2 LDA CSLMODE ;GET CURRENT MODE CPI .MODE3 ;IS IT MODE 3?? CZ SETM2 ;SET MODE 2 IF NOT IN THERE RET ;AND OUT ;HERE IF JUST WANT TO DISPLAY CURRENT KLINIK STATE KLDIS: LDA KLLINE.ON ;GET CURRENT VALUE ANA A ;SET FLAGS JMP CHOOSE ;GO DISPLAY THE APPROPRIATE MESSAGE .SBTTL *** "TT" CMD *** TTCMD: CALL SETUSE ;ON THIS COMMAND WE DESIRE THAT THE CTY ENTER USER MODE PLINE KSPRMT ;"KS10>" PLINE U ; "USR MOD" JMP SETM2 ;SIMPLE TRANSFER OF KLINIK LINE TO MODE 2 .SBTTL *** "PW" CMD *** ;COMMAND FOR SETTING A PASSWORD INTO THE 8080, SO THAT THE KLINIK LINE ;USER WILL HAVE SOMETHING TO MATCH AGAINST WHEN HE TRIES TO GET INTO THE SYSTEM PWCMD: MVI A,0 ;ON ANY PASSWORD COMMAND, FORCE A RE-EXAMINE OF STA KLNKSW ;OF THE KLINIK MODE ;NOW DO THE NORMAL STUFF U NEED TO DO WITH THIS COMMAND JC PW.CLR ;IF NO PW TYPED, GO CLR PASSWORD ;FALL THRU ELSE.. IE MUST SET THE PASSWORD PW.SET: LHLD .ARG1 ;GET POINTER TO THE TYPE-IN BUFFER LXI D,PASSWORD ;POINT TO THE BUFFER AREA WHERE THE PASSWORD WILL BE MVI B,-6 ;SET A MAX COUNT FOR THE LENGTH OF THE PASSWORD PW.LOOP: MOV A,M ;COPY A PASSWORD CHARACTER TO THE ACCUM CPI EOLCH ;IS IT END OF LINE?? RZ ;IF YES,SIMPLE RETURN ;FALL TO HERE IF MORE TO BE MOVED CALL UP.LO ;UPPER CASE ONLY STAX D ;MOVE A CHARACTER TO THE SAVE BUFFER INX D ;UPDATE DESTINATION POINTER INX H ;UPDATE SOURCE POINTER INR B ;UPDATE CHARACTER COUNT JNZ PW.LOOP ;STAY IN THE LOOP ;FALL THRU WHEN DONE 6 CHRACTERS.. THAT HAD BETTER BE ALL, ELSE ERROR MOV A,M ;GET 7TH CHARACTER CPI EOLCH ;IT BETTER BE END RZ ;IF YES, WAS END OF LINE, THEN OK TO RETURN ;FALL THRU WHEN USER TYPED TOO MANY CHARACTERS PLINE PWLEN ;ERR MESSAGE PW.CLR: CLRRM PASSWORD+1 ;CLEAR 5 BYTES OF THE 6 BYTE BUFFER DCX H ;POINTER CAME OUT GOOD MVI M,0 ;CLR THE 6TH BYTE OF THE BUFFER RET ;THAT'S ALL .SBTTL *** "MK" & "UM" CMD *** ;CONSOLE COMMAND TO MARK AND UMARK SPECIFIED MICRO-CODE LOCATIONS UMCMD: MVI C,0 ;WE ARE CLEARING THE MARK BIT.. JMP MRKCM ;AND GO SAVE IT AS A FLAG FOR WHAT WE ARE DOING MKCMD: MVI C,1 ;A BIT SAYS WE ARE SETTING THE MARK BIT MRKCM: PUSH B ;SAVE "B,C", IT HAS DATA FOR SET OR CLEAR RUN.. ;IS CPU RUNNING?? CALL LCCMD ;"C-BIT" IS CLR..GO ASSEMBLE A LEGAL RAM-ADDRESS CALL CRM.AD ;SET DIAGNOSTIC ADDRESS REG CALL CP1 ;GIVE SINGLE PULSE TO GET DATA WHERE I CAN READ MVI A,^O17 ;GET FUNCTION READ FOR CRAM DATA THAT INCLUDES MRK CALL READC ;DO THE DIAGNOSTIC FUNCTION READ CALL CRM.AD ;SET DIAGNOSTIC ADDRESS REG LXI D,TMPB2 ;GET PNTR TO DATA THAT HAS THE MARK BIT POP B ;GET INSTR TYPE LDAX D ;GET THE ACTUAL DATA ANI ^O376 ;CLEAR BIT 0 ORA C ;NOW EITHER SET OR CLEAR THE BIT MRKRT: STAX D ;BUT DATA BACK, NEW MARK BIT STATUS CALL ADATP ;WRITE DATA TO BUS REG MVI A,7 ;NOW WISH TO DO FUNCTION WRITE 7 STA CRMFN ;SET INTO FUNC WORD JMP WFNC1 ;AND FINISH UP BY WRITING DATA BACK .SBTTL *** "ZM" CMD *** ;CONSOLE COMMAND TO ZERO THE SM10 MOS MEMORY.. ZMCMD: CLRRM MEMAD ;CLEAR MEMORY ADDRESS BUFFER(TO START AT 0) MVI A,2 ;BITS TO SAY WRITE TYPE FUNCTION STA MEMAD+4 ;WRITE INTO THE BUFFER CLRRM DMDAT ;DATA TO DEPOSIT IS ALL ZEROES INTON ;INTERNAL MODE ON CALL DM1 ;DEPOSIT ZEROES INTO FIRST LOCATION ZM1: CALL INC36 ;TO NEXT ADDRESS .ADDR MEMAD ;HERE IT IS LXI D,MEMAD ;DO PART OF THE DEPOSIT HERE, FOR SPEED SAKE CALL ADATP ;LOAD UP BUS REGS WITH THE DESIRED DATA MVI A,4 ;NOW FUNCTION TYPE BIT INTO ACCUM OUT BUSARB ;***** I/O WRT ***** CALL DMGO ;NOW GO DO THE DEPOSIT ;AND CHECK TO SEE IF GOT A NXM LDA ERRCD ;GET ERROR CODE.. ANA A ;CHECK IF SET JZ ZM1 ;IF NO ERRORS YET, KEEP GOING ;FALL THRU WHEN HAD "NO DATA ACNOWLEDGE" ERROR INTOFF ;CLEAR INTERNAL MODE ENDCMD ;AND DONE .SBTTL *** "RP" CMD *** ;NOTE: THE LIST OF SAVED COMMAND DISPATCHES IS NOT IN THE NORMAL 8080 ;ADDRESS FORMAT..IE THE COMMAND LIST IS SAVE IN PAIRS OF BYTES AS ;HI ORDER PIECE FIRST.. ;LO ORDER PIECE SECOND.. RPCMD: JNC RP1 ;IF ARG, BEGIN AT A SPECIAL PLACE XRA A ;CLR ACCUM RP0: STA RPCNTR ;THERE IS NO REPEAT COUNT CALL RPFOO ;IN THE BEGINNING YOU MUST RESET THE POINTERS XRA A ;CLR ACCUM STA RPEND ;CLR THE REPEAT KILLER CMA ;MAKE ACCUM .EQ. -1 STA RPTON ; THAT REPEAT FUNCTION IS TURNED ON JMP RP2 ;CONTINUE... RP1: CALL ARG16. ;FETCH THE ARG THAT WAS TYPED MOV A,H ;IT MUST ONLY BE 256 OR LESS ANA A ;SET PROCESSOR FLAGS JNZ KILNM ;IF .GT. 256, THEN BAD NUMBER ;FALL THRU IF ACCUM 0 MOV A,L ;GET REAL ARG INTO ACCUM INR A ;SET ACCUM 1 GREATER THAN ACTUAL JMP RP0 ;CONTINUE BY INITING FLAGS RPTRTN: LDA RPEND ;NEXT THING IS TO SEE IF TIME TO STOP REPEAT ANA A ;TEST DATA JNZ RP.OUT ;AND END THE REPEAT IF "END" FLAG IS SET RP2: LHLD RPLST ;GET POINTER TO COMMAND DISPATCH LIST MOV A,M ;CHECK BYTE..MAKE SURE ITS NOT THE END-OF-LIST INR A ;IF IT WAS -1, NOW ITS A ZERO JNZ RP4 ;AND GO BACK TOO LDA RPCNTR ;CHECK IF THIS IS A COUNTED REPEAT CZ RPFOO ;IT WAS END OF LIST IF U GOT HERE, SO FIX POINTERS ANA A ;SET FLAGS JZ RPTRTN ;IF .EQ. 0 NO COUNT ON THE REPEAT DCR A ;THERE IS A COUNTER, DOWN IT STA RPCNTR ;SAVE NEW COUNT CPI 1 ;SEE IF AT BOTTOM LINE CNZ RPFOO ;IF A COUNTED REPEAT, FIX END OF LIST ONLY IF MORE TO DO JNZ RPTRTN ;JUMP IF NO RP.OUT: XRA A ;CLEAR ACCUM PRIOR TO LEAVING STA RPTON ;TURN OFF THE "ON" FLAG RET ;AND HERE IF YES RP4: MOV D,M ;IF IT WAS OK.. START ASSEMBLING THE DISPATCH INX H ;UPDATE TO LO ORDER PIECE MOV E,M ;AND DISPATCH IS NOW IN "D,E" INX H ;UPDATE POINTER SHLD RPLST ;SAVE POINTER TO WHERE WE ARE IN CMD LIST LXI H,NULLW ;"H,L" GETS PLACE WE WANT TO RETURN TO PUSH H ;PLACE ON STACK SO THAT "RET" INS COMES HERE XCHG ;DISPATCH ADDRESS INTO "H,L" MOV A,H ;GET HI ORDER PIECE OF ADDR TO SEE IF ARG ANA A ; WAS TYPED WITH THIS COMMAND..SET FLAGS JP RPGO ;IF SIGN BIT CLR, CMD GOT NO ARG ;OTHERWISE MUST SET THE C-BIT TO TELL CMD TO LOOK FOR ARG ANI ^O177 ;CLR SIGN BIT MOV H,A ;PUT IT BACK FOR CORRECT DISPATH STC ;SET C-BIT IF NECCESSARY RPGO: CMC ;SET C-BIT FOR THIS COMMAND TO SEE PCHL ;AND GO DO IT.. ;IF REACHED END OF THE DISPATCH LIST, THEN THIS CODE RESETS ;THE POINTER BACK TO THE BEGINNING OF THE LIST RPNEW: CMA ;RPFOO DOESNT TOUCH ACCUM, SET ACCUM TO -1 STA CMDS.. ;NOW ZAP THE FIRST IN LINE FLAG RPFOO: LXI H,RPINI ;BUFFER BEGINNING ADDRESS SHLD RPLST ;PUT BACK INTO RAM LXI H,RPTBFI ;POINTER TO DATA BUFFER SHLD RPBUFS ;RESET INTO HOLDING LOCATION RET ;AND RETURN .SBTTL *** "DS" CMD *** ;COMMAND TO SELECT NON DEFAULT DISK UNIT AND UNIBUS ADAPTERS FOR BOOTING ;FROM DISK DSCMD: PLINE Q.UBA ;MESSAGE TO ASK FOR "UNIBUS ADAPTER" TO BE USED CALL PICKUP ;GO FETCH THE RESPONSE THAT WAS TYPED JC DS1 ;IF NOTHING TYPED, LEAVE UBA AS CURRENTLY SELECTED ;FALL INTO HERE IF A NEW UBA NUMBER WAS TYPED LDA TMPB2 ;GRAB THE NEW UBA NUMBER AS TYPED RLC ;THE UBA NUMBER IS JUSTIFIED "*4" IN A BYTE RLC ;TAKES 2 ROTATES TO GET IT JUSTIFIED STA DSKUBA ;AND SAVE THE NEW VALUE IN THE RAM DS1: PLINE Q.RH ;ASK FOR AN RH11 TO USE CALL PICKUP ;GET WHAT WAS TYPED JC DS2 ;IF NOTHING TYPED, DO NOTHING MOV5B ;NOW SAVE THIS NEW DISK BASE .ADDR TMPB2 ;THIS IS WHERE THE DATA SHOULD BE SITTING .ADDR DSBASE ;THIS IS WHERE WE WILL KEEP IT DS2: PLINE Q.UNIT ;ASK FOR A UNIT NUMBER TO BOOT FROM CALL PICKUP ;GO FETCH WHAT WAS TYPED RC ;IF NOTHING TYPED, THEN ALL DONE. RETURN FROM THIS CMD ;FALL TO HERE IF A UNIT WAS TYPED..GO SET THE UNIT TO BE USED LDA TMPB2 ;GET NUMBER TYPED FOR THE NEW UNIT STA UNITNM ;SET IT INTO RAM AS THE NEW VALUE RET ;ALL DONE THIS COMMAND.... .SBTTL *** "MS" CMD *** ;COMMAND TO SELECT WHAT MAGTAPE TO BOOT FROM MSCMD: PLINE Q.UBA ;ASK FOR A UNIBUS ADAPTER TO LOAD FROM CALL PICKUP ;GET WHAT WAS TYPED JC MS1 ;IF NOTHING, LEAVE UBA ALONE.. GO GET THE NEXT THING ;FALL INTO HERE IF A NEW UBA WAS SELECTED LDA TMPB2 ;GET THE NEW UBA TYPED RLC ;UBA NUMBERS MUST BE JUSTIFIED ON BYTE BOUNDARY *4 RLC ;TAKES TWO SHIFTS TO SET THE UBA NUMBER STA MTAUBA ;SAVE THE NEW UBA VALUE IN THE RAM MS1: PLINE Q.RH ;ASK FOR A NEW RH11 TO USE CALL PICKUP ;FETCH WHAT WAS TYPED JC MS1.5 ;IF NOTHING TYPED, THEN DO NOTHING MOV5B ;IF SOMETHING TYPED, GET IT FROM THE BUFFER .ADDR TMPB2 ;PLACE WHERE THE STUFF WAS PUT .ADDR MTBASE ;PLACE WHERE WE KEEP THE MAGTAPE BASE REG MS1.5: PLINE Q.TCU ;GO ASK FOR A UNIT NUMBER CALL PICKUP ;GO SEE WHAT WAS TYPED JC MS2 ;IF NOTHING TYPE, LEAVE VALUE ALONE.. GO AROUND THIS. ;FALL TO HERE IF NEED TO SET A NEW UNIT NUMBER LDA TMPB2 ;GET WHAT WAS TYPED STA TAPEUNIT ;SET IN THE NEW UNIT NUMBER MS2: PLINE Q.DEN ;NOW GO SEE WHAT DENSITY TO SET FOR THE MAGTAPE CALL INBUF ;UPDATE BUFFER POINTER. THIS CASE IS DIFFERENT THAN ;THE OTHERS.. WE NEED TO EXAMINE ASCII. NOT OCTAL JC MS3 ;BUT IF NOTHING TYPED, GO ASK FOR A NEW SLAVE ;FALL THRU IF NEED TO SET A DENSITY.... ;NOW H,L REG POINTS TO THE STRING JUST TYPED IN PUSH H ;SAVE POINTER TO THE TYPED IN BUFFER LXI D,EIGHT0 ;GET POINTER TO THE "800" LIST CALL STRCMP ;NOW DO A STRING COMPARE JNZ S16CHK ;IF WAS NOT AN "800", SEE IF ITS A "1600" ;OK, IT WAS 800..NOW SET UP THE CHANNEL DATA TO SAY 800 BPI TAPE MVI A,2 ;A 2 IS THE CORRECT CODE FOR 800 BPI POP H ;IF "800" MATCHED, THEN CLEAN UP THE STACK JMP MS2.5 ;GO TO NEXT CHECK S16CHK: POP H ;GET POINTER TO THE TYPED IN STUFF LXI D,SIXTN ;MATCH AGAINST "1600" CALL STRCMP ;DO THE STRING COMPARE JNZ KILNM ;IF WAS NOT 1600, THEN IT WAS BAD ;IT WAS 1600, SO SET THE RIGHT THING FOR TAPE BPI MVI A,4 ;THIS IS THE CODE FOR 1600 BPI MS2.5: STA DEN.SLV+1 ;SET THE BYTE IN THE CHANNEL DATA WORD MS3: PLINE Q.SLV ;ASK FOR A NEW SLAVE DEVICE CALL PICKUP ;FETCH WHAT WAS TYPED RC ;IF NOTHING TYPED, THEN WE ARE ALL DONE ;ELSE FALL TO HERE TO GET THE SLAVE LDA TMPB2 ;GET THE NUMBER STA DEN.SLV ;SET THE BYTE AS REQUIRED RET ;AND ALL DONE EIGHT0: .ASCIZ /800/ ;FOR 800 BPI TAPES SIXTN: .ASCIZ /1600/ ;STRING FOR 1600 BPI TAPES ;SOME SUBROUTINES FOR USE BY THE DEVICE SELECT COMMANDS ;FIRST A ROUTINE TO READ IN A NUMBER TYPED IN ANSWER TO AN 8080 QUESTION ;AND SAVE THE NUMBER TYPED IN THE 36 BIT BUFFER "TMPB2". RETURNS C-BIT CLEAR ;IF A NUBER WAS GATHERED AND STORED IN "TMPB2". RETURNS C-BIT SET IF NOTHING ;WAS TYPED. PICKUP: CALL INBUF ;SET UP THE INPUT BUFFER TO THE CURRENT TYPEIN. RC ;RETURNS HERE WITH C-BIT SET IF NOTHING TYPED ;GET HERE IF SOMETHING WAS TYPED.. GO GET IT AND PUT IT IN "TMPB2" ARG36 ;GATHER A 36-BIT ARGUMENT .ADDR TMPB2 ;PUT IT IN THIS BUFFER XRA A ;CLEAR C-BIT BECAUSE ALL WAS OK. RET ;ALL DONE ;SUBROUTINE TO FIX UP THE BUFFER POINTERS IN THE INPUT BUFFER INBUF: LXI H,EOL ;GET POINTER TO END-OF-LINE COUNTER DCR M ;SO CAN DECREMENT CALL BFRST ;RESET TTY INPUT POINTERS LHLD BUF. ;FIND THE BEGINNING OF BUFFER SHLD .ARG1 ;AND SET IT AS THE POINTER TO THE FIRST ARG LXI H,INRDY ;PASS A RETURN ADDRESS IN H,L JMP NULLW ;ENTER TTY INPUT WAIT INRDY: LHLD .ARG1 ;GET POINTER TO THE START OF THE NEW DATA FNDARG: CALL SEPCHR ;EAT UP ANY NO-OP SEPARATORS SHLD .ARG1 ;REPLACE THE POINTER JMP EOCML ;CHECK IF AT END-OF-LINE. C-SET IF YES(IE NO ARG) .SBTTL *** "BT" CMD *** INDIRECT=^O77 BOOT: PLINE BTMSG1 ;INCLUDE A MESSAGE SO THAT USERS KNOW U R BOOTING BTAUT: PCRLF ;AND KEEP IT ON ONE LINE MVI A,^O10 ;BIT 32 IN TENLAND TO SAY THIS WAS A BOOT BUTTON LOAD STA GOCODE ;SAVE IN THE "GO CODE" PLACE STC ;FALL THRU TO A "BT" BTCMD: CALL BTCHOICE ;GO SELECT MONITOR OR DIAG PRE-BOOT BT.SRC: CALL MICROP ;READ THE PAGE OF FILE POINTERS INTO MEMORY @1000 ;WHEN GET TO HERE, THE PAGE HAS BEEN READ IN. JC C.BTERR ;ERROR IN BOOT PROCESS DURING MICRO-CODE LOAD CALL DMEM2CRAM ;LOAD DATA FROM MEMORY INTO CRAM ;FALL THRU IF DONE THE CRAM LOADING PORTION ;NOW MUST READ IN THE BOOT CODE ITSELF,START THE SM10 MICRO-CODE ;AND THEN START THE BOOT PROGRAM AT ADDRESS 1000 ;NOW SET UP DISK POINTERS TO POINT TO BOOT BLOCK OF DISK, ;IN ORDER THAT WE LOAD THE MONITOR BOOT LB.GO: CALL LBINT ;GO READ-IN THE APPROPRIATE BOOTSTRAP LB.GO1: MOV5B ;SET UP A START ADDRESS .ADDR MA1000 ;MEMORY ADDRESS 1000 FOR STARTING PROGRAM .ADDR TMPBF2 ;SET UP SO START COMMAND CAN FIND THE ADDRESS ;TEMP CODE FOR FIGURING OUT HOW TO MAKE THE INTERNAL START CODE WORK JMP STINT ;GO START THE MACHINE WITH MONITOR BOOT .SBTTL *** "LB" CMD *** LBCMD: CALL BTCHOICE ;IF ARG GIVEN, GO SET UP A CHOICE FOR THE BOOTING LBINT: LXI D,^O1000 ;ALL POINTERS START AT 1000 LDA RM100 ;GET THE OFFSET AS SELECTED(MON OR DIAG PRE-BOOT) ADD E ;ADD LO ORDER TO THE OFFSET MOV E,A ;PUT IT BACK CALL FILEINIT ;READ IN POINTERS TO THE "PRE-BOOTS" JC L.BTERR ;ERROR IN LOADING THE PRE-BOOT CALL BT.GO ;START UP THE MICRO-CODE & INTERNAL OFF ;NOW PASS ADDRESSES OF RH BASE & DRIVE # TO THE PRE-BOOT PROGRAMS INFOBT: LHLD UNITNM ;UNIT NUMBER INTO HL REGISTER JMP PASSSRC ;ROUTINE WHICH WRITES LOCS 36,37 & 40 ;CUTE LITTLE ROUTINE FOR SELECTING WHICH BOOT TO LOAD BTCHOICE: JC LOAD4 ;IF NO ARG, SET FOR "BOOT>" INPUT CALL ARG16. ;ASSEMBLE THE ARG ;AS LONG AS IT WAS A NUMBER, WE WILL LOAD THE DIAG BOOT MVI A,6 ;A 6 IS THE OFFSET FOR THE DIAG PRE-BOOT EXIT4: STA RM100 ;SAVE IT RET LOAD4: MVI A,4 ;PASS A 4.. TO SAY LOAD MONITOR BOOT JMP EXIT4 ;AND COMMON EXIT ;ROUTINE TO START UP THE MACHINE(KS10), AND RE-ESTABLISH THE PARITY DEFAULT BT.GO: CALL SM1 ;START THE MICRO-CODE JC D.BTERR ;IF MICRO-CODE DOES NOT START BT.GO1: INTOFF ;INTERNAL MODE OFF MVI A,DEFLTE ;GET MACHINE DEFAULT VALUE FOR ENABLES CALL KS.PAR ;SET THEM INTO THE RAM & WRITE INTO KS MVI A,TRPDEF ;GET MACHINE DEFAULT FOR TRAP ENABLES TP.SET: STA TRAPEN ;SET DEFAULT INTO THE RAM OUT DIAG ;***** I/O WRT 205/TRAPS ENABLE ***** RET ;AND OUT .SBTTL *** "MT" CMD *** MTCMD: SHLD CMD.. ;SAVE WHAT COMMAND THIS IS, SO RETRYS WILL WORK CALL MTSETUP ;GO TO SOME COMMON CODE MVI A,READ.TAPE ;GET THE COMMAND EXECUTION CODE FOR THE TAPE CMD CALL MTXFR ;AND READ-IN THE MICRO-CODE FROM TAPE JNC MT.1 ;NO NEED TO CHECK IF FATAL ERR IF ALL OK CALL NONFATAL ;WAS AN ERROR, GO SEE WHAT KIND JNZ A.BTERR ;ERR TYPE "A" IF INITIAL READ FAILS MT.1: MVI A,MT.BIT ;SET ACCUM .EQ. MAGTAPE BIT CALL MEM2CRAM ;LOAD MICRO-CODE FROM MEMORY TO "CRAM" SPACE CALL MBINT ;NOW LOAD IN THE PRE-BOOT PROGRAM CALL BT.GO ;START THE MICRO-CODE,REPLACE PARITY & TRAP DEFAULTS JMP LB.GO1 ;AND PROCEED TO START THINGS ;NOW MUST DO A RE-WIND.. SKIP FIRST FILE(MICRO-CODE), THEN READ-IN THE ;SECOND FILE(THE PRE-BOOT) MBINT: MVI A,SKP.TAPE ;GRAB A SKIP COMMAND CALL MTXFR ;ISSUE A REWIND. AND A FILE-SKIP ;NOW WE EXPECT THERE TO BE A FRAME COUNT ERROR FROM THE SPACE FORWARD ;AND WE WILL DO WHAT WE CAN TO IGNORE IT JNC MTSKOK ;IF NO ERROR AT ALL, THATS OK TOO CALL NONFATAL ;CHECK ERROR TYPE IF FALL INTO HERE JNZ L.BTERR ;IF WAS NOT A FRAME COUNT ERROR, IT WAS MORE SERIOUS ;IF COMPARE RESULT WAS ZERO, THEN THE ERROR WAS A FRAME COUNT ERROR ;AND WE WILL IGNORE IT BY FALLING INTO THE CONTINUE CODE MTSKOK: MVI A,READ.TAPE ;GET A TAPE READ COMMAND CALL QMXFR ;EXECUTE TAP COMMAND LIST WITH NO REWIND IN IT JNC PASSME ;NO ERROR IF NO "C" BIT CALL NONFATAL ;SEE WHAT KIND OF ERROR JNZ L.BTERR ;BOOT ERROR IF NO Z PASSME: LHLD TAPEUNIT ;GET TAPE UNIT FOR CURRENT MAGTAPE SELECTION ;NOW PASS INFO IN LO MEMORY ADDRESS SPOTS PASSSRC: PUSH H ;SAVE THE PASSED UNIT NUMBER ON TOP OF STACK MOV5B ;PASS RH BASE ADDRESS TO INTERNAL BUFFER .ADDR RHBASE ;FROM HERE .ADDR DMDAT ;TO HERE LXI H,DMDAT+2 ;GET POINTER TO PIECE FOR UBA LDA UBANUM ;GET CURRENT UBA ORA M ;PUT IT INTO MEMORY MOV M,A PUSH H ;SAVE THE POINTER TO "DMDAT" AREA DEPOS 36 ;DEPOSIT IN MEMORY POP H ;GET BACK THE POINTER TO "DMDAT" AREA MVI M,0 ;CLEAR BYTE WITH BITS 12-19 POP H ;GET THE UNIT NUMBER THAT WAS SAVED ON THE STACK SHLD DMDAT ;AND PUT IT INTO THE DEPOSIT MEMORY DATA AREA DEPOS 37 ;DEPOSIT IN MEMORY HERE MOV5B ;FINALLY PASS DENSITY SLAVE INFORMATION .ADDR DEN.SLV ;GET IT FROM HERE .ADDR DMDAT ;PUT IT HERE DEPOS 40 ;AND MOS MEMORY HERE RET ;BACK TO CALLER ;ROUTINE THAT CHECKS TO SEE WHAT KIND OF ERROR WE HAVE SUFFERED UNDER ;THE MAGTAPE TRANSFER NONFAT: MVI A,<^O377&FRMERR+2> ;CHK ERROR CODE FOR FATAL OR NON FATAL TYPES LXI H,ERRCD ;NOW POINT TO THE ACTUAL ERROR TYPE THAT WE GOT CMP M ;COMPARE THE TWO PUSH PSW ;SAVE FLAGS WHILE WE RESET THE TAPE DRIVE CZ MTRESET ;GO RESET ANY ERRORS ENCOUNTERED IN THE SKIP OPERATION POP PSW ;GET BACK THE FLAGS RZ ;ONLY RETURN IF ERROR WAS NON FATAL ;FALL TO HERE IF ERR WAS FATAL TYPE..SEE IF WE CAN RETRY IT MVI A,<^O377&RETRY.+2> ;"RETRYABLE" ERROR?? CMP M ;COMPARE RNZ ;OUT IF CAN'T EVEN RETRY..DIE ;AND HERE IF IT WAS RETRYABLE LXI SP,RAMST+^O2000 ;FIRST CLEAR THE STACK LXI H,NORML ;PUT A RETURN ADDRESS ONTO THE STACK PUSH H LHLD CMD.. ;NOW GET "WHICH" COMMAND TO RETRY PCHL ;GIVE IT A GO .SBTTL *** "MB" CMD *** ;COMMAND TO LOAD ONLY THE BOOTSTRAP OFF OF THE CURRENTLY SELECTED MAGTAPE MBCMD: SHLD CMD.. ;SAVE WHICH COMMAND THIS IS CALL MTSETUP ;GO TO SOME COMMON CODE TO SET UP FOR MAGTAPE XFER CALL MBINT ;AND GO CALL BT.GO ;START UP THE MICRO-CODE & INTERNAL OFF RET ;BACK TO NULL JOB LOOP ;SOME COMMON CODE THAT SETS UP PARAMETERS FOR MAGTAPE XFER'S..SAVES A FEW ;BYTES OF 8080 SPACE MTSETUP: CALL BTINT ;FIRST SET UP FOR THE BOOTING PROCESS LDA MTAUBA ;GET SELECTED UBA FOR MAGTAPE STA UBANUM ;PASS TO COMMON SPOT FOR CHANNEL COMMAND LIST TO FIND MOV5B ;AND MOVE THE SELECTED MT BASE FOR RH BASE TO FIND .ADDR MTBASE ;SELECTED MAGTAPE RH BASE ADDRESS .ADDR RHBASE ;COMMON RH BASE REGISTER LOCATION RET ;BACK TO MAILINE MA1000: D 0,0,,1,000 HOMEWD: D 505,755,,000,000 ;"HOM" MEANS HOME BLOCK ONES: D 777,777,,777,777 ;ALL ONES... .SBTTL FILE SYSTEM ;--PAGE OF POINTERS FORMAT-- ; +0 POINTER TO FREE ; +1 LENGTH OF FREE ; +2 POINTER TO MICRO-CODE ; +3 LENGTH OF MICRO-CODE ; +4 POINTER TO MONITOR PRE-BOOT ; +5 LENGTH OF PRE-BOOT ; +6 POINTER TO DIAG PRE-BOOT ; +7 LENGTH OF SAME ; +10 POINTER TO BC1 MICRO-CODE ; +11 LENGTH OF SAME ; +12 POINTER TO BC2 PRE-BOOT ; +13 LENGTH ; +14 POINTER TO MONITOR BOOT PROGRAM ; +15 LENGTH OF SAME ; +16 POINTER TO DIAGNOSTIC BOOT ; +17 LENGTH OF SAME ; +20 POINTER TO BC2 ITSELF ; +21 LENGTH OF SAME ; +22 POINTER TO FI-ABLE 0 ; +23 LENGTH OF SAME ; . ; . ; . ; +776 POINTER TO FI-ABLE 366(8) ; +777 LENGTH OF SAME ;ROUTINE TO "FIND THE 8080 FILE SYSTEM", WHICH IS REALLY JUST A PAGE ;OF PHYSICAL POINTERS, TO PHYSICAL DISK LOCATIONS MICROP: LXI D,^O1002 ;FOR MICROCODE, ALWAYS GO TO 2ND POINTER FILEINIT: PUSH D ;SAVE POINTER INTO THE FILE PAGE CALL BTINT ;AND SET UP TO DO A READIN POP D ;RESTORE "D,E"..KLUDGY WAY TO MAKE SUBROUTINE HAVE FILESH: PUSH D ; MULTIPLE ENTRY POINTS CALL DSKDFT ;FETCH CURRENT DISK DEFAULTS LXI H,00 ;CLR "H,L" SHLD BLKADR ;AND SET THE DESIRED CYLINDER TO 00 INX H ;BUMP H,L TO MAKE IT .EQ. 01 SHLD BLKNUM ;NOW SET THIS INTO THE BLOCK NUMBER(HOME BLOCK) CALL CHKHOM ;GO SEE IF THIS PAGE HAS THE "HOM" BLK I.D. JZ GOODPK ;IF YES, JUMP TO CONTINUE READ-IN ;FALL THRU IF FIRST HOME BLOCK NO GOOD MVI A,^O10 ;TRY ALTERNATE HOME BLOCK STA BLKNUM ;SET BLOCK NUMBER TO ALTERNATE CALL CHKHOM ;TRY ALTERNATE JNZ A.BTERR ;IF THIS ONES BAD, THEN GIVE UP GOODPK: EXAM 1103 ;EXAMINE WORD WITH HOME BLOCK IN IT ;NOW THAT YOUVE READ HOME BLOCK, FIND POINTER FILE ;AND TRANSFER THE ENTIRE MICRO-CODE INTO MOS MEMORY ;SHORT ROUTINE TO MOVE DATA FROM THE EMBUF INTO THE CHANNEL COMMAND LIST CALL BLKRDR ;READ IN THE PAGE OF POINTERS FROM THE DISK JC B.BTERR ;ERROR IN BOOT PROCESS DURING POINTER PAGE READ-IN ;NOW EXAM THE REAL DESIRED DATA POP H ;FETCH UP THE FILE POINTER ADDRESS STC ;SET SIGN WHICH INDICATES AND EXAMINE CALL EXMHL ;AND READ IT IN TO MEM ;SHORT ROUTINE TO MOVE DATA FROM THE EMBUF INTO THE CHANNEL COMMAND LIST BLKRDR: LHLD EMBUF+3 ;GET CYLINDER FROM SPECIAL HOME BLK PNTR SHLD BLKADR ;SET CYLINDER IN CHANNEL COMMAND LIST LHLD EMBUF ;GET TRACK SECTOR BYTE SHLD BLKNUM ;SET INFO INTO THE TRCK/SECTOR WORD CALL DSXFR ;FINALLY READ THE FIRST PAGE OF THE DESIRED RET ;LITTLE ROUTINE TO READ IN THE HOME BLOCK, CHECK THAT IT IS A HOME BLOCK ; VIA THE "HOM" ID, AND RETURN Z-BIT SET IF IT IS CHKHOM: CALL DSXFR ;EXECUTE DISK TRANSFER JC A.BTERR ;BOOT ERROR "A", IF OOPS EXAM 1000 ;NOW EXAMINE THE HOME BLOCK ID CALL CMP36 ;AND TRY OUT A COMPARE .ADDR HOMEWD ;EXPECTED ID .ADDR EMBUF ;AGAINST WHAT WAS JUST READ IN RET ;AND OUT BTINT: INTON ;SET INTERNAL MODE ON CLRB PARBT ;NO PARITYS CLRB TRAPEN ;AND NO TRAPS WHILE BOOTING CALL MRCMD ;AND DONT FORGET MR. RESET RET ;LITTLE ROUTINE TO SET UP DISK DEFAULTS DSKDFT: LDA DSKUBA ;GET CURRENTLY SELECTED DISK UBA NUMBER STA UBANUM ;SET INTO COMMAND LIST PLACE MOV5B ;AND SEND CURRENTLY SELECTED RHBASE .ADDR DSBASE ;CURRENT DISK RH BASE .ADDR RHBASE ;TO PLACE FOR COMMAND LIST TO FIND IT RET ;OUT .SBTTL CRAM LOADER CODE DMEM2CR: MVI A,BT.BIT ;DO COUPLE ROUTINES A FAVOR, LOAD BIT MEM2CR: STA BT.TYPE ;ACCUM HAD THE BOOTING TYPE..SAVE IT LXI H,00 ;ZEROES TO "H,L" PUSH H ;SAVE CURRENT CRAM ADDRESS CALL CADWR ;AND THEN WRITE IT TO THE CRAM MVI A,7 ;START WITH FUNCTION 7 STA CRMFN NEWPAG: MOV5B ;INITIALIZE MEM ADDRESS .ADDR MA1000 ;WITH 1000 OCTAL .ADDR MEMAD ;STANDARD MEM ADDRESS ;CODE TO DECIDE IF WE NEED TO READ AN ADDITIONAL DISK SECTOR LHLD MEMAD ;GET CURRENT MOS MEM ADDRESS RD.EXM: MOV A,L ;GET 8 BITS OF ADDRESS TO BE EXAMINED OUT A2835 ;SET PIECE OF ADDRESS INTO ADDRESS REGISTER MOV A,H ;GET COUPLE MORE BITS OUT A2027 ;SET INTO CSL BOARD ADDRESS REGISTER MVI A,4 ;SPECIAL KEY TO MAKE "EXAMINE" WORK CORRECTLY CALL EM.CRM ;GO DO A MEMORY EXAMINE, OF THE SHORT FLAVOR LHLD EMBUF ;GET 16 BITS OF THE MEMORY DATA MOV A,H ;COPY TO ACCUM, SO THAT WE CAN MAKE IT 12 BITS ANI ^O17 ;CLR THE BITS MOV H,A ;PUT BACK INTO THE HI ORDER REG CALL WFUNC ;WRITE THE PIECE LXI H,CRMFN ;GET CURRENT DIAG FUNCTION DCR M ;DOWN COUNT LHLD EMBUF+1 ;GET 16 BITS OF THE MEMORY READ MVI C,4 ;NOW A QUICK LITTLE LOOP XRA A ;CLR ACCUM TEMP QQLOOP: MOV A,H ;COPY TO ACCUM RAR ;ROTATE INTO THE C-BIT MOV H,A ;PUT IT BACK MOV A,L ;TRY BOTTOM PIECE RAR ;ROTATE C-BIT INTO THE TOP MOV L,A ;PUT IT BACK DCR C ;DOWN THE LITTLE COUNTER JNZ QQLOOP ;CONTINUE CALL WFUNC ;WRITE THIS PIECE LXI H,CRMFN ;DOWN THE FUNCTION COUNTER DCR M ;DECREMENT JP BBLOOP ;JUMP AROUND THIS STUFF IF NOT AT FUNCTION 0 ;IF DONE FUNCTIONS 0-7, TRY A LITTLE RESET MVI A,7 ;RESTART AT FUNCTION 7 STA CRMFN ;SAVE IT ;HERE IF FINSHED A CRAM WORD & NEED TO DO RESET. POP H ;GET CRAM ADDRESS INX H ;UPDATE PUSH H CALL CADWR ;NOW WRITE THIS, THE NEXT CRAM ADDRESS MOV A,H ;NOW GET HI ORDER PIECE OF CRAM ADDR ANI ^O10 ;IS IT .EQ. 4000 OCTAL YET?? JZ SEEPAGE ;IF NOT 4000 OCTAL YET, CHECK FOR A NXT WORD POP H ;AND RESTORE STACK BEFORE LEAVING RET ;OTHERWISE ALL DONE BBLOOP: LHLD EMBUF+3 ;GRAB 16 BITS OF THE MEMORY DATA MOV A,H ;PASS 8 BITS TO THE ACCUM, SO WE CAN MAKE IT 4 BITS ANI ^O17 ;OFF UNNEEDED BITS MOV H,A ;PUT IT BACK CALL WFUNC ;WRITE THIS DATUM LXI H,CRMFN ;GET FUNCTION DCR M ;DOWN TO NEXT FUNCTION SEEPAGE: LHLD MEMAD ;GET THE CURRENT MEMORY ADDRESS INX H ;GO TO NEXT ADDRESS SHLD MEMAD ;SAVE THIS NEXT ADDRESS MOV A,H ;TEST H FOR AT "2000" ANI ^O4 ;IF "2000" WEIGHT BIT IS SET, TIME FOR NEW PAGE OF DATA JZ RD.EXM ;IF MEM ADDRESS .EQ. 2000, THEN FALL THRU TO NEXT READIN CALL NEXTCR ;ROUTINE TO FETCH NEXT PAGE OF CRAM DATA JMP NEWPAG ;AND BACK TO BEGINNING ;ELSE, MUST READ IN ANOTHER PAGE'S WORTH FROM CURRENT BOOT DEVICE NEXTCR: LDA BT.TYPE ;FIND OUT WHAT KIND OF DEVICE WE ARE BOOTING FROM CPI BT.BIT ;SEE IF DOING BOOT FROM THE DISK JNZ TAPDEV ;IF FLAG .NE. BT.BIT, THEN BOOTING FROM MAGTAPE ;FALL THRU TO DO BOOT FROM DISK LXI H,QXFR ;SET UP FOR THE QUICK XFR COMMAND LIST CALL CHNXCT ;READ IN, SHORT FORMAT(TRK/SEC/CYL IS PRESET) JC C.BTERR ;ERROR IN READING CRAM RET ;BACK TO CALLER ;JUMP TO HERE TO DO BOOT FROM TAPE TAPDEV: MVI A,READ.TYPE ;PASS TO CHANNEL CMD LIST EXECUTOR THE XFR TYPE CALL QMXFR ;READ IN A SINGLE PAGE FROM MAGTAPE RNC ;IF NOTHING BAD, RETURN CALL NONFATAL ;IF BADNESS, SEE IF FATAL KIND OR NOT JNZ C.BTERR ;ERROR IN READING THE CRAM RET ;BACK TO CALLER .SBTTL *** "FI" CMD *** ;COMMAND TO READ IN A PARTICULAR PAGE OF THE FILESYSTEM AND TO EXECUTE ITS ;CONTENTS AS IF THEY WERE TYPED IN 8080 COMMANDS FICMD: CALL ARG16. ;COLLECT IT WHEN ITS THERE ;BEWARE..IF YOU TYPE FI WITH A BOGUS ARGUMENT, THEN YOU LOSE.. ;HE WHO USES THE FI CMD BEST KNOW WHAT HE'S DOING LXI D,^O1022 ;START WITH OFFSET "0" INTO THE "FI" FILES DAD D ;ADD THIS TO THE NUMBER TYPED TO GET THE DESIRED CALL FILEINIT ;READ IN THE DESIRED PAGE JC L.BTERR ;IF ERR ;NOW DO SOMETHING WITH THE STUFF TYPED... MOV5B ;FIRST MUST GET INFO FROM MOS MEM TO 8080 RAM .ADDR MA1000 ;INFO STARTS AT MOS MEME LOC 1000 .ADDR MEMAD ;AND WE WILL TELL INTERNAL READER TO START THERE LXI D,E.BEG+2 ;A PLACE TO STORE ASCII BYTES FROM MEMORY FI.GET: INTON ;NO PRINTING CALL GATHER ;GO READ IN A WORD FROM MOS MEM INTOFF ;OK TO PRINT NOW MVI L,4 ;NOW ONLY 4 BYTES PER WORD ARE USEFUL LXI B,EMBUF ;AND THIS IS WHERE IN 8080 RAM THE BYTES ARE FI.MOV: LDAX B ;FETCH UP A BYTE STAX D ;PUT IT IN PLACE CPI ^O377 ;IS IT END OF STRING?? JNZ FI.NXT ;IF NO, GO MOVE SOME MORE CALL MV.ALL ;GOT HERE, MOVE TO EXECUTE BUFFER JMP DCODE ;AND GO DO IT ;NOPE.. MOVE SOME MORE FI.NXT: INX B ;UPDATE THE POINTERS INX D DCR L ;CHECK COUNT TO SEE IF WE'VE DONE 4 YET JNZ FI.MOV ;IF NOT, GO MOVE THE NEXT BYTE FROM THE CURRENT WORD JMP FI.GET ;YES, READ NEXT MEM WORD AND TRY IT ;;**********PROPOSED INSTRUCTION ******************** ;;.SBTTL *** "B1" CMD *** ;;COMMAND TO READ IN A SECOND TYPE OF MICRO-CODE AND EXECUTE IT.. ;;I.E. BOOTCHECK 1 MICRO-CODE ;;B1CMD: LXI D,^O1010 ;GET THE CORRECT OFFSET ;; CALL FILEINIT ;READ IN THE FIRST PAGE ;; JC C.BTERR ;IF ERR ;; ;; MVI A,BT.BIT ;SAY THAT THIS IS A LOAD FROM DISK ;; CALL MEM2CRAM ;READ IT IN AS MICRO-CODE ;; CALL BT.GO ;START IT UP ;; RET ;THAT IT .SBTTL *** "B2" CMD *** ;BOOTCHECK 2.. THIS LOADS IN A SEPARATE "PRE-BOOT", WHICH ;LOADS IN THE BOOT CHECK 2 B2CMD: MVI A,^O12 ;GET THE OFFSET STA RM100 ;SAVE IT SO THAT WE CAN USE SOME SUPER COMMON CODE JMP BT.SRC ;THAT'S IT!!!! .SBTTL *** "VD" CMD *** ;COMMAND TO VERIFY THE CONTENTS OF THE C-RAM AGAINST THE MICRO-CODE ;AS IT SITS ON DISK VDCMD: CALL MICROP ;NOW READ IN HOME BLOCKS, THEN 1ST PAGE OF U-CODE JC C.BTERR ;IF ERROR, GO TELL WORLD ABOUT IT MVI A,BT.BIT ;WENT OK.. SPECIFY A DISK TYPE OPERATION JMP VERCRAM ;AND GO IN TO VERIFY THE CRAM .SBTTL *** "VT" CMD *** ;COMMAND TO VERIFY THE CONTENTS OF THE C-RAM AGAINST THE MICR-CODE ;AS IT SITS ON MAG TAPE VTCMD: CALL MTSETUP ;GO TO SOME COMMON CODE TO LOOK AT MAGTAPES MVI A,READ.TAPE ;TELL CHANNEL LISTER TO DO A READ IN CALL MTXFR ;READ IN FIRST PAGE OF U-CODE OFF THE TAPE JC A.BTERR ;IF ERROR, GO REPORT IT MVI A,MT.BIT ;WENT OK.. SPECIFY A TAPE OPERATION ;FALL STRAIGHT INTO THE CODE TO VERIFY THE CRAM .SBTTL VERIFY CRAM CODE ;ROUTINES THAT DO READ INS FROM THE CURRENTLY SELECTED DEVICE ;AND COMPARES THAT HARD MICRO-CODE DATA AGAINST THE CURRENT ;CONTENTS OF THE CONTROL-STORE VERCRAM: STA BT.TYPE ;BEGIN BY SAVING THE DEVICE AGAINST WHICH WE WILL VERIFY MOV5B ;START BY SETTING MEMORY ADDRESS AT 1000 .ADDR MA1000 ;A "1000" .ADDR MEMAD ;PLACE WHERE MEM ADDRESS IS KEPT LXI H,00 ;BEGIN WITH CRAM ADDRESS 00 SHLD CRMAD ;SET CRAM ADDRESS TO ZEROES JMP V.GO ;ENTER LOOP AT THE PROPER PLACE V.DONWD: LHLD CRMAD ;GET CURRENT CRAM ADDRESS INX H ;AND UPDATE FOR NEXT TIME AROUND MOV A,H ;PUT HI ORDER PIECE OF IT INTO ACCUM ANI ^O10 ;SEE IF AT END OF CRAM YET RNZ ;IF IT IS, ALL DONE, GO OUT ;HERE IF REALLY READY TO DO A CRAM LOC V.GO: CALL CADWR ;WRITE IT TO CRAM, BE IT GOOD OR BAD SHLD CRMAD ;NOW SAVE ADDRESS WHILE WE DO SOME STUFF CALL CP1 ;SINGLE CLOCK GETS CRAM CONTENTS TO CONTROL REG CALL RCINT ;READ IN CONTENTS OF C-RAM AND SAVE IN 8080 RAM ;HERE WHEN CRAM DATA IS SAFELY TUCKED AWAY IN THE 8080 RAM LXI B,VERLST ;B,C PAIR POINTS TO LIST OF DATA OFFSETS LXI D,CRMBF ;D,E PAIR POINTS TO ACTUAL DATA LIST(H,L PNTS EXPECTED) V.NXMEM: CALL GATHER ;HERE TO CALL ROUTINE THAT READS IN THE NEXT MEM WORD MVI A,3 ;AND TAKE TIME OUT TO RESET THE 3 COUNTER STA VERCNT ;SET UP A CLEAN COUNT ;AND HERE BELOW BEGINS THE ACTUAL DATA COMPARES V.BLP: LDAX B ;GET THE FIRST INDEX BYTE FROM THE LIST OF BYTES ANI ^O77 ;OFF THE SIGNALS, AND CONTINUE V.BLP1: LHLD EMBUF ;GET EXPECTED DATA INTO H,L REGISTER INX B ;UPDATE B,C TO POINT AT FUNCTION READ ADD E ;ADD AS AN OFFSET TO THE D,E PAIR MOV E,A ;PUT THE GOOD ADDR BACK INTO "E" MOV A,D ;AND GRAB THE HI ORDER FOR A SEC ACI 0 ;ADD IN THE CARRY IF REQUIRED MOV D,A ;PUT THE HI ORDER BACK AGAIN LDAX D ;NOW LOAD IN THE FIRST "ACTUAL" DATUM INX D ;UPDATE POINTER TO ACTUAL CMP L ;COMPARE AGAINST EXPECTED JNZ V.ERR ;REPORT IF BADNESS MOV A,H ;GET UPPER 12 BITS OF THE EXPECTED ANI ^O17 ;IF DATA WAS EQUAL, ONLY DISCREPENCY CAN BE IN B7-B4 MOV H,A ;GET THE 4 BITS OF DATA LEFT AFTER THE "AND" LDAX D ;GET THE ACTUAL DATA TO ACCUM CMP H ;SEE IF SAME V.ERR: CNZ VERRPT ; AND B3-B0 SHOULD BE .EQ. 0.. IF NOT REPORT AS ERROR DCX D ;FIX D TO LOOK AT THE BEGINNG OF THE "ACTUAL" 2 BYTES ;NOW NEED TO CHOOSE IF NEED CHECK TWICE(FOR DOUBLE COPIES), OR IF END ;OF LIST FOR THIS CRAM WORD INX B ;UPDATE POINTER INTO THE INDEXER LIST LDAX B ;GET THE NEXT INDEX BYTE RAL ;COPY SIGN INTO C-BIT JC V.DONWD ;IF SET, END OF LIST.. GO DO NEXT CRAM WORD RAL ;WASN'T END OF LIST.. SEE IF A DOUBLE CHECKER JC V.BLP ;JUMP BACK TO MAIN LOOP WITHOUT UPDATING IF YES ;IF NOT A DOUBLE, MUST FALL THROUGH TO UPDATE EXPECTED ;HERE WHEN MUST UPDATE EXPECTED..NOT A DOUBLE COPY V.NXT: LXI H,VERCNT;LOAD CURRENT COUNT FOR HOW MANY COMPARE PER MEM WORD DCR M ;DECREMENT THAT COUNT JZ V.NXMEM ;IF DOWN TO ZERO, GO READ IN THE NEXT MEMORY WORD LXI H,EMBUF ;TELL SHR36 WHERE IT SHOULD SHIFT CALL SHR36 ;IF NOT DOWN, SHIFT WHAT WE HAVE TO THE NEXT 12 BIT GRP .BYTE 12. ;SPECIFY THE NEXT 12 BIT GROUP IS WHAT WE WANT JMP V.BLP ;AND CONTINUE IN THE BIG LOOP ;LIST OF INDEXER BYTES .RADIX 8 VERLST: .BYTE 0,17 ;READ FCN 17 (BITS 84-95) .BYTE 2,16 ;READ FCN 16 (BITS 72-83) .BYTE 2,15 ;READ FCN 15 (BITS 60-71) .BYTE 2,14 ;READ FCN 14 (BITS 48-59) .BYTE 2,13 ;READ FCN 13 (BITS 36-47) .BYTE 102,12 ;READ FCN 12 (BITS 36-47) SECOND COPY .BYTE 10,6 ;READ FCN 6 (BITS 24-35) .BYTE 102,5 ;READ FCN 5 (BITS 24-35) SECOND COPY .BYTE 2,4 ;READ FCN 4 (BITS 12-23) .BYTE 10,0 ;READ FCN 0 (BITS 00-11) .BYTE 200 ;END OF LIST MARKER .RADIX 10 ;SUBROUTINE TO READ IN THE NEXT WORD FROM MEMORY. ;ALSO CHECKS TO SEE IF AT THE END OF THE MEMORY PAGE(ADDR 1777), AND IF SO ;TO GO AND READ IN THE NEXT PAGE OF MICRO-CODE FROM THE DEVICE AGAINST ;WHICH WE ARE VERIFYING THE MICRO-CODE. GATHER: PUSH D PUSH B LHLD MEMAD ;GET CURRENT MEMORY ADDRESS PUSH H ;SAVE CURRENT MEM ADDRESS MOV A,H ;GET THE HI ORDER PIECE OF THE MEM ADDRESS ANI ^O4 ;SEE IF ADDRESS AT "2000" YET JZ G.SKP ;IF NOT, SIMPLY GO READ IN THE NEXT WORD ;ELSE MUST READ IN THE NEXT PAGE OF MICRO-CODE CALL NEXTCR ;DO THE READ IN POP H ;GET OLD CRUMMY H,L OFF THE STACK LXI H,^O1000 ;WANT TO RESET MEM ADDRESS TO BEGINNING OF PAGE PUSH H ;PUT BACK ON STACK SHLD MEMAD ;AND PASS NEW ADDRESS IN RAM G.SKP: CALL EM2 ;EXAMINE THE NEXT MEMORY WORD POP H ;GRAB THE ADDRESS WE WANT TO READ NEXT TIME INX H ;UPDATE TO NEXT SHLD MEMAD ;PUT IT BACK POP B ;RESTORE THE REGS NOW POP D RET ;AND OUT ;VERIFY ERROR REPORTER SUBROUTINE. REPORTS VERIFY ERRORS AS THEY HAPPEN ;AND THEN PERMITS THE VERIFIER TO CONTINUE VERIFYING THE REST OF THE CRAM VERRPT: PUSH H ;SAVE CONTENTS OF H,L PAIR PUSH D ;MUST ALSO SAVE D,E INTOFF ;PRINT ALL THIS GOOD STUFF LXI H,CRMAD ;THEN PRINT THE CRAM ADDRESS OF THE FAILING CRAM WORD CALL P16 ;AND PRINT OUT THE ADDRESS PSLASH ;THROW OUT A "/" LDAX B ;FETCH UP THE DIAG FUNC OF THE READ FAILURE CALL P8BITA ;AND PRINT IT PCHAR ': ;SIMPLE CHARACTERS ARE ": A " PSPACE PCHAR 'A PSPACE XCHG ; AND NOW H,L POINTS AT THE ACTUAL DCX H ;NOW D,E POINTS TO THE ACTUAL CALL P16 ;PRINT THE ACTUAL DATA XCHG ;FIX SO H,L POINTS AT TEMP LOC ONCE AGAIN PSPACE ;ANOTHER SPACE PCHAR 'E ;A "W" STANDS FOR "WAS" PSPACE LHLD EMBUF ;GET THE EXPECTED DATA INTO H,L PAIR MOV A,H ;WANT TO STRIP ANY BITS ABOVE 12 BITS ANI ^O17 ;KEEP ONLY RELEVANT BITS MOV H,A ;PUT IT BACK SHLD TMPB2 ;PUT IT IN THE TEMP PLACE CALL P16. ;PRINT THE EXPECTED PCRLF PUSH B ;SAVE B REG TOO CALL DECNET ;IF THERE IS A HOST, TELL HIM TOO POP B INTON ;AND BACK TO INTERNAL MODE POP D POP H RET ;EXECUTE CHANNEL COMMANDS.... DSXFR: LXI H,DSKSEQ ;PNTR TO COMMAND LIST XCTNOW: CALL CHNXCT ;EXECUTE CHANNEL LIST RET MTXFR: LXI H,MTASEQ ;PNTR TO COMMAND LIST XCTMTA: STA SKP.GO ;ACCUM HAD XFR TYPE..SAVE IT JMP XCTNOW ;GO EXECUTE THE CHANNEL COMMAND LIST QMXFR: LXI H,QTXFR ;PNTR TO COMMAND LIST JMP XCTMTA ;GO EXECUTE THE CHANNEL COMMAND LIST MTRESET: LXI H,MTARST ;CHANNEL COMMAND LIST TO CLEAR ERROR FROM MAGTAPE JMP XCTNOW ;GO EXECUTE THE CHANNEL COMMAND LIST .SBTTL CHANNEL COMMAND LIST EXECUTOR ;ROUTINE TO A CHANNEL COMMAND LIST TYPE OPERATION, FOR DATA ;TRANSFERS FROM OUR SELECTED BOOT DEVICE.. ;COMMAND LIST IS CODED AS FOLLOWS ; THE LIST IS A SERIES OF 36-BITCOMMANDS. ;WE HAVE FREE USE OF BITS 0-17 AS COMMAND TYPES ; BITS 15,16,17 .EQ. 0 MEAN "DI" COMMAND ; BITS 15,16,17 .EQ. 1 MEAN "LI" COMMAND ; BITS 15,16,17 .EQ. 2 MEAN "EI" COMMAND ; BITS 15,16,17 .EQ. 3 MEAN "WAIT" COMMAND ; BITS 15,16,17 .EQ. 4 MEAN "ERRTST" COMMAND ; BITS 15,16,17 .EQ. 5 MEAN "END" OF COMMAND LIST ; BITS 15,16,17 .EQ. 6 MEAN "TWAIT" COMMAND ; BITS 15,16,17 .EQ. 7 MEAN "UBA" COMMAND ;POINTER TO THE CURRENT COMMAND LIST IS ALWAYS STORED IN H,L CHNXCT: INTON ;SET UP FOR INTERNAL MODE PUSH B PUSH D PUSH H DSCON: LXI D,2 ;"D,E" GETS THE CONSTANT "2" DAD D ;NOW "H,L" POINTS TO "DATA+2"(BITS 12-19) MOV B,H ;COPY "H,L" INTO "B,C" MOV C,L PUSH H ;SAVE "H,L" MOV A,M ;GET BITS 12-19 INTO ACCUM RAR ;NOW JUSTIFY ACCUM AT BITS 16,17 RAR ;TAKES 2 SHIFTS ANI ^O17 ;OFF ALL BUT BITS 14,15,16,17 MOV E,A ;NOW PUT INTO LO-ORDER HALF OF DOUBLE REG LXI H,DSLST ;GET A PNTR TO THE DISPATCHING LIST DAD D ;CREAT PNTR TO THE COMMAND MOV E,M ;GET LO ORDER PIECE OF CMD DISPATCH INX H MOV D,M ;GET HI ORDER PIECE OF CMD DISPATCH XCHG ;ASSEMBLED ADDRESS TO "H,L" LXI D,XFRRT ;NOW GET A PSEUDO RETURN PC TO PUT ON STACK PUSH D ;AND PUT IT THERE PCHL ;DISPATCH TO THAT ASSEMBLED ADDRESS ;UPON COMPLETION OF THE COMMAND LIST COMMANDS, YOU GENERALLY ;RETURN HERE IN THE CODE XFRRT: POP H ;GET THE POINTER TO CURRENT LOCATION IN COMMAND LIST INX H ;MAKE IT POINT TO NEXT WORD IN THE LIST JMP DSCON ;AND CONTINUE IN COMMAND LIST EXECUTOR ;COMMAND LIST DISPATCH SELECTION DSLST: .ADDR CMDDI ;DI CMD .EQ. 0 .ADDR CMDLI ;LI CMD .EQ. 2 .ADDR CMDEI ;EI CMD .EQ. 4 .ADDR CMDWAIT ;WAIT CMD .EQ. 6 .ADDR CMDERCHK ;ERRTST CMD .EQ. 10 .ADDR CMDEN ;END CMD .EQ. 12 .ADDR CMDTWAIT ;WAIT CMD WITH NO TIMEOUT. CHECKS FOR BIT TRUE .EQ. 14 .ADDR CMDUBA ;LI TYPE CMD. NO OFFSETS, GOOD FOR UBA STUFF .EQ. 16 ;CODE FOR "EI" COMMAND CMDEI: ANA A ;CLR THE "C-BIT" JMP CMDLI1 ;GO TO COMMON CODE FOR LI AND EI COMMAND ;CODE FOR "LI" COMMAND CMDLI: STC ;SET THE "C-BIT" CMDLI1: PUSH PSW ;AND SAVE IT MOV5B ;PASS THE COMMAND LIST EXECUTOR THE RHBASE ADDRESS .ADDR RHBASE ;KEPT IN HERE .ADDR IOAD ;USED IN HERE LXI H,IOAD+2 ;"H,L" PNTS TO DEST+2 LDA UBANUM ;CURRENT UBA NUMBER INTO ACCUM ORA M ;THROW IN THE CURRENT BITS MOV M,A ;PUT IT ALL BACK DCX H ;NOW MAKE "H,L" POINT TO ADDR +0 DCX H DCX B ;MAKE "B,C" PAIR POINT TO SELECTED OFFSET FROM BASE LDAX B ;GET SELECTED OFFSET ADD M ;ADD OFFSET TO THE BASE MOV M,A ;AND PUT THE WHOLE MESS BACK POP PSW ;NOW GET STATE OF PROCESSOR FLAGS RC ;IF "C" SET,IT WAS AN LI AND WE ARE DONE ;CALL THRU IF "C" CLR..IT WAS EI AND WE MUST FINISH IT CALL EI1 ;EXECUTE "EI" CMD RET ;ALL DONE ;CODE FOR LI TYPE COMMAND ONLY USING NO OFFSETS, TAKING THE ADDRESSES ;EXACTLY AS PRESENTED.. GOOD FOR UBA OPERATIONS, WHICH REQUIRE NO OFFSETS CMDUBA: LXI D,IOAD+2 ;"D,E" PNTS TO DEST+2 PUSH D ;SAVE THE ADDRESS OF UBA/RH ADDRESS CALL MOV18B ;MOVE SOME DATA POP H ;ADDR OF UBA/RH INTO H,L LDA UBANUM ;CURRENT UBA NUMBER INTO ACCUM ORA M ;THROW IN THE CURRENT BITS MOV M,A ;PUT IT ALL BACK RET ;WE ARE DONE ;CODE FOR DI COMMAND CMDDI: LDAX B ;GET DISP CODE TO SEE IF INDIRECT ANA A ;CHECK THE SIGN BIT JP DILOCL ;AND JUMP IF NO INDIRECTION ;FALL TO HERE IF WAS INDIRECT MOV L,C ;PASS ADDR IN "B,C" TO "H,L" MOV H,B DCX H ;NOW BACK UP PNTR TO HI ORDER PCE OF INDIRECT WRD MOV B,M ;AND INTO B DCX H ;NOW TO LO ORDER PIECE OF INDIRECT WORD MOV C,M ;LO ORDER PIECE TO C AND DONE INX B ;"B,C" MUST POINT TO SRC + 2 INX B DILOCL: LXI D,DMDAT+2 ;"D,E" POINTS TO DEST+2 CALL MOV18B ;MOVE SOME STUFF AROUND CALL DI1 ;EXECUTE THE DEPOSIT RET ;AND BACK TO COMMAND LIST ;CODE FOR WAIT COMMAND(FOR WAITING FOR A TAPE TO FINISH, FOR EXAMPLE) CMDWAIT: XRA A ;CLEAR ACCUM MOV D,A ;NOW CLR "D", THE REGISTER WE WILL USE FOR TIMEOUT COUNT MOV E,A ;CLR "E" TOO WAITLP: PUSH B ;SAVE B,C CALL CHKBIT ;CHECK BITS VERSUS DEVICE STATUS TO SEE IF SET(I.E READY) POP B ;RESTORE B,C RNZ ;IF READY BIT SET, ITS OK, GO AWAY ;FALL THRU IF READY NOT SET PUSH B ;SAVE B,C FROM DESTRUCTION PUSH D ;SAVE TIME-OUT COUNT CALL EI1 ;DO ANOTHER EXAMINE OF DEVICE STATUS TO SEE IF READY NOW POP D ;GET THE TIME-OUT COUNT POP B ;RESTORE B,C INX D ;INCREMENT MOV A,E ;SEE IF COUNT DOWN TO ZERO YET ORA D ;USE TOP HALF TOO JNZ WAITLP ;GO TRY AGAIN ;FALL THRU IF DEVICE TIME'S OUT BEFORE GETTING A READY JMP DEVERR ;GO REPORT "?BT" AND THE FAILED PC ;CODE FOR TWAIT COMMAND CMDTWAIT: PUSH B ;FIRST SAVE THE BC POINTERS CALL EI1 ;READ THE CURRENT STATE AS IT IS NOW POP B ;RESET B TO A GOOD VALUE PUSH B ;AND SAVE IT FROM DESTRUCTION AGAIN CALL CHKBIT ;NOW SEE IF APPROPRIATE BIT IS SET POP B ;RESTORE RNZ ;RETURN IF BIT WAS SET AS DESIRED JMP DEVERR ;ELSE.. GO SAY ERR, BIT WAS NOT SET AS DESIRED ;CODE FOR ERROR TEST COMMAND CMDERCHK: PUSH B ;SAVE B,C CALL CHKBIT ;FIRST GO CHECK TO SEE IF ANY OF DESIRED BITS SET POP B ;AND RESTORE RZ ;IF NONE SET, RETURN CAUSE ALL IS OK ;FALL TO HERE IF SOME BITS SET..HAD DEVICE ERROR & THEREFORE "BOOT" FAILED DEVERR: MOV H,B ;NOW COPY "B,C" TO "H,L" REGISTER MOV L,C SHLD ERRCD ;"H,L" NOW HAS FAILING PC INTOFF ;LET ALL MESSAGES PRINT NOW XRA A ;CLR C-BIT, SO THAT IT WILL SET LATER, TO INDICATE ERR JMP DEVEXIT ;GO EXIT WITH MESSING WITH PRINT FLAGS ;CODE FOR THE END COMMAND CMDEN: LXI D,MAD000 ;GUARANTEE CSL BUS ADDR REG .EQ. 0 AFTER XFR CALL ADATP ;WRITE THE CSL BUS ADDRESS REG WITH 0'S INTOFF ;CLR INTERNAL MODE STC ;SET THE C-BIT, SO THAT IT WILL BE CLEARED LATER DEVEXIT: CMC ;COMPLEMENT C-BIT, SO IT WILL SAY ERR, OR NO ERR POP H ;THROW OUT PSEUDO RETURN FROM STACK TOP POP H ;THROW OUT THE SAVED "H,L" POP H ;AND RESTORE ALL THE REGISTERS POP D ;THAT WE SAVED POP B MVI A,0 ;ACCUM WILL ALWAYS BE 0 ON EXIT FROM CMD LIST EXECUTOR RET ;ROUTINE FOR MOVING 3 BYTES OF DATA ;"B,C" HAS SRC+2..."D,E" HAS DST+2 MOV18B: MVI H,2 ;COUNT OF 3 IS HOW MANY TO MOVE LDAX B ;GET PIECE OF SOURCE ANI 3 ;ONLY INTERESTED IN BITS 18,19 STAX D ;PUT AT DESTINATION DCX B ;POINT TO NEXT RELEVANT BYTE DCX D ;FOR SRC AND DST MOV18X: LDAX B ;GET A PIECE OF THE SRC TO ACCUM STAX D ;AND PUT AT DESTINATION PLACE DCX B ;DOWN THE POINTER DCX D ;DOWN THE OTHER POINTER DCR H ;AND DOWN THE COUNTER.. JNZ MOV18X ;CONTINUE TILL MOVED 3 BYTES RET ;THEN OUT ;COMMON ROUTINE FOR CHECKING DEVICE STATUS, FOR EITHER DEVICE ERRORS OR ;READY BIT TRUE..MUST BE CALLED IMMEDIATLY AFTER AN "EI." COMMAND CHKBIT: LHLD EMBUF ;GET CURRENT DEVICE STATUS INTO "H,L" DCX B ;MAKE B PNT TO +1 DCX B ; AND MAKE IT PNT TO +0 LDAX B ;BYTE OF DESIRED INTO ACCUM ANA L ;COMPARE AGAINST CURRENT DEVICE RNZ ;IF NON-ZERO, NO NEED TO LOOK FURTHER INX B ;IF 1ST BYTE WAS ZERO, BUMP PNTR TO LOOK AT NEXT BYTE LDAX B ;NEXT BYTE INTO THE ACCUM ANA H ;COMPARE VERSUS DESIRED RET ;PLAIN RETURN..Z BIT WILL BE SET APPROPRIATELY .SBTTL *** "BC" CMD *** ;CODE WHICH PERFORMS THE VERY FAMOUS BOOT CHECK I BCCMD: CALL MRCMD ;MAKE SURE MACHINE IS STOPPED INTON ;SET UP INTERNAL MODE CLRB ERRCD ;BEGIN BY CLEARING THE ERROR CODES CLRB ERRCD+1 ;MUST CLEAR BOTH HALVES .IF NDF,NEEDRM CLRRM BUSAD ;WILL GENERATE A STARTING BUFFER OF (400000,,0) MVI A,^O10 ;THIS TURNS OUT TO BE BIT0 IN 36-BIT LAND STA BUSAD+4 ; SET IT LXI B,^O400 ;SET B=1, C=0 BC.ALP: PUSH B ;SAVE COUNTERS CALL DBCMD ;EXECUTE THE DEPOSIT BUS ;CHECK FOR FAILURE LDA ERRCD ;FETCH AN ERROR CODE ANA A ;SET 8080 CONDITION CODES JNZ BCA.ERR ;GO STANDARD ERROR REPORT IF ERR FOUND ;NO ERROR, GENERATE THE NEXT DATUM LXI H,BUSAD ;POINT TO A BUFFER TO BE SHIFTED CALL SHR36 ;SHIFT 36 BITS(I.E. FLOAT A 1 OR 0) .BYTE 1 ;SHIFT ONLY ONE PLACE AT A TIME ;NOW CHECK FOR END OF TEST POP B ;GRAB UP THE CURRENT LOOP COUNTERS INR C ;UP COUNT FOR THIS DATAUM MOV A,C ;COPY TO ACCUM CPI 36. ;NOW SEE IF FLOATED DOWN THE ENTIRE 36 BIT WORD JC BC.ALP ;JUMP IF NOT DONE A GROUP OF 36 YET.. ;HERE WHEN DONE A GROUP OF 36, SEE IF THIS WAS FIRST OR SECOND TIME THROUGH DCR B ;DECREMENT "TIMES THROUGH THE LOOP" COUNTER JM BC.2ND ;IF MINUS, TIME TO GET OUT..GO NEXT PHASE OF TEST ;HERE WHEN DONE FIRST WORD, TIME TO SET UP TO FLOAT A 0 THROUGH A FIELD ;OF ONES MOV5B ;MOVE 2ND DATA PATTERN .ADDR BC.DB2 ;INIT 2ND PATTERN TO BE (377777,,777777) .ADDR BUSAD ;AND THIS IS THE PLACE THAT THE DB COMMAND USES MVI C,00 ;RESET THE COUNTER JMP BC.ALP ;AND GO ROUND FOR THE SECOND TIME...... BC.DB2: D 377,777,,777,777 ;BOOTCHECK CODE FOR EXECUTING A TEST OF THE CRAM AND ITS ABILITIY TO HOLD ;ALL ONES AND ZEROES, AND TO SEE IF ITS ADDRESSING LOGIC WORKS AS ;IT SHOULD.... BC.2ND: LXI H,00 ;START AT CRAM ADDRESS 00 BC.BLP: CALL W.CRMZ ;WRITE THE LOCATION WITH ALL ZEROES INX H ;UPDATE TO NEXT CRAM ADDRESS MOV A,H ;NOW CHECK TO SEE IF DONE ALL ANI ^O10 ;IS ADDRESS AT "4000" YET?? JZ BC.BLP ;BACK AND ZERO MORE IF NOT YET ;NOW READY FOR COMBINED ADDRESS AND DATA TEST MVI H,00 ;L IS ALREADY .EQ. 0, NOW MAKE H,L PAIR .EQ. 0 BC.BL1: CALL CADWR ;WRITE CURRENT CRAM ADDRESS PUSH H ;AND SAVE IT FOR A WHILE CALL CP1 ;CLOCK TO GET THE CONTENTS OF THAT LOC TO C.R. CALL RCINT ;NOW READ-IN THE CONTENTS OF THE C.R. LXI H,00 ;DATA TO VERIFY AGAINST IS 00 CALL V.VER ;VERIFY CONTENTS OF C.R. TO BE ALL 0 CALL A.CRMO ;NOW WRITE THAT LOCATION WITH ALL ONES POP H ;RETRIEVE CURRENT CRAM ADDRESS INX H ;UP TO THE NEXT ADDRESS MOV A,H ;COPY HI HALF TO ACCUM, SO CAN CHECK FOR 4000 ANI ^O10 ;ADDRESS AT "4000"?? JZ BC.BL1 ;BACK INTO LOOP IF NOT YET.. ;WHEN DONE HERE, FALL INTO MEMORY PART OF BOOT CHECK ;A PAGE MOS MEMORY CHECK BC.3RD: CALL ZMCMD ;FIRST CLEAR THE ENTIRE MOS MEMORY(AT LEAST TRY) MOV5B ;SET UP THE INITIAL DATA .ADDR ONES ;DATA FOR DEPOSITING IS ALL ONES .ADDR DMDAT ;.. THE DEPOSIT BUFFER MOV5B ;SET UP THE STARTING MEMORY ADDRESS .ADDR MA1000 ;START AT ADDRESS 1000 .ADDR MEMAD ;.. MEMORY ADDRESS BUFFER BC.CLP: CALL EM2 ;EXAMINE A LOCATION CALL CMP36 ;THEM COMPARE RESULTS..DATA SHOULD BE ALL ZEROES .ADDR EMBUF ;THIS IS THE ACTUAL READ-IN DATA .ADDR ZEROES ;VERSUS 36-BITS OF 0'S JNZ BC.CERR ;GO TO ERROR REPORT IF NOT ALL ZEROES ;FALL THRU IF THAT WENT OK. CALL DM2 ;NOW DEPOSIT ONES INTO THAT LOC AND CONTINUE CALL EM2 ;WHILE WE ARE AT IT, WE'LL CHECK ALL ONES CALL CMP36 ;DO THE 36-BIT COMPARE .ADDR EMBUF ;THIS STUFF JUST READ IN .ADDR ONES ;AGAINST ALL ONES JNZ BC.CERR ;IF BAD, SAY SO.. LHLD MEMAD ;FETCH UP THE CURRENT MEMORY ADDRESS INX H ;UPDATE TO THE NEXT MOV A,H ;COPY HI PIECE TO THE ACCUM ANI ^O4 ;SEE IF REACHED ADDRESS 2000 SHLD MEMAD ;REPLACE THE UPDATED ADDRESS FIRST JZ BC.CLP ;AND CONTINUE IF HAD NOT REACHED THE MAX RET ;RETURN..DONE ALL BOOT CHECK OK ;SUBROUTINES REQUIRED FOR THE CRAM TESTING ;SUBROUTINES FOR WRITING ALL ONES AND ALL ZEROES INTO A SELECTED CRAM ;LOCATION.. DESIRED ADDRESS PASSED IN THE H,L REGISTER(FOR W.XXX CALLS) ;USES CURRENTLY SELECTED ADDRESS FOR (A.XXX CALLS) A.CRMO: PUSH H ;SAVE H,L LXI H,-1 ;H,L TO ALL ONES INDICATES THE ALL ONES DATA DESIRED JMP W.LOC ;GO COMMON CODE W.CRMZ: CALL CADWR ;WRITE DESIRED ADDRESS A.CRMZ: PUSH H ;SAVE H,L LXI H,00 ;SET TO ZERO, DATA IS ALL ZEROES W.LOC: MVI C,7 ;TAKES 8 FUNCTION WRITES TO DO ALL OF ONE CRAM LOC W.LP: MOV A,C ;GET CURRENT FUNCTION TO ACCUM STA CRMFN ;PUT FUNCTION INTO LOC USED BY STANDARD ROUTINE CALL WFUNC ;WRITE ONE OF THE 8 PIECES OD A CRAM LOC DCR C ;DOWN COUNT JP W.LP ;AS LONG AS .GE. 0, KEEP GOING POP H ;HERE WHEN DONE ALL 8 RET ;NOW GET OUT OF HERE. ;ROUTINE TO VERFIY THAT A CRAM LOCATION IS INDEED ALL ONES OR ALL ZEROES. ;NO ARGUMENTS PASSED TO THIS ROUTINE V.VER: SHLD CRMBF+^O14 ;ALL DONT CARE LOCS OF THE "READ" ARE FUDGED SHLD CRMBF+^O16 ; TO MATCH EXPECTED DATA SHLD CRMBF+^O20 ; THERE ARE 12 DONT CARE LOCATIONS SHLD CRMBF+^O30 ; SOME ARE VARIOUS ADDRESS(NXT/CURRENT/SUBRTN) SHLD CRMBF+^O32 ; AND SOME ARE JUST UNBUFFERED COPIES OF THE SHLD CRMBF+^O34 ; BUS MOV A,L ;NOW COPY EXPECTED DATA INTO "B,C" PAIR CMA ;FIRST COMPLIMENT MOV C,A ;THEN MOVE MOV A,H ; NEED BOTH HALVES PLEASE CMA ;COMPLIMENT MOV B,A ;THEN MOVE LXI H,CRMBF ;NOW POINT TO BEGINNING OF BUFFER WHERE EXPECTED DATA V.BCLP: MOV E,M ;IS KEPT.. PROCEED TO COPY BUFFER DATA INTO INX H ;(UPDATE POINTER) MOV D,M ;THE D,E REGISTER PAIR INX H ;AND UPDATE MEMORY POINTER AFTER EACH MOVE XCHG ;SWAP, SO NOW "H,L" HAS BUFFER, "D,E" HAS POINTER DAD B ;ADD COMPLIMENT TO EXPECTED...SHOULD GET 0. INX H ; TWO'S COMPLIMENT , THAT IS.. MOV A,L ;PIECE TO ACCUM ORA H ;"OR" IN THE OTHER PIECE JNZ BC.BERR ;AND GO HANDLE ERROR IF RESULTS .NE. 0 ;YOU FELL THROUGH TO HERE IF DATA CHECK WAS OK.. XCHG ;SWAP..NOW "H,L" HAS POINTER, "D,E" HAS 00 MVI A,<&^O377> ;CHECK IF DONE CMP L ;SEE IF AT LAST LOCATION IN LIST JNZ V.BCLP ;JUMP BACK IF NOT YET RET ;ELSE OK TO RETURN ;ERROR REPORTING BC.CERR: LHLD MEMAD ;GRAB UP FAILED MEM ADDRESS MVI B,^O100 ;GET A BIT TO SET IN ERROR PRINTOUT JMP BCC.ERR ;GO PROCESS STANDARD ERROR TYPEOUTS BC.BERR: POP H ;CLEAR A RETURN ADDRESS MVI B,^O200 ;BIT TO SET FOR CRAM FAILURES POP H ;NOW GATHER UP THE CURRENT CRAM ADDRESS BCC.ERR: SHLD ERRCD ;SAVE 1 BYTE BY DEPOSITING TWICE MOV A,H ;HI HALF TO THE ACCUM ORA B ;THROW IN A WEIGHT SO NUMBER WILL DIFFER STA ERRCD+1 ;PUT NUMBER INTO ERROR CODE LOC JMP BCB.ERR ;AND GO PRINT OUT THE CORRECT ERROR STUFF BCA.ERR: POP B ;GET COUNTER OFF THE STACK MOV A,C ;SUBTEST TO ACCUM STA ERRCD ;PLACE FROM WHICH TO REPORT ERRORS BCB.ERR: CLRB NOPNT ;GUARANTEE PRINTING ON PLINE ERRMSG ;"?BC" LXI H,ERRCD ;POINT AT THE ERROR I.D. CALL P16 ;PRINT JMP MMERR ;OUT .ENDC