1
0
mirror of https://github.com/PDP-10/its.git synced 2026-03-07 03:35:53 +00:00
Files
PDP-10.its/src/kshack/cmds.m80
2018-09-18 07:17:02 +02:00

2559 lines
82 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
.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 <CR><LF>
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,<<CRMBF+32.>&^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