1
0
mirror of https://github.com/PDP-10/its.git synced 2026-03-29 19:08:01 +00:00
Files
PDP-10.its/src/kshack/hcore.m80
2018-09-18 07:17:02 +02:00

1768 lines
58 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**** KS10 CONSOLE HARDCORE ****
.SBTTL **"RST" INSTRUCTION CODE**
;AT POWER UP, ALWAYS BEGIN AT 0000
.= 0000
NOP ;NO-OPS FOR 2 INSTR CYCLES
NOP ; LETS 8080 SETTLE DOWN
DI ;GUARANTEE INTERRUPTS DISABLED
JMP PWRUP ;BEGIN WITH INITIALIZATION CODE
;*** RESERVE "RESTART" MEMORY BLOCKS FOR INTERRUPTS
;*** AND SPECIAL PURPOSE "RST" INSTRUCTIONS
;BEGIN CODE FOR "PCHAR" WITH A "RST 1"
.= ^O10
XTHL ;GET POINTER TO TRAILING ARG
MOV A,M ;CHAR INTO ACCUM
INX H ;UPDATE POINTER TO RETURN ADDRESS
XTHL ;RESTORE RETURN ADDRESS TO STACK
JMP PCHR ;AND GO....
;*** RESERVE "RESTART" MEMORY BLOCKS FOR INTERRUPTS
;*** AND SPECIAL PURPOSE "RST" INSTRUCTIONS
;SUBROUTINE TO SET INTERNAL STATUS(I.E. DONT TYPE ON TTY)
.= ^O20
INTON: PUSH H ;SAVE THE LIL BUGGER
LXI H,NOPNT ;GET VALUE OF FLAG
INR M ;INCREMENT BY ONE
POP H ;RESTORE THE REG WE SAVED
RET ;AND RETURN
;*** RESERVE "RESTART" MEMORY BLOCKS FOR INTERRUPTS
;*** AND SPECIAL PURPOSE "RST" INSTRUCTIONS
;BEGIN CODE FOR "PLINE"
.= ^O30
XTHL ;GET PNTR TO TRAILING ARG
MOV E,M ;GET LO ORDER PIECE
INX H ;UPDATE PNTR
MOV D,M ;GET HI ORDER PIECE
INX H ;UPDATE PNTR
JMP PLNE ;AND GO TO ACTUAL ROUTINE
;*** RESERVE "RESTART" MEMORY BLOCKS FOR INTERRUPTS
;*** AND SPECIAL PURPOSE "RST" INSTRUCTIONS
;BEGIN CODE FOR "TRAP" OR "UUO" TYPE SUBROUTINE CALLS
.= ^O40
XTHL ;SAVE "H,L" WHILE GETTING PC
MOV A,M ;GET INDEX INTO SUBROUTINE DISPATCH LIST
INX H ;UPDATE "PC" TO POINT AT RETURN
XTHL ;PUT BACK RETURN AND RESTORE "H,L"
PUSH H ;NOW SAVE "H,L" WHILE WE SET UP DISPATCH
JMP RTNDIS ;GO CALCULATE SUBROUTINE TO DISPATCH TO..
;*** RESERVE "RESTART" MEMORY BLOCKS FOR INTERRUPTS
;*** AND SPECIAL PURPOSE "RST" INSTRUCTIONS
;THIS CODE CLEARS A SINGLE BYTE OF RAM SPACE, IN THE RANGE
;FROM 20000-20377
.= ^O50
XTHL ;SAVE "H,L" WHILE GETTING PC
MOV A,M ;GET INDEX INTO SUBROUTINE DISPATCH LIST
INX H ;UPDATE "PC" TO POINT AT RETURN
XTHL ;PUT BACK RETURN AND RESTORE "H,L"
PUSH H ;NOW SAVE "H,L" WHILE WE SET UP DISPATCH
JMP CLRBYT ;GO CALCULATE SUBROUTINE TO DISPATCH TO..
;*** RESERVE "RESTART" MEMORY BLOCKS FOR INTERRUPTS
;*** AND SPECIAL PURPOSE "RST" INSTRUCTIONS
;THIS CODE EXECUTES THE "INTERNAL MODE OFF" FUNCTION, TURNING OFF
;THE PRINTING OF 8080 FUNCTIONS EXECUTED INTERNALLY. "INTOFF" IS
;CALLED AT LEAST 15 TIMES, SO THIS RESTART CODE SAVES AT LEAST
;30 BYTES OVER "CALLS INTOFF"
.= ^O60
PUSH H ;SAVE THE LIL BUGGER
LXI H,NOPNT ;CLEAR ACCUM
DCR M ;DECREMENT PRINT FLAG
POP H ;RESTORE THE REG WE SAVED
RET ;AND RETURN
;*** RESERVE "RESTART" MEMORY BLOCKS FOR INTERRUPTS
;*** AND SPECIAL PURPOSE "RST" INSTRUCTIONS
;BEGIN CODE FOR HANDLING INTERRUPTS
.= ^O70
DI ;GUARANTEE INTERRUPTS DISABLED
PUSH PSW ;SAVE
PUSH B ; EVERYTHING
PUSH D ; ONTO THE STACK
PUSH H
JMP INTRP ;AND GO TO PROCESS THE INTERRUPT...
;MAINLINE CODE BEGINS HERE
.= ^O100
.SBTTL **POWER UP START LOCATON**
;BEGIN BY SETTING UP 8080 STACK POINTER
PWRUP: LXI SP,RAMST+^O2000 ;LOAD STACK PNTR WITH TOP RAM LOC
;*********************************************
;WILL BE TAKEN OUT WHEN WE PUT IN THE POWER UP SELF TEST
;MUST SET DISPATCH LIST AND CLEAR RAM
LXI H,RAMST ;SET "H,L" REGISTER TO START RAM ADDR
LXI D,^O2000 ;COUNTER TO FILL REST OF RAM W 0'S
CLRLP: MVI M,00 ;CLEAR A RAM LOC
INX H ;NEXT RAM LOCATION
DCX D ;DOWN COUNTER
MOV A,E ;LO ORDER PIECE TO ACCUM
ORA D ;THROW IN THE HI ORDER PIECE
JNZ CLRLP ;CONTINUE TILL DONE
;***************************************************
;BEGIN PROCEEDURE FOR INITIALIZING KS10
;MUST INDIVIDUALLY CLEAR KS10 FLOPS "RUN","EXECUTE",& "CONTINUE"
; BECAUSE THEY ARE NOT RESET BY KS10 BUS RESET
XRA A ;SET ACCUM=0
;SET 0'S TO "RUN,EXECUTE,CONT"
OUT CPUCTL ;***** I/O WRT 212/0 *****
;ISSUE KS10 BUS RESET
CALL MRINT ;DOES RESET AND SETS DEFAULT PARITY & TRAPS
.SBTTL **INITIALIZE UARTS**
;RAM BUFFERS HAVE BEEN INITIALIZED.. NOW MUST READ FRONT
; PANEL SWITCHES & INITIALIZE "UART"
IN TTYSW ;***** I/O READ 300Q *****
CMA ;FIX INVERSION
LXI B,^O2200 ;THIS SETS B=^O4 AND C=^O200
MOV H,A ;H WILL HOLD CTY STOP BIT FOR US.@BIT POS 7
RAR ;BIT 4 MOVES TO BIT 3
RAR ;BIT MOVES TO BIT 2
MOV E,A ;E WILL HOLD KLINIK LENGTH BIT. @BIT POS 2
RAR ;BIT 6 IS AT 4 FROM OTHER SHIFTS, NOW TO BIT 3
RAR ;AND TO BIT 2
MOV L,A ;L WILL HOLD CTY LENGTH BIT. @BIT POS 2
MOV A,H ;ORIGINAL BACK TO ACCUM
RAL ;BIT 5 TO BIT 6
RAL ;AND TO BIT 7
MOV D,A ;D WILL HOLD KLINIK STOP BIT. @BIT POS 7
;NOW BEGIN MASKING OPERATIONS TO ISOLATE THE DESIRED UART BIT SETTINGS
MOV A,C ;MASK OF OCTAL 200 INTO ACCUM
ANA H ;ACCUM HAS ONLY CTY STOP BIT
MOV H,A ;COPY BACK TO H
MOV A,C ;MASK TO ACCUM
ANA D ;ACCUM HAS ONLY A STOP BIT
MOV D,A ;COPY BACK TO D
;NOW MASK FOR THE LENGTH BITS
MOV A,B ;MASK OF OCTAL 4 INTO ACCUM
ANA L ;ACCUM NOW HAS CTY LENGTH BIT ONLY
ORA H ;THROW IN THE CTY STOP BIT
ORI ^B01001010 ;ADD IN THE CONSTANT BITS
OUT CTYCTL ;SET THE UART MODE..........
;NOW SET MODE FOR THE KLINIK STUFF
MOV A,B ;MASK OF OCTAL 4 INTO ACCUM
ANA E ;ACCUM NOW HAS KLINIK LENGTH BIT ONLY
ORA D ;THROW IN THE KLINIK STOP BIT
ORI ^B01001010 ;ADD IN THE CONSTANT BITS
OUT REMCTL ;SET THE KLINIK UART MODE
;NOW ENABLE THE UART TO RECEIVE AND TRANSMIT
MVI A,^B00010101 ;BITS FOR UART CONTROL
;SET UART TO RECEIVE AND TRANSMIT
OUT CTYCTL ;***** I/O WRT 200/025 *****
MVI A,^O20 ;ONE BIT TO SAY RESET THE UART
OUT REMCTL ;RESET THE KLINIK UART BUT DO NOT ENABLE IT!!
IN CTYDAT ;***** I/O RD 201***** READ 1 DUMMY CHAR OUT OF UART
IN REMDAT ;***** I/O RD 203***** READ 1 DUMMY CHAR OUT OF UART
CALL BFRST ;INIT TTY INPUT BUFFER
.SBTTL 8080 PROM CHECKSUMMER
;CODE TO COMPUTE A CHECKSUM FOR EACH OF THE 2K 8080 PROM PIECES
;FIRST COMPUTE THE CHECKSUMS FOR EACH PROM, THEN DO SIMPLE TEST ON THE 8080
;RAM..BEGIN WITH THE PROMS
LXI H,00 ;START AT PROM ADDRESS 0
LCHKR: XRA A ;CLEAR ACCUM
MOV C,A ;CLEAR B,C PAIR
MOV B,A ;"B,C" TO BE USED AS ADDEND
MOV E,A ;CLEAR D,E PAIR
MOV D,A ;"D,E" TO HOLD CURRENT COUNT OF CHECKSUM
A256: MOV C,M ;GET A BYTE
INX H ;UPDATE MEM POINTER
XCHG ;PUT CURRENT CHECKSUM SUB TOTAL INTO H,L
DAD B ;THROW IN AN ADDEND
XCHG ;RETURN H,L TO RIGHTFUL PLACE
;NOW QUICK CHECK FOR THE END OF PROM
MOV A,L ;GET LO ORDER OF CURRENT PROM ADDRESS
ANA A ;SET CONDITION CODES
JNZ A256 ;IF .EQ. 0,WE'VE DONE 256 LOCS, IF .NE. 0, DO MORE
;FALL TO HERE WHEN DONE A CHUNK OF 256..SEE IF ITS ON A PROM BOUNDARY NOW
MOV A,H ;GET HI ORDER PIECE OF ADDRESS
ANI ^O7 ;IF THIS .EQ. 0, THEN WE ARE AT A BOUNDARY
JNZ A256 ;IF .NE 0, THEN KEEP TRYING
;FALL THRU HERE WHEN WE'VE COMPLETED A PROMS WORTH
MOV A,H ;GET HI ORDER, WHICH CORRESPONDS TO "WHICH PROM"
RRC ;JUSTIFY AT EDGE OF THE ACCUM
RRC
RRC
DCR A ;DECREMENT MAKES "0-3" INSTEAD OF "1-4"
ADD A ;DOUBLE THIS VALUE TO MAKE IT ON 16 BYTE BOUNDARIES
PUSH PSW ;SAVE THIS VALUE FOR A BIT
PUSH H ;AND SAVE OUR CURRENT POINTER
JNZ DEV ;IF DOING PROM ZERO, ELIMINATE THE ACTUAL CHECKSUM COUNT
;FELL THRU TO HERE TO DO ACTUAL CHECKSUM ELIMINATION
;EXECUTED WHEN CHECKSUMMING PROM 0. IT REMOVES THE ACTUAL CHECKSUM VALUES
;FROM THE COMPUTED CHECKSUM, AS WE CANNOT SOLVE THE CHECKSUM FEEDBACK
;LOOP PROBLEM
PUSH PSW ;SAVE ACCUM
LXI H,CHECKS ;H,L GETS A POINTER TO THE LIST OF CHECKSUMS
MVI A,8. ;START WITH A COUNT OF 8, FOR THE EIGHT BYTES WE MUST SUB
DEVLP: STA T80DT ;SAVE COUNT IN RAM, SO WE CAN USE ACCUM
MVI B,^O377 ;IN B,C PAIR, ENSURE UPPER HALF .EQ. -1
MOV A,M ;GET CHECKSUM BYTE TO ACCUM
CMA ;NEGATE IT
MOV C,A ;THROW IT INTO A 16 BIT ENTITY
INX B ;AND MAKE B,C PAIR 2'S COMPLIMENT
XCHG ;GET CURRENT COMPUTED CHECKSUM TO H,L
DAD B ;"SUBTRACT" THE BYTE WE'VE ASSEMBLED.(2'S COMP ADDITION)
XCHG ;PUT H,L/D,E PAIR RIGHT
INX H ;AND UPDATE THE POINTER INTO THE LIST
LDA T80DT ;GET OUR CURRENT COUNT FROM THE RAM
DCR A ;DECREMENT
JNZ DEVLP ;CONTINUE IN THE LOOP
LXI B,00 ;NOW GUARANTEE B,C PAIR IS ALL GONE
;FALL THRU WHEN FINISHED
POP PSW ;RESTORE ACCUM
DEV: MOV C,A ;GET CURRENT PROM NUMBER INTO C
LXI H,CHECKS ;H,L POINTS TO THE TABLE OF CHECKSUM
DAD B ;ADD INDEX, AND NOW (M) PNTS TO EXPECTED CHECKSUM
MOV C,M ;COPY EXPECTED CHECKSUM INTO C
INX H
MOV B,M ;AND B, MAKES "B,C" PAIR
INX H ;AND KEEP COUNT UP
;NOW D,E HAS CALCULATED CHECKSUM AND B,C HAS EXPECTED CHECKSUM
XCHG ;H,L NOW HAS CALCULATED CHECKSUM
DAD B ;IF CHECKSUM OK, RESULT OF THIS SHOULD .EQ. 0
MOV A,L ;GET LO PIECE
ORA H ;THROW IN HI PIECE..CONDITION CODE FLAGS NOW SET
XCHG ;D,E NOW HAS THE RESULTS OF THE ADDITION
POP H ;BEFORE JUMPING ON CONDITION CODES, FIRST FIX REGISTER
JNZ CHKERR ;IF H,L WAS .NE. 0, THEN WE HAD PROM CHECKSUM ERROR...
;FALL THRU IF CHECKSUM WAS OK
POP PSW ;RESTORE INDEX INTO "WHICH PROM" WE ARE IN
CPI 6 ;SEE IF DONE ALL
JNZ LCHKR ;JUMP BACK TO BEGINNING IF NOT DONE ALL
;FALL THRU IF DONE ALL..PROMS CHECKSUM OK
JMP XXX230 ;SO AVOID THE ERROR PRINTOUT CODE
;YOU JUMPED TO HERE IF YOU ENCOUNTERED A CHECKSUM ERROR.
ROMMSG: .ASCIZ /?CHK / ;IF PROM CHECKSUM FAILS, USE THIS MESSAGE
CHKERR: PLINE ROMMSG ;PRINT "?CHK "
POP PSW ;RETRIEVE PROM NUMBER
RRC ;DIVIDE DOWN, SINCE WE DOUBLED IT BEFORE
INR A ;MAKE PROM TYPE-OUT BE 1-4
ORI ^O60 ;MAKE IT ASCII
CALL PCHR ;GO PRINT IT
PCRLF ;<CR-LF>
;FINAL STEP IS TO ENABLE PARITY DETECTION IN THE KS10
; DEFAULT IS: PARITY DETECTION ON..DATA PATH PARITY DETECION ENABLED
XXX230: MVI A,DEFLTE ;INIT ENABLES TO BE ON
OUT SMPAR ;***** I/O WRT 100/174 *****
;LITTLE ROUTINE TO LOAD ALL DEFAULT CONSTANTS INTO THE 8080 RAM
;THIS ROUTINE SAVE ABOUT 40. BYTES OF PROM, OVER USING LXI'S,SHLD'S
;MVI'S & STA'S
LXI H,KATIM1 ;LIST OF DESTINATION LOCATIONS BEGINS HERE
LXI D,PRMLST ;LIST OF DATUMS FOR THE RAM INIT
RAMMER: LDAX D ;GET BYTE FROM THE DATA LIST
CPI ^O252 ;TEST FOR END OF LIST
JZ XXX235 ;CONTINUE PROM INIT
;ELSE MORE RAM TO INITIALIZE
MOV M,A ;PUT GOOD STUFF IN RAM
INX H ;UPDATE POINTERS
INX D
JMP RAMMER
PRMLST:
.ADDR KPAINI ;KATIM1(2) KEEP ALIVE INITIAL COUNTER
.IIF DF,SCECOD, .BYTE -1 ;FOR SCE ADR INIT
.IIF DF,SCECOD, .BYTE -1 ;FOR SCE ADR INIT
.ADDR MODE0 ;MODDIS(2) INIT THE KLINIK LINE TO MODE 0
.ADDR REINI ;NORMAL INSTR ENDS WILL GO TO REINIT
.ADDR ENVBUF ;ENVPNT(2) APT PNTER FOR ENVELOPES SENT TO THE HOST
.BYTE DEFLTE ;PARBT(1) INIT ENABLES TO BE ON
.BYTE TRPDEF ;TRAPEN(1) INIT ENABLES THE HARDWARE TRAPS
.BYTE ^O14 ;MTAUBA(1) DEFAULT MAGTAPE UBA NUMBER IS "3"
.BYTE ^O4 ;DSKUBA(1) DEFAULT DISK UBA NUMBER IS "1"
.BYTE ^O10 ;STATE(1) STATE BEGINS WITH DTR TRUE
.BYTE ^O41 ;LSTMSG(1) FIRST APT MSG SHOULD BE 136(NOT OF 41)
D 0,0,,2,0 ;DEN.SLV(5) GET DEFAULT VALUE FOR ALL TAPES
.MTBASE: D 0,0,,772,440 ;MTBASE(5) INITIAL DEFAULT MTA RHBASE ADDRESS
.DSBASE: D 0,0,,776,700 ;DSBASE(5) INITIAL DEFAULT DSK RHBASE ADDRESS
.BYTE -1 ;RPINI(1) SO CAN MAKE IT -1
.BYTE ^O252 ;END OF LIST MARKER
XXX235: MVI A,^O25 ;BIT TO RESET THE UART
OUT REMCTL ;RESET THE KLINIK UART AND ENABLE IT!!
MVI A,^O10 ;GET A BIT TO SET "DATA TERMINAL READY"
OUT DTR ;SET IT.
PLINE INIMS ;PRINT VERSION AND ID
INTON ;SET INTERNAL MODE
CALL EM1 ;DO PSUEDO EXAMINE TO SET MEM LATCHES
CALL EBCMD ;EXAMINE THE BUS, TO SEE IF ZERO
EI ;ENABLE INTERRUPTS
CALL CMP36 ;NOW CHECK RESULTS OF THE "EB" CMD
.ADDR EMBUF ;THE RESULTS READ FROM THE BUS
.ADDR MAD000 ; VERSUS A WORD OF ALL ZEROES
JZ PWRCHK ;IF OK, GO TO AUTO BOOT
;FALL THRU IF ERRORS ENCOUNTERED
INTOFF ;LEAVE INTERNAL MODE
PLINE INIER ;SAY "INITIALIZE ERROR"
JMP REINI ;AND GO OUT
;JUMP TO HERE IF DOING PWR FAIL RESTART
PWR.FAIL: CALL MICROP ;READ IN POINTERS AND READY TO GO
JC C.BTERR ;IF BOMBED, GIVE UP
CALL DMEM2CRAM ;GO READIN THE MICRO-CODE
CALL BT.GO ;START MICRO-CODE
CLRRM TMPBF2 ;CLEAR A BUFFER
MVI M,^O70 ;POWER FAIL START ADDRESS IS "70"
MVI A,4 ;CODE 4 INDICATES PWR FAIL
STA GOCODE ;SAVE IN RESTART INDICATOR
CALL STINT ;GO START MACHINE, USE INTERNAL MODE
JMP REINI ;AND GO LET THINGS HAPPEN
;FIRST THING TO DO IS TO CHECK IF THIS IS A POWER FAIL RESTART
;NOTE: WE ARE STILL IN "INTERNAL" MODE HERE..THINGS WONT PRINT
PWRCHK: CLRRM IOAD ;CLEAR A BUFFER..WE WILL GENERATE A "100000"
INX H ;CLRRM PASSES PNTR..WE MAKE IT "IOAD+1"
MVI M,^O200 ;SET BIT THAT MAKES IT "100000"
CALL EI1 ;GO EXAMINE I/O ADDRESS
INTOFF ;CLEAR INTERNAL MODE
SYSUP: MVI C,150. ;NOW DO AN AUTO BOOT SEQUENCE
SYSUP1: LXI H,25. ;WILL DO A DELAY LOOP
CALL LTLOOP ; BY HAND, BY-PASSING USUAL MACRO GENERATION
LDA RPEND ;SEE IF A CHAR WAS TYPED TO END THE AUTO BOOT
ANA A ;SET CONDITION FLAGS
JNZ REINI ;IF A CHAR WAS TYPED, NO AUTO STUFF, GO NULL JOB
;WHILE WE HAVEN'T GOT ANYTHING TO DO, MIGHT AS WELL CHECK BOOT SWITCH
;TO SEE IF THAT GOT PUSHED WHILE WE WERE SITTING HERE
IN BOOTSW ;***** I/O RD/301 *****
ANI 2 ;"BOOT" BUTTON PUSHED IS "TRUE .LO."
JZ N0.5 ;THEREFORE, IF RESULTS .EQ. Z-BIT, THEN BUTTON PUSHED
IN ^O102 ;READ AND SEE IF "AC PWR LO" HAPPENED
ANI ^O100 ;CHECK THE RESET SIGNAL
JZ 0000 ;ITS TRUE .LO., SO IF TRUE, RESTART THE MACHINE
;FALL THROUGH IF NO BOOT BUTTON PUSHED
DCR C ;STILL TIMING OUT.. WAIT LONGER
JNZ SYSUP1 ;BACK WHILE WAITING
;NOW SEE IF NEED AUTO BOOT, OR POWER FAIL RECOVERY..
LDA EMBUF+2 ;FETCH UP BITS 12-19
ANI ^O200 ;CHECK THE PWR SAVED BIT
JZ PWR.FAIL ;IF BIT SET, GO TRY A POWER FAIL RECOVERY
;FELL THROUGH IF THIS MUST BE AN AUTO BOOT SEQUENCE
PLINE AUTOMS ;SAY "BT AUTO"
CALL BTAUT ;CALL THE BOOT
.SBTTL **BEGINNING OF BASIC CONSOLE NULL JOB... BEGINS WITH A PROMPT
REINI: LXI SP,RAMST+^O2000 ;RESET STACK POINTER TO RE-INIT
CLRB EOL ;GUARANTEE END-OF-LINE CNTR RESET
CLRB ERRCD ;CLEAR CURRENT ERROR CODE
CLRB ERRCD+1 ;CLEAR CURRENT ERROR CODE
CLRB RPTON ;ALWAYS CLEAR THE REPEAT FLAG
CLRB NOPNT ;CLR THE "NO PRINT" FLAG
LXI H,RPINI ;GET POINTER TO BUFFER WHERE WE SAVE
SHLD RPLST ; THE COMMAND DISPATCH ADDRESSES.USED BY REPEAT
LXI H,REINI ;IF GOT HERE, SAFE TO GUARANTEE U ALWAYS GET HERE
SHLD NOREND ;PASS REINIT LOCATION TO THE NORMAL END DISPATCH
CALL BFRST ;RESET TTY INPUT BUFFER
EI ;MAKE SURE THAT BOMBS RESTORE THE INTERRUPTS
LDA USRMD ;GRAB USER MODE FLAG
ANA A ;SET CONDITION CODES
JNZ NULLJ ;IF USER MODE, NO PROMPTS, NO CR-LF, NOTHING
LDA MMFLG ;IF MM MODE WE WILL PRINT NO PROMPTS
ANA A ;SET 8080 FLAGS
JNZ NULLJ ;SKIP PROMPT IF MM
PCRLF ;START FRESH WITH CR-LF
PLINE KSPRMT ;PROMPT IS "KS10>"
;HERE BEGINS THE NULL STATE LOOP....
; CHECK FRONT PANEL BOOT SWITCH
NULLJ: LXI H,DCODE ;NULLJ JOB WILL PROCESS COMMANDS ON "END-OF-LINE"
NULLW: IN ^O102 ;READ AND SEE IF "AC PWR LO" HAPPENED
ANI ^O100 ;CHECK THE RESET SIGNAL
JZ 0000 ;ITS TRUE .LO., SO IF TRUE, RESTART THE MACHINE
IN ^O302 ;READ THE STATE OF THE KLINIK SWITCHES
CMA ;FIX THE HARDWARE INVERSION
MOV C,A ;SAVE RESULTS OF READ IN REG "C"
ANI ^O14 ;OFF ALL BUT THE 2 KLINIK BITS
RRC ;JUSTIFY "WORD-WISE"
MOV B,A ;SAVE THE KLINIK BITS FOR A SEC.
LDA KLNKSW ;GET THE CURRENT KLINIK SWITCH STATE
CMP B ;NOW SEE IF KLINIK SWITCH HAS CHANGED SINCE LAST TIME
PUSH H ;SAVE H,L IT HAS OUR DISPATCH ADDRESS
CNZ KLNKLT ;IF COMPARE WAS .NE. 0, THEN WE MUST CHANGE LIGHTS
POP H ;RETRIEVE H,L SO THAT WE HAVE THE REAL DISPATCH
;OK, NOW SEE IF WE ARE WATCHING CARRIER FROM THE KLINIK LINE,
;AND IF WE ARE, SEE IF IT HAS GONE AWAY.. IF KLINIK CARRIER GOES
;AWAY FOR 2 SECONDS, THEN WE WILL HANGUP THE LINE
MOV A,C ;GET STATE OF THE CARRIER INTO ACCUM
ANI 1 ;SEE IF IT IS SET
JZ N00 ;IF THERE IS NO CARRIER, THEN SEE IF WE CARE
;CARRIER WAS TRUE IF WE GOT HERE, SET FLAG SAYING THAT WE MUST WATCH
;IF IT DECIDES TO GO AWAY ON US
STA WATCHC ;SET FLAG SAYING WATCH THE KLINIK
JMP N0 ;AND PROCEED WITH THE NULL JOB
;GOT HERE IF CARRIER WAS FALSE, SEE IF WE CARE
N00: LDA WATCHC ;FETCH UP THE "WATCH" FLAG
ANA A ;SET FLAGS
JZ N0 ;WE DONT CARE, JUMP
;CARRIER WENT AWAY ON US. WAIT 2 SECONDS, IF STILL GONE, HANG EM UP
PUSH H ;BEST SAVE DISPATCHER TYPE ADDRESS
LONG.DELAY 2 ;WAIT 2 SECONDS
IN CARRIER ;***** I/O RD 302 *****
ANI 1 ;SEE IF TRUE(HIGH) OR FALSE(LOW)
CNZ HANGUP ;IT WAS STILL FALSE(I.E HIGH), HANGUP THE LINE
POP H ;NOW RESTORE
CLRB WATCHC ;AND SAY TO LEAVE THIS ALONE FOR A WHILE
;ELSE FALL THRU CAUSE ALL OK
N0: IN BOOTSW ;***** I/O READ 301 *****
ANI 2 ;IS BOOT SW SET???(TRUE LO, BECAUSE OF INVERSION)
JNZ N1 ;SKIP NEXT INSTR IF FALSE(I.E HIGH)
N0.5: CALL BOOT ;OTHERWISE...GO TO BOOT COMMAND
JMP NULLJ ;AFTER BOOT, ALL TTY INPUT WAITS ARE KILLED
;CONTINUE NULL STATE STATUS CHECK
; CHECK FOR SYSTEM PARITY ERRORS
N1: IN BOOTSW ;***** I/O RD 301 *****
ANI ^O10 ;IS PARITY ERR SIGNAL SET(TRUE .LO.)
JNZ NX2 ;SKIP NEXT INSTR IF NOT SET
;IF YES SET, MUST CHECK THE PARITY ERROR
LDA CHKPAR ;GET FLAG TO SEE IF SHOULD REPORT PARITY ERRORS
ANA A ;SET FLAGS
JNZ RPTPAR ;IF NOT ZERO, MUST GO REPORT PARITY ERROR
JMP N2 ;AND CONTINUE ELSE
NX2: CMA ;IF HERE, SET ACCUM .EQ. -1
STA CHKPAR ;AND SET FLAG TO SAY REPORT PARITY ERR
;CONTINUE NULL STATE STATUS CHECKS
; CHECK TO SEE IF RUN FLOP HAS DIED
N2: IN RUNFP ;;***** I/O READ 300Q *****
ANI ^O10 ;IS HALT LOOP SET??(TRUE .LO.)
JNZ NX3 ;SKIP NEXT INSTR IF NOT SET(CPU MUST BE "RUNNING")
;FALL THRU IF HALT LOOP SET..
LDA CHKHLT ;GET THE FLAG THAT SAYS IF WE SHLD CHK HALT
ANA A ;SET CONDITION CODES
PUSH PSW ;SAVE FLAGS FOR LATER USE
CNZ HLTCM ;IF FLAG SET, GO REPORT THE HALT
POP PSW ;GET FLAGS BACK
JNZ CHKKA ;IF YOU JUST HALTED, GO SEE IF RELOAD REQUEST
JMP N3 ;IF CLR, NO NEED TO REPORT..THEY KNOW
;THIS AND THE "CONTINUE" CODE IS THE ONLY CODE
;IN THE CONSOLE THAT SETS THE "CHECK HALT" FLAG..
;AND U CAN ONLY GET HERE IF THE "HALT LOOP" FLAG HAS BEEN CLEARED, BY
;ANY MEANS..AND WHEN U GET HERE, THE ACCUM MUST BE ZERO
NX3: CMA ;SET ACCUM = -1
STA CHKHLT ;AND ZAP THE CHECK HALT FLAG..
;CONTINUE NULL STATE STATUS CHECKS
;CHECK TO SEE IF MOS MEMORY REFRESH CYCLE HAS DIED
N3: IN REFERR ;READ REFRESH ERROR BIT
ANI 01 ;REFRESH ERROR TRUE??(TRUE .LO.)
JNZ NX4 ;SKIP FOLLOWING CODE IF NO REFRESH ERROR
;FALL INTO THIS IF A REFRESH ERROR OCCURS
LDA CHKREF ;GET FLAG THAT SAYS CHECK REFRESH ..SEE IF SHOULD BE REPORTED
ANA A ;SET 8080 FLAGS
PUSH H ;SAVE DISPATCHING ADDRESS
CNZ NOREFRESH ;GO REPORT REFRESH ERROR IF NECESSARY
POP H ;RESTORE DISPATCH ADDRESS
JMP N4 ;AND CONTINUE AS IF NOTHING HAPPENED
;THIS IS THE ONLY CODE THAT CAN SET THE "REPORT REFRESH ERROR FLAG"
NX4: CMA ;U GOT HERE ON A JZ, SO ACCUM MUST BE ZERO
STA CHKREF ;AND SET FLAG TO -1
;CONTINUE NULL STATE STATUS CHECK
; CHECK FOR "END-OF-LINE" OR A RUNNING 10'S "KEEP-ALIVE"
N4: LDA USRMD ;IS THIS USER MODE?
ANA A ;SET CONDITION FLAGS
JNZ LIVE10 ;IF YES, CHECK 10 INTERRUPTS & KEEP ALIVE
;BEFORE DOING ANOTHER COMMAND. SEE IF WE ARE ENVELOPING AND MUST SEND
;OUT A PACKET
LDA CSLMODE ;ONLY DO ENVELOPE STUFF IF IN MODE 4 OR GREATER
CPI .MODE4 ;CHECK IF MODE 4
JNZ EOL.LK ;NOT MODE 4, PROCEED AS NORMAL
PUSH H ;SAVE H,L IT HAS THE DISPATCH ADDRESS
CALL DECNET ;IF SOMETHING THERE, SEND IT OUT
POP H ;NEED H,L AGAIN
;OTHERWISE, CTY'S EOL FLAG
;BUT FIRST SEE IF THIS IS A REPEAT
EOL.LK: LDA RPTON ;GET THE REPEAT FLAG
ANA A ;SET THE PROCESSOR FLAGS
JNZ RPTRTN ;GO BACK TO THE REPEAT FUNCTION SO THAT HE CAN PROCEED
LDA EOL ;GET VALUE OF EOL FLAG
ORA A ;SET FLAGS..IS EOL SET??
JZ NULLW ;REMAIN IN NULL JOB LOOP IF NOT SET
;ELSE GO PROCESS A COMMAND
PCHL ;RETURN TO COMMAND IN TTY INPUT, OR DECODE
.SBTTL **TYPEIN COMMAND DECODER AND DISPATCHER**
DCODE: XRA A ;ZERO OUT THE ACCUM
MOV B,A ;AND ZERO OUT TMP LOCATION
LXI D,CMDLST ;"D,E" NOW POINTS TO COMMAND LIST CHARACTER PAIRS
LHLD FIRST ;"H,L" NOW POINTS TO FIRST CHARACTER TYPED AS COMMAND
CALL FNDARG ;FIRST GO CLR ANY LEADING SPACES OR TABS FROM COMMAND LINE
JC NORML ;IF AT END-OF-COMMAND, ITS A NULL COMMAND
;NOW BEGINS COMMAND LOOK UP LOOP... "H,L" POINTS TO FIRST COMMAND CHAR.
;WHILE "D,E" POINTS TO FIRST CHAR IN THE LIST OF ALLOWABLE COMMANDS
DCODL: LDAX D ;CMD LIST CHAR TO ACCUM
ORA A ;IS THIS A ZERO BYTE??
JZ NXMDC ;IF YES,END OF LIST
INX D ;WHILE YOU R AT IT UPDAT CMD LIST PNTR
CMP M ;COMPARE CMD LIST CHAR WITH TYPED CHAR.
JZ MTCH1 ;IF THEY MATCH, BR TO "MTCH1"
;HERE IF NO MATCH..UPDATE CMD LIST PNTR TO START OF NEXT COMMAND,
;THEN CHECK IF TRIED ENTIRE LIST YET..
;IF TRIED ENTIRE LIST, REPORT COMMAND ERROR AND BACK TO NULL JOB LOOP.
;IF NOT TRIED ENTIRE LIST YET, LOOP BACK AND TRY SOME MORE
MISS2: INX D ;BUMP PNTR PAST SECOND CHAR OF CMD
INX D ;BUMP PAST THE DISPATCH ADDR
INX D
INR B ;UPDATE NUMBER OF "TRIES"
JMP DCODL ;IF NOT, JUMP BACK AND TRY AGAIN
;IF FALL TO HERE, WAS ILLEGAL COMMAND.. CLEAR REST
;UP TO EOL... TYPE ERROR MESSSAGE AND BACK TO NULL JOB LOOP
;FIRST STEP IS CLEARING BAD COMMAND FROM COMMAND BUFFER
NXMDC: PLINE CMDNG ;COMMAND NO GOOD
JMP MMERR ;AND BACK TO PROMPT..
.SBTTL ****CTY SERVICE****
;CODE ENTERED FROM THE NULL JOB LOOP WHENEVER WE ARE IN USER MODE(MODE 3)
;CODE CHECKS TO SEE IF CHAR IS AVAILABLE FROM THE 10,& ALSO IF KEEP ALIVE
;COUNT IS ACTIVE. WE ALSO CHECK FOR REBOOT REQUESTS (AS IN 20 SYSTEM MONITOR'S
;"BUGHALTS")
LIVE10: IN SMSTS ;SEE IF INTERRUPT FROM THE 10 IS PENDING
ANA A ;SET CONDITION CODES
PUSH PSW ;SAVE FLAGS FOR A LITTLE BIT
CP CHRRDY ;IF PLUS, A CHARACTER IS READY, GO PROCESS
;FIRST, WE ONLY WANT TO CHECK THE KEEP-ALIVE COUNTER EVERY SECOND.
;FIRST WE WILL CHECK OUR COUNTERS AND SEE IF TIME TO CHECK KEEP-ALIVE DATA
POP PSW ;GET FLAGS BACK
CP FAKLIT ;IF TYPED A CHAR, THEN DOWN COUNT FOR TIME WASTED
JZ CHKKA ;IF ZERO, DO WHAT MUST BE DONE
CALL DTIME ;ALWAYS DO IT AT LEAST ONCE
JNZ NULLJ ;IF NOT ZERO, IT HASN'T BEEN A SECOND YET. BACK NULL
;WHEN YOU FALL TO HERE, IT IS TIME TO CHECK FOR "KEEP-ALIVE" OR "RELOAD"
CHKKA: LXI H,KPAINI ;FIRST WE MUST RESET OUR MAJOR LOOP COUNTER
SHLD KATIM1 ;EACH NUM IN THIS LOC .EQ. .444 SECONDS BETWEEN CHECKS
INTON ;DON'T PRINT THIS CRUD
DI ;NO INTERRUPTS
EXAM 31 ;MOS MEMORY LOC 31 HAS THE INFORMATION
EI ;OK..INTERRUPTS
INTOFF ;INTERNAL MODE OFF NOW
LDA EMBUF+3 ;GRAB THE RELOAD BITS.. WE CERTAINLY NEED THOSE
RAL ;"FORCED RELOAD" SHIFT INTO CARRY
JC FRELOAD ;IF "RELOAD" SET, GO EXECUTE A RELOAD
;NOW SEE IF KEEP-ALIVE ACTIVE
RAL ;"KEEP-ALIVE" BIT INTO THE C-BIT
JNC NULLJ ;IF ITS NOT SET, GO BACK TO NULL JOB
;KEEPING A WATCH ON THE KEEP ALIVE COUNT...BLINKY LIGHTS
LDA STATE ;GET CURRENT STATE OF THE LIGHTS
MOV D,A ;SAVE IT JUST FOR A LITTLE BIT
ANI STMSK ;CLR THE "STATE" LIGHT FROM THE CURRENT SELECTIONS
MOV E,A ;AND NOW SAVE THIS LITTLE BIT IN A REGISTER
MOV A,D ;GET BACK THE ORIGINAL "STATE"
CMA ;"BLINK"
ANI STBIT ;ONLY WANT TO BLINK THE SINGLE LIGHT
ORA E ;THROW IN THE PART THAT IS AS WAS..
STA STATE ;PUT THE WHOLE MESS BACK, THE NULL LOOP WILL BLINKY
OUT LIGHTS ;BLINK THE LIGHTS HERE
JM NULLJ ;AND IF MINUS, WE ARE "SHUTING DOWN", LET LIGHTS GO
;WE DID AN EXAM 31 A VERY SHORT TIME AGO, SO THE EXAMINE BUFFER SHOULD STILL
;HAVE A VALID "KEEP-ALIVE" UPDATE COUNT IN IT
LXI H,KACNTR ;GET POINTER TO THE PREVIOUS "KA" COUNT
LDA EMBUF+1 ;GET WHAT SHOULD BE AN UPDATED "KA" COUNT
CMP M ;COMPARE..BETTER BE DIFFERENT
JZ DIEING ;IF SAME, GO SEE IF CPU IS REALLY DIEING
;FALL THRU IF THE COUNTS WERE DIFF..SAVE THE NEW COUNT
MOV M,A ;NEW COUNT GOES TO RAM, OVERWRITES THE OLD
CLRB DIECNT ;CLEAR THAT DIE COUNT
JMP NULLJ ;BACK TO THE NULL LOOP
;ROUTINE FOR WHEN DOING CTY OUT PUT THE LIGHTS STILL BLINK AT A REASONABLE
;RATE
FAKLIT: LHLD KATIM1 ;GET CURRENT COUNT FOR BETWEEN THE LIGHTS
MOV A,L ;GET LO ORDER PIECE
ANI ^O374 ;TWEEK LITE COUNT, CAUSE OUR TYPING MESSED UP TIMER LOOP
MOV L,A ;PUT LO ORDER PIECE BACK(MASKING .EQV. TO SUBTRACT 100)
JMP DTM1 ;AND PROCEED
;ROUTINE TO DOWN COUNT KEEP ALIVE COUNTER
DTIME: LHLD KATIM1 ;GET A 16-BIT MINOR LOOP COUNTER
DCX H ;DECREMENT THE COUNTER
DTM1: SHLD KATIM1 ;AND PUT IT BACK
MOV A,L ;NOW CHECK THE COUNT FOR .EQ. 0
ORA H ;"OR" HI PIECE WITH THE "LO" PIECE
RET
;ROUTINE TO ENTERED WHEN THE "FORCE RELOAD" BIT HAS BEEN SET BY A RUNNING
;PROGRAM IN THE KS10
FRELOAD: CLRB NOPNT ;CLEAR THE NO PRINT FLAG
PLINE FRCMSG ;PRINT MESSAGE TO INDICATE THE FORCED RELOAD
MVI A,2 ;BIT 34 IS THE APPROPRIATE GUY ON A FORCED RELOAD
STA GOCODE ;SET BIT IN THE 8080 RAM BUFFER
IN RUNFP ;NOW SEE IF WE MUST HALT THE PROCESSOR
ANI ^O10 ;WE DID NOT INVERT SIGNAL.0=HALTED, 1=RUNNING
INTON ;DONT PRINT WHAT HAPPENS TO THE HALT
CNZ HACMD ;MAKE SURE THE PROCESSOR IS STOPPED
INTOFF ;OK TO PRINT NOW
LDA SECRET ;SECRET LOCATION
ANA A ;SET 8080 FLAGS
JNZ REINI ;IF FLAG SET, WE WILL NOT DO AUTO RELOADS
LXI D,^O1004 ;POINTER TO THE MONITOR PRE-BOOT
CALL FILEINIT ;GO READ IN THE MONITOR PRE-BOOT
JC L.BTERR ;IF ERROR, FATAL OUT
LXI H,1 ;NO ERR, NOW GO START THE MICRO-CODE AT LOC 1
CALL SM1.5 ;START MICROCODE, ADDRESS PASSED IN H,L
LONG.DELAY 2 ;GUARANTEE THAT THE "SM 1" HAS TIME TO FINISH
CALL BT.GO1 ;NOW FIX PARITY AND OTHER THINGS THAT WE BROKE
CALL INFOBT ;AND PASS THE SOURCE OF THE PRE-BOOT IN MOS MEM
CALL LB.GO1 ;AND GO EXECUTE THE BOOT CODE
JMP NULLJ ;AND BACK TO NULL JOB
DIEING: LXI H,DIECNT ;GET THE NUMBER OF CONSECUTIVE "NO CHANGES" IN KA CNT
INR M ;INCREMENT
MOV A,M ;GET COUNT INTO ACCUM
CPI KATIMX ;NOW SEE IF OFFICIAL DEATH
JM NULLJ ;IF NOT YET, GO BACK AND WAIT FOR MORE
;ELSE, FALL ON THROUGH TO THE RELOAD CODE
;ROUTINE ENTERED WHEN THE "KEEP-ALIVE" COUNT DOES NOT CHANGE, AND WE
;ISSUE A RELOAD BECAUSE WE BELIEVE THAT THE PROGRAM RUNNING IN THE KS10
;HAS DIED
CLRB NOPNT ;CLEAR THE NO PRINT FLAG
CLRB DIECNT ;AND RESET THE DIE COUNT
PLINE KAMSG ;PRINT MESSAGE TO INDICATE KEEP-ALIVE FAILURE
INTON ;DONT PRINT ANY OF THIS STUFF
CALL HACMD ;FIRST, STOP THE MACHINE
DI ;NO INTERRUPTS, TILL THE EXAMINE IS COMPLETE
EXAM 71 ;EXAMINE THE INSTRUCTION IN 71
EI ;OK TO INTERRUPT NOW
MVI A,1 ;KEEP ALIVE CODE IS A 1
STA GOCODE ;SAVE FOR PASSING TO KS10
CALL EXINTM ;NOW GO EXECUTE LOC 71 IN PAGE 0 OF MONITOR SPACE
CALL COCMD ;LET THE PROCESSOR RESUME
INTOFF ;MAY RESUME PRINTING THIS STUFF
JMP NULLJ ;AND BACK TO NULL JOB
.SBTTL **COMMAND DECODER CONTINUED**
;CONTINUE COMMAND DECODER......
;HERE IF FIRST CHARACTER MATCHED.SEE IF SECOND CHAR MATCHED.
MTCH1: INX H ;INPUT BUFFER NOW PNTS TO SECOND CHAR TYPED
LDAX D ;ACCUM GETS SECOND "EXPECTED" CHAR FROM COMMAND LIST
CMP M ;NOW. DOES SECOND CHARACTER MATCH??
JZ MTCH2 ;JUMP IF YES, SECOND CHAR MATCHES.
;HERE IF SECOND CHARACTER DID NOT MATCH.RESET "H,L" & GO BACK TO TRY AGAIN
DCX H ;RESET "H,L"
JMP MISS2 ;AND CONTINUE PROCESSING
;GET TO HERE IF SECOND CHARACTER MATCHED
MTCH2: INX D ;UPDATE PAST 2ND CHAR
INX H ;UPDATE BUFFER POINTER
CALL SEPCHR ;GET RID OF SEPARATORS
;"H,L" SHOULD NOW POINTS TO THE CMD BUFF
;"D,E" NOW POINTS TO THE DISP ADDR
;OR ELSE TO "EOL" CHAR IF CMD HAS NO ARGS.. ANYTHING ELSE IS COMMAND ERROR
SHLD .ARG1 ;SAVE "H,L" POINTER TO FIRST ARG.
MOV A,B ;NOW LOAD ACCUM WITH NUMBER "TRIES" TO FIND MATCH
XCHG ;DISP POINTER NOW TO "H,L"
MOV E,M ;SET LOW ODER HALF OF "TABLE ENTRY" INTO "E"
INX H ;BUMP POINTER
MOV D,M ;SET HIGH ORDER HALF OF "TABLE ENTRY" INTO "D"
LXI H,NORML ;SET A RETURN VALUE
PUSH H ;AND PLACE ON STACK FOR RETURNS
;PIECE OF CODE TO SAVE EACH COMMAND DISPATCH ADDRESS IN THE RAM BUFFER
;SO THAT THE REPEAT FUNCTION CAN DISPATCH THRU THE LIST WITHOUT DECODING
;THE TYPED IN COMMAND STRING AGAIN..
ANA A ;CHECK IF THIS IS RP COMMAND..IF YES MUST
STA T80DT ;SAVE WHICH COMMAND IS BEING EXECUTED
JZ CMDGO ;JUMP SO THAT CMD LST BUFFER NO CHANGED
LDA CMDS.. ;SEE IF THIS IS THE FIRST COMMAND IN A LINE
ANA A ;SET FLAGS
CZ RPNEW ;IF IS THE FIRST COMMAND, RESET REPEAT BUFFER POINTERS
LHLD RPLST ;GET POINTER TO CURRENT FREE BUFFER LOCATION
MOV M,D ;SAVE HI ORDER PIECE OF DISPATCH ADDRESS
INX H ;UPDATE MEM POINTER
MOV M,E ;SAVE LO ORDER PIECE OF DISPATCH ADDRESS
INX H ;UPDATE POINTER TO FIRST FREE..
XRA A ;CLR ACCUM
CMA ;IN ORDER TO MAKE IT -1
MOV M,A ;SET -1 AS END-OF-LIST INDICATOR
SHLD RPLST ;AND RESTORE THE POINTER
;CONTINUE THE DISPATCH
CMDGO: XCHG ;SET "TABLE ENTRY" INTO "H,L"
;AND DISPATCH TO ACTUAL COMMAND CODE
CALL EOCML ;SET "C-BIT" TO SAY END-OF-LINE IF TRUE
PUSH PSW ;SAVE STATE OF PROCESSOR FLAGS
CNC REMARG ;IF NO C-BIT, CMD HAD ARG..MUST REMEMBER IT
;FINALLY SEE IF COMMAND REQUIRES AN ARG
JNC CMDGO9 ;IF REQUIRES NO ARG, GO GO GO
;FALL HERE IF COMMAND HAD NO ARG..SEE IF IT SHOULD HAVE HAD ONE
MOV A,H ;GET HI ORDER OF DISP ADDRESS
RAL ;SHIFT HI ORDER BIT (BIT15) INTO THE C-BIT
JC RRARG ;WELL IF SET, IT NEEDED ARG.. REPORT THAT HAD NONE
;ELSE ALL OK.. CLEAR BIT15 IF SET AND PROCEED
CMDGO9: MOV A,H ;HI ORDER TO ACCUM
ANI ^O177 ;CLEAR BIT 15 NO MATTER WHAT
MOV H,A ;PUT HI ORDER BACK
POP PSW ;GET THE PROCESSOR FLAGS BACK
PCHL ;ADDR TO PC TAKES THE DISPATCH
;ROUTINE TO REMEMBER IF COMMAND HAD AN ARG..USED BY REPEAT FUNCTION
REMARG: PUSH PSW ;SAVE FLAGS
LDA T80DT ;SEE IF THIS WAS A REPEAT, IN WHICH CASE, DO NOTHING
ANA A ;SET CPU FLAGS
JZ REMAR1 ;IF WAS RP, GET OUT
PUSH H ;AND SAVE DISPATCH ADDRESS
LHLD RPLST ;GET THIS DISPATCH FROM REPEAT LIST
DCX H ;BACK UP ADDR POINTER TO POINT
DCX H ; HI ORDER PIECE OF ADDRESS
MOV A,M ;NOW GET HI ORDER PIECE INTO ACCUM
ORI ^O200 ;ADD SIGN BIT TO REMEMBER ARG
MOV M,A ;NOW PUT IT BACK
POP H ;RESTORE DISPATCH ADDRESS
REMAR1: POP PSW ;AND RESTORE C-BIT FROM PREVIOUS "EOCML"
RET ;AND RETURN
;THIS IS "NORML", FOR NORMAL RETURNS.. IT SETS UP PREVIOUS POINTERS
;AND THEN GOES BACK TO PROMPT
NORML: LXI H,EOL ;GET PNTR TO COMMAND COUNT
MOV A,M ;COPY TO ACCUM
DCR A ;DECREMENT IT
MOV M,A ;PUT BACK WHERE U GOT IT
;IF COUNT WAS DOWN TO ZERO, THEN RESET IT
DCR A ;IF COUNT WAS ZERO, THIS MAKES IT NEGATIVE
JM NORDIS ;IF EOL HAS GONE MINUS, TAKE NORMAL DISPATCH
CALL FXNXT ;OTHER WISE BE CLEVER & CRYPTIC
CLRB ERRCD ;AND CLEAR ERROR CODE
LXI H,DCODE ;FIX H,L FOR NORMAL NULL JOB
JMP N1 ;AND FINALLY, ALL ELSE GOES TO NULL LOOP
FXNXT: LHLD .ARG1 ;GET CMD PNTR
INX H ;UPDATE IT PAST THE CURRENT EOL CHAR(, OR CR-LF)
SHLD FIRST ;FIX CURRENT CMD LINE PNTR
RET ;AND THATS ENOUGH FOR NOW
;CODE FOR BUFFER OVER FLOW
BFOVR: PLINE BV ;"BUFFER OVERFLOW
NORDIS: LHLD NOREND ;GET THE CURRENT DISPATCH ADDRESS FOR NORMAL ENDS
PCHL ;AND GO
;SUBROUTINE TO PRINT A SINGLE CHARACTER..
;CHARACTER TO BE PRINTED IS PASSED IN THE ACCUM..
;IF THE UART SHOULD FAIL AND NEVER REACH THE TRANSMITTER READY STAT
;THE 8080 WILL HANG IN THIS LOOP FOREVER TRYING TO PRINT
PCHR: PUSH PSW ;SAVE CHARACTER ON THE STACK
LDA NOPNT ;GET NO PRINT FLAG
ORA A ;IS IT SET??
JZ PCHR0 ;IF NOT CONTINUE AS NORMAL
POP PSW ;IF IT IS..NO PRINTING
RET ;SO RETURN
PCHR0: LDA CSLMODE ;GET CURRENT KLINIK LINE MODE
CPI .MODE4 ;IS THIS APT MODE??
JNZ PCHR1 ;IF NO, PRINT
;HERE IF DOING APT AND MUST MERELY STACK CHARS TO BE ENVELOPED AND SENT OUT
;A LITTLE LATER. THE CHARACTER TO BE STACKED IS SITTING ON THE TOP OF THE
;STACK
POP PSW ;NOW GET THE CHARACTER THAT WAS STACKED
PUSH H ;MUST SAVE H,L IN HERE
LHLD ENVPNT ;GET THE POINTER TO THE ENVELOPE
MOV M,A ;PUT CHARACTER INTO THE BUFFER
INX H ;UPDATE THE POINTER
MVI M,0 ;GUARANTEE LAST BYTE IS A ZERO
SHLD ENVPNT ;PUT IT BACK WHERE U GOT IT
POP H ;AND RESTORE REG
CPI CRCHR ;IF WE ARE BUFFERING A CR, MUST SET THE FLAG
RNZ ;IF NOT A CR, JUST LEAVE
STA MAILFG ;ELSE SET THE FLAG
RET ;AND OUT
PCHR1Z: PUSH PSW ;CHAR ON STACK FOR A BIT
PCHR1: IN CTYCTL ;GET UART STATUS
ANI 01 ;CHECK BITS TO SEE IS XMITTER READY??
JZ PCHR1 ;JUMP BACK IF NOT READY YET
;NOW,BEFORE PRINTING, SEE IF NEED TO TYPE TO KLINIK LINE TOO.
LDA CSLMODE ;GET CURRENT KLINIK LINE MODE
CPI .MODE3 ;KLINIK IN PARALLEL MODE??
JNZ PCHROV ;IF NOT, JUST GO PRINT
;FALL THROUGH IF NEED KLINIK TOO
PCHR2: IN REMCTL ;GET KLINIK UART STATUS
ANI 01 ;CHECK THE READY BIT
JZ PCHR2 ;IF NOT READY, GO BACK AND TRY AGAIN
POP PSW ;GET CHAR OFF STACK WHEN THINGS ARE READY
OUT REMDAT ;PRINT CHAR ON THE KLINIK LINE
OUT CTYDAT ;PRINT ON CTY
RET ;AND BACK TO CALLER
PCHROV: POP PSW ;FINALLY READY..GET CHAR FROM STACK
OUT CTYDAT ;SEND CHARACTER
RET ;AND RETURN
;SUBROUTINE KCHR. FOR PRINTING A SINGLE CHARACTER ON THE KLINIK LINE ONLY
;PARTICULARLY USEFUL FOR THE "?NA" AND "PW:" MESSAGES
;CHARACTER TO BE PRINTED CAN BE A TRAILING ARG, OR YOU CAN CALL THIS ROUTINE
;IN THE MIDDLE AND PASS THE CHAR TO BE PRINTED IN THE ACCUM
KCHR: XTHL ;SWAP STACK TOP WITH H,L
MOV A,M ;GET THE TRAILING ARG FROM PROM
INX H ;UPDATE RETURN ADDRESS PAST THE TRAILING ARG
XTHL ;PUT THE RETURN BACK ON THE STACK
KCHR0: PUSH PSW ;SAVE THE CHARACTER JUST FOR A LITTLE BIT
KCHR1: IN REMCTL ;GET KLINIK UART STATUS
ANI 01 ;SEE IF UART IS READY
JZ KCHR1 ;LOOP TILL IT IS
POP PSW ;READY NOW, GET THE CHAR OFF THE STACK
OUT REMDAT ;SEND TO UART
RET ;AND BACK TO CALLER
;SUBROUTINE KLINE. FOR PRINTING A LINE OF CHARACTERS. A TRAILING ARG
;POINTING TO THE STRING TO BE PRINTED IS USED. "\" MEANS <CR-LF>.
KLINE: XTHL ;SWAP STACK, GET POINTER TO TRAILING ARG TO H,L
CALL TARG1 ;GET POINTER TO ARG INTO D,E
XTHL ;FIX RETURN ADDRESS
KLINE1: LDAX D ;GET FIRST CHAR INTO ACCUM
INX D ;UPDATE THE CHARACTER POINTER
ANA A ;WELL THEN, SEE IF CHAR IS 0, MEANING END OF STRING
RZ ;OUT IF YES
;WELL THEN , MIGHT AS WELL GO PRINT THE THING
CALL KCHR0 ;GO PRINT THE CHARACTER
JMP KLINE1 ;AND WHEN RETURN, GO FETCH UP THE NEXT CHAR
;SUBROUTINE TO PRINT A LINE OF CHARACTERS..
;POINTER TO THE LINE OF CHARACTERS TO BE PRINTED IS PASSED IN
;"H,L" REGISTER..NO REGISTERS ARE DESTROYED BY THIS ROUTINE
;THE END-OF-MESSAGE FOR THE LINE OF CHARACTERS TO BE
;PRINTED IS INDICATED BY A "00" BYTE AT THE END OF THE MESSAGE TEXT
PLNE: XTHL ;REPLACE RETURN..PUT ON STACK
XCHG ;TRAILING ARG FROM "D,E" TO "H,L"
PLN1: MOV A,M ;GET CHARACTER FROM MEM.
INX H ;INCREMENT TO NEXT CHARACTER TO BE PRINTED
CPI BSLASH ;IS THIS A BACK SLASH(I.E. IN-LINE CRLF)
JZ PLN2 ;JUMP IF YES...
ORA A ;IS IT A "00" BYTE???
RZ ;RETURN IF DONE
;FALL HERE IF GOTTA REAL CHAR..
CALL PCHR ;GO PRINT CHAR IN ACCUM
PLN2: CZ CRLFIN ;GET HERE ON ZERO FLAG,ONLY IF NEED CRLF
JMP PLN1 ;CONTINUE LOOP
;SUBROUTINE TO PRINT A CARRIAGE RETURN-LINE FEED
;NO REGISTERS DESTROYED..JUST CALL TO GET YOUR
;<CR><LF> PRINTED
.CRLF: POP H ;MUST FIX THE STACK
CRLFIN: PCHAR CRCHR ;PRINT CARRIAGE RETURN
PCHAR LFCHR ;PRINT LINE FEED
RET ;RETURN
.SBTTL **COMMAND DISPATCH LIST**
;THIS LIST CONTAINS ALL CHARACTER PAIRS WHICH ARE CONSIDERED
;LEGITIMATE COMMANDS TO THE KS10 CONSOLE
CMDLST:
.BYTE 'R,'P ;*REPEAT IN FAST LOOP*
.ADDR RPCMD
.BYTE 'D,'N ;*DEPOSIT NEXT*
.ADDR BIT15!DNCMD
.BYTE 'D,'C ;*DEPOSIT CRAM*
.ADDR BIT15!DCCMD
.BYTE 'D,'M ;*DEPOSIT MEMORY*
.ADDR BIT15!DMCMD
.BYTE 'L,'C ;*LOAD CRAM ADDRESS*
.ADDR BIT15!LCCMD
.BYTE 'L,'A ;*LOAD MEMORY ADDRESS*
.ADDR BIT15!LACMD
.BYTE 'D,'I ;*DEPOSIT I/O*
.ADDR BIT15!DICMD
.BYTE 'L,'I ;*LOAD I/O ADDRESS*
.ADDR BIT15!LICMD
.BYTE 'D,'B ;*DEPOSIT BUS*
.ADDR DBCMD
.BYTE 'D,'K ;*DEPOSIT KONSOLE*
.ADDR BIT15!DKCMD
.BYTE 'L,'K ;*LOAD ADR FOR KONSOLE*
.ADDR BIT15!LKCMD
.BYTE 'E,'K ;*EXAMINE KONSOLE*
.ADDR EKCMD
.BYTE 'L,'F ;LOAD DIAG FUNCTION
.ADDR BIT15!LFCMD
.BYTE 'D,'F ;DEPOSIT INTO DIAG FUNCTION
.ADDR BIT15!DFCMD
.BYTE 'M,'K ;*MARK MICRO-CODE*
.ADDR BIT15!MKCMD
.BYTE 'U,'M ;*UNMARK MICRO-CODE*
.ADDR BIT15!UMCMD
.BYTE 'P,'E ;*PARITY ENABLE*
.ADDR PECMD
.BYTE 'C,'E ;*CACHE ENABLE*
.ADDR CECMD
.BYTE 'T,'E ;*1 MSEC CLOCK ENABLE*
.ADDR TECMD
.BYTE 'T,'P ;*TRAP ENABLE*
.ADDR TPCMD
.BYTE 'S,'T ;*START*
.ADDR BIT15!STCMD
.BYTE 'H,'A ;*HALT*
.ADDR HACMD
.BYTE 'C,'O ;*CONTINUE*
.ADDR COCMD
.BYTE 'S,'I ;*SINGLE INSTRUCT*
.ADDR SICMD
.BYTE 'S,'M ;*START MICRO-CODE*
.ADDR SMCMD
.BYTE 'M,'R ;*MASTER RESET*
.ADDR MRCMD
.BYTE 'C,'S ;*START CPU CLOCK*
.ADDR CSCMD
.BYTE 'C,'H ;*HALT CPU CLOCK*
.ADDR CHCMD
.BYTE 'C,'P ;*PULSE CPU CLOCK*
.ADDR CPCMD
.BYTE 'E,'N ;*EXAMINE NEXT*
.ADDR ENCMD
.BYTE 'E,'M ;*EXAMINE MEMORY*
.ADDR EMCMD
.BYTE 'E,'I ;*EXAMINE I/O*
.ADDR EICMD
.BYTE 'E,'C ;*EXAMINE CRAM*
.ADDR ECCMD
.BYTE 'E,'B ;*EXAMINE BUS*
.ADDR EBCMD
.BYTE 'E,'J ;*EXAMINE CURRENT CRAM INFO*
.ADDR EJCMD
.BYTE 'T,'R ;*TRACE*
.ADDR TRCMD
.BYTE 'R,'C ;*FUNCTION READ CRAM CONTROL REG*
.ADDR RCCMD
.BYTE 'Z,'M ;*ZERO KS10 MOS MEMORY*
.ADDR ZMCMD
.BYTE 'P,'M ;*PULSE MICRO-CODE..*
.ADDR PMCMD
.BYTE 'B,'T ;*BOOT SYS*
.ADDR BTCMD
.BYTE 'B,'C ;*BOOT CHECK*
.ADDR BCCMD
.BYTE 'L,'B ;*LOAD BOOT*
.ADDR LBCMD
.BYTE 'E,'X ;*EXECUTE*
.ADDR BIT15!EXCMD
.BYTE 'L,'T ;*LAMP TEST*
.ADDR LTCMD
.BYTE 'K,'L ;*KLINIK*
.ADDR KLCMD
.BYTE 'E,'R ;*EXAMINE REGISTER*
.ADDR ERCMD
.BYTE 'L,'R ;*LOAD REGISTER*
.ADDR LRCMD
.BYTE 'D,'R ;*DEPOSIT REGISTER*
.ADDR DRCMD
.BYTE 'M,'T ;*MAGTAPE BOOT*
.ADDR MTCMD
.BYTE 'D,'S ;*DISK SELECT*
.ADDR DSCMD
.BYTE 'M,'S ;*MAGTAPE SELECT*
.ADDR MSCMD
.BYTE 'S,'H ;*SHUTDOWN*
.ADDR SHCMD
.BYTE 'M,'B ;*MAGTAPE BOOTSTRAP*
.ADDR MBCMD
.BYTE 'P,'W ;*PASSWORD*
.ADDR PWCMD
.BYTE 'T,'T ;*KLINIK LINE TO TTY*
.ADDR TTCMD
.BYTE 'V,'T ;*VERIFY AGAINST TAPE*
.ADDR VTCMD
.BYTE 'V,'D ;*VERIFY AGAINST DISK*
.ADDR VDCMD
.BYTE 'X,'1 ;DUMMY
.ADDR RAMX1
.BYTE 'F,'I ;*FILE*
.ADDR BIT15!FICMD
.BYTE 'B,'2 ;**TEMP BOOTCHECK 2**
.ADDR B2CMD
.BYTE 'M,'M ;MANUFACTURING MODE
.ADDR MMCMD
.BYTE 'S,'C ;SOFT CRAM ERROR RECOVERY "ON/OFF" SWITCH
.ADDR SCCMD
.BYTE 0 ;END LIST MARKER
.SBTTL CHECKSUMS AS COMPUTED BY SPECIAL 10-BASED PROGRAM
.IF DF,PASS1
CHECKS: .ADDR 0 ;PSUEDO BYTES FOR RAM NUMBER 1
.ADDR 0 ;PSUEDO BYTES FOR RAM NUMBER 2
.ADDR 0 ;PSUEDO BYTES FOR RAM NUMBER 3
.ADDR 0 ;PSUEDO BYTES FOR RAM NUMBER 4
.ENDC
.IF DF,PASS2
CHECKS: .ADDR CHKSM0 ;CHECKSUM FOR RAM NUMBER 1
.ADDR CHKSM1 ;CHECKSUM FOR RAM NUMBER 2
.ADDR CHKSM2 ;CHECKSUM FOR RAM NUMBER 3
.ADDR CHKSM3 ;CHECKSUM FOR RAM NUMBER 4
.ENDC
.TITLE VER 4.2 KS10 CONSOLE PROGRAM
INIMS: .ASCIZ /\KS10 CSL.V4.2\/ ;POWER UP MESSAGE AND IDENTIFIER
.SBTTL *** "MR" CMD ***
;THIS CODE PERFORMS THE "MASTER RESET" CONSOLE FUNCTION
MRCMD:
XRA A ;SET ACCUM=0
OUT CPUCTL ;SET 0'S TO "RUN,EXECUTE,CONT"
CALL CHCMD ;AND INSURE CPU HAS STOPPED...
;ISSUE SM10 BUS RESET
MRINT: MVI A,5 ;BITS FOR "DP RESET", & "CRAM RESET"
OUT CRMCTL ;***** I/O WRT 204/5 *****
MVI A,^B10000000 ;BIT7 FOR RESET
OUT RESET ;ISSUE RESET,SET CONSOLE MODE
CALL SMFINI ;GET CURRENT PARITY SETTINGS & SET IN KS
LDA TRAPEN ;BIT FOR "CLR TEN INT" SHOULD BE LOW
OUT DIAG ;***** I/O WRT 205/XX *****
MVI B,0 ;WILL SET NO BITS IN THE STATE WORD
CALL STATEM ;SET THE STATE
.BYTE ^O12 ;OFF THE STUFF WE DONT WANT
ENDCMD ;AND OUT
.SBTTL ****INTERRUPT HANDLER****
;HERE ON INTERRRUPTS..REGS ALREADY SAVED AT "RST" BLOCK
INTRP: LXI H,ENDIN ;PUSH OUR FAVORITE EXIT ADDRESS ON THE STACK
PUSH H ; AND WE CAN DO "RET"'S TO LEAVE ROUTINE
IN CTYCTL ;GET CTY TTY STATUS
MOV B,A ;SAVE IT IN THE "B" REG FOR A COUPLE INSTRS
IN REMCTL ;NOW FETCH UP THE REMOTE STATUS
ORA B ;AND THROW BOTH STATUS'S TOGETHER
ANI ^O70 ;ANY ERR BITS SET??
JNZ TTERR ;GO TELL ERR IF YES
;FALL THROUGH IF NO ONE IN ERROR. NOW SEE WHO THE CHARACTER IS FROM
MOV A,B ;COPY CTY STATUS INTO ACCUM
ANI 2 ;IS A CHARACTER IN THE CTY UART??
JNZ INTCH ;JUMP IF YES. FIND CHARACTER IN CTY UART.
;FALL HERE IF IT WAS A KLINIK CHAR
IN REMDAT ;FETCH OUT THE CHARACTER
ANI ^O177 ;OFF THE PARITY BIT
MOV B,A ;MAKE SECOND COPY OF CHARACTER IN "B"
CPI CNTLY ;BEFORE DISPATCHING, SEE IF THIS IS "CONTROL-Y"
JNZ KL.DSP ;IF NOT, DO EVERYTHING AS PER NORMAL
;AHA. IT WAS A CONTROL-Y..NOW SEE IF IN MM MODE
LDA MMFLG ;GET FLAG
ANA A ;SET 8080 CONDITION CODES
JNZ MMERR1 ;IF YES, MM MODE, THEN GO ABORT WHAT EVER YOU ARE DOING
MOV A,B ;NOW REPLACE THE CHAR WE JUST BOMBED
;ELSE FALL THROUGH
KL.DSP: LHLD MODDIS ;GET CURRENT KLINIK MODE DISPATCH
PCHL ;DISPATCH TO DO THE RIGHT THING
;CHECK IF WE ARE IN USER MODE
INTCH: IN CTYDAT ;INPUT CHARACTER
ANI ^O177 ;STRIP BIT 8
MOV B,A ;SAVE CHAR FOR 2 INSTRUCTIONS
;SEE IF THIS IS MANUFACTURING MODE BEFORE WE CONTINUE
LDA CSLMODE ;GRAB CURRENT CSL MODE
ANI .MODE4 ;AND SEE IF ITS MODE 4
JZ CMNBUF ;IF NO, CTY INPUT NORMAL
;PLACE YOU GO IF MANUFACTURING MODE.. CTY CHARS ARE JUST SENT TO KLINIK
MOV A,B ;GRAB CHARACTER TO BE SENT TO KLINIK
CALL KCHR0 ;ONLY ECHO CTY STUFF AGAINST THE KLINIK LINE
;NOW SEE IF THAT WAS A MODE CHANGE CHAR WE JUST SENT DOWN THE LINE
CPI CNTLY ;IS IT "CONTROL-Y"
RNZ ;IF WAS NOT, SIMPLY GET OUT
CLRB KLNKSW ;FORCE RE-EXAMINE OF THINGS
CLRB MMFLG ;TURN OFF MANUFACTURING MODE
CALL SETM2 ;FORCE KLINIK LINE IMMEDIATELY INTO MODE 2
JMP REINI
;ALSO STANDARD COMMON ENTRY POINT WHEN KLINIK LINE PARALLELS THE CTY
MODE3:
CMNBUF: LDA USRMD ;GET USER MODE FLAG
ANA A ;IS IT SET??
MOV A,B ;COPY CHAR INTO ACCUM(GET HERE FOR KLINIK OR CTY)
JNZ USER ;JUMP IF IN USER MODE...
;FALL THRU TO HERE IF NOT USER MODE AND WE NEED DO SOMETHING WITH CHAR
CPI CNTLO ;CONTROL O???
JNZ SKP2 ;JMP IF NO
;ELSE FALL INTO CONTROL-O CODE..STOP THE PRINTER
PCHAR UPARR
PCHAR OCHR
LDA NOPNT ;GET CURRENT STATE OF "NO PRINT"
ADI ^O200 ;ZAP PRINT FLAG
STA NOPNT ;PUT IT BACK
XRA A ;ZAP CHAR SO WE CAN EARLY EXIT
SKP2: CPI CNTLS ;IS IT CONTROL-S
CZ CNTS ;CALL IF YES
CPI CNTLQ ;IS IT CONTROL-Q
JNZ SKP6 ;JMP IF NO
;FALL TO HERE IF YES, ZAPP CNTL-Q FLAG
CLRB STPPD ;ZAP!!
XRA A ;CLEAR ACCUM
SKP6: STA RPEND ;ANY OTHER CHARS MEAN END REPEAT LOOP
CPI CNTLZ ;CONTROL Z??
JZ CNTZ ;JMP IF YES
CPI CNTLU ;CONTROL-U??
JNZ SKP8 ;JMP IF NO
;FALL TO HERE TO DO THE CONTROL-U CODE
PCHAR UPARR
PCHAR UCHR
PCRLF ;AND A CR-LF TO GIVE CLEAN LINE
CALL BFRST ;CLEAR INPUT BUFFER
XRA A ;AND SET ACCUM FOR EARLY OUT
SKP8: CPI CNTLC ;CONTROL-C??
JZ CNTC ;JMP IF YES
CPI Q.OUT ;SEE IF MUST TAKE A QUICK OUT
RZ ;LEAVE IF YES
CPI COMMA ;IS IT A COMMA?
JNZ M11 ;IF NOT COMMA, AVOID THIS NEXT COUPLE INSTRUCTIONS
;FALL TO HERE IF WAS A COMMA
LXI H,CMCNT ;POINT TO THE COMMA COUNTER
INR M ;UPDATE.. AND CONTINUE
;NOT SPECIAL CHAR..PROCESS NORMAL
M11: CPI CNBCK ;CONTROL BACKSLASH SHOULD LOOK LIKE CRLF
CZ EOMRK ;CALL IF YES
CPI CRCHR ;CARRIAGE RET??
CZ EOMRK ;CALL IF YES
CPI LFCHR ;LINE FEED??
CZ EOMRK ;CALL IF YES
LHLD BUF. ;POINTER TO FIRST FREE BUFFER PLACE
CPI RBOUT ;RUB-OUT CHAR??
JZ RUB ;JMP IF YES
;OTHERWISE ITS A REGULAR CHAR..
;THIS IS DUMB CODE FOR FIRST GO AROUND
;TYPE-AHEAD WONT WORK
CALL UP.LO ;CONVERT SO PROGRAM INTERNAL ONLY SEES UPPER CASE
MOV M,A ;CHAR INTO BUFFER SPACE
INX H ;UPDATE PNTR
SHLD BUF. ;AND REPLACE PNTR
MOV B,A ;SAVE THE CHAR JUST TYPED
SUI ^O40 ;CHECK IF ITS A PRINTING CHAR
JM NOECH ;IF IT IS NONE-PNT..GO NO ECHO
MOV A,B ;GET CHAR BACK
SUI ^O176 ;IS IT TOO HI TO BE PRINTING CHAR??
JP NOECH ;IF YES, GO NO ECHO
MOV A,B ;GET CHAR BACK AGAIN
CALL PCHR ;NOW GO ECHO IT.....
NOECH: LDA BFCNT ;GET CHAR COUNT
INR A ;BUMP UP
CPI 80. ;TOO MANY??
JZ BFOVR ;JMP BUFFER OVERFLOW IF YES
STA BFCNT ;REPLACE COUNT
POP H ;CLEAR STACK OF THE PSEUDO RETURN FIRST
;FALL INTO END INTERRRUPT CODE IF CHAR COUNT OK
ENDIN: POP H ;RESTORE REGS
POP D
POP B
POP PSW
EI ;INTERRUPTS BACK ON
RET ;AND OUT
;AND ACCEPT LOWER CASE AS REQUESTED
UP.LO: CPI ^O141 ;LOW CASE "A" OR BETTER??
RM ;IF MINUS, NOT LOW CASE, CONTINUE
CPI ^O173 ;LOW CASE "Z" OR WORSE??
RP ;IF POS, OR ZERO, ITS NOT LOW CASE RANGE
;FALL INTO HERE IF IT WAS LOWER CASE....
SUI ^O40 ;MAKE IT UPPER FOR ALL
RET ;AND OUT
;CODE FOR END-OF-LINE CHAR TYPED IN
EOMRK: PCRLF ;GIVE CR-LF
LDA CMCNT ;GET COUNT OF COMMAS
INR A ;UP BY ONE, FOR THE CR-LF
STA EOL ;AND SET EOL MARKER
XRA A ;CLEAR ACCUM
STA CMCNT ;SET LOCATION
CMA ;SET ACCUM = -1
RET ;RETURN
;CODE FOR A RUB-OUT
RUB: LDA BFCNT ;GET CURRENT CHAR COUNT
ANA A ;IS IT 0??
RZ ;GOOD, NOTHING TO DELETE
DCR A ;DECREMENT OTHERWISE
STA BFCNT ;AND PUT IT BACK
DCX H ;AND BACK UP THE BUFFER PNTR
SHLD BUF. ;PUT IT BACK
PSLASH ;TYPE SLASH AS RUBOUT INDICATOR
MOV A,M ;GET CURRENT CHAR IN BUFFER
CALL PCHR ;ECHO WHAT WAS RUBBED OUT
CPI COMMA ;OH WAIT, WAS THAT A COMMA??
RNZ ;JMP IF NO, TAKE A NORMAL OUT
;FALL THRU IF WAS A COMMA
LXI H,CMCNT ;GET COMMA COUNT
DCR M ;DECREMENT
RET ;AN EXIT THIS PLACE
;HERE IF USER MODE FLAG IS SET..
USER: CPI CNBCK ;IS IT "^\"??
JNZ TENCHR ;IF NOT,THEN ITS A CHAR FOR THE KS-10
;BEFORE WE LEAVE USER MODE, WE MUST CHECK THE CONSOLE ENABLE SWITCH
END.USR: IN BOOTSW ;***** I/O RD 301 ***** IS CONSOLE LOCKED UP??
;BIT 2 IS "LO" IF CONSOLE ENABLE IS TRUE. IF BIT 2 IS "HI", WE ARE DISABLED
;DUE TO THE HARDWARE INVERSION OF SIGNAL LEVELS
ANI ^O4 ;CHECK BIT 2
RNZ ;IF HI, WE ARE DISABLED AND WILL IGNORE
;IF YES, USER MODE MUST BE CLEARED
CLRB NOPNT ;CLR NO PRINT FLAG IN CASE WE WERE IN "INTERNAL MODE"
CALL CLRUSE ;EXIT FROM USER MODE
PLINE RDYMS ;"ENABLED"
LXI H,REINI ;SET UP AN EXIT ADDRESS
IOUT: POP D ;CLEAR THE PSEUDO RETURN TO "ENDIN" FROM STACK
POP D ;CLEAR ORIGINAL SAVED "H,L" OFF STACK
POP D
POP B
POP PSW
INX SP ;NOW GET OLD RETURN ADDR OFF STACK
INX SP
EI ;ENABLE INTS..
PCHL ;AND GO TO PROMPT
RDYMS: .ASCIZ /ENABLED\/
CLRUSE: CLRB USRMD ;AND CLEAR THE USER MODE FLAG
LDA MMFLG ;BEFORE DROPPING USER, SEE IF IN MM MODE
ANA A ;SET 8080 FLAGS
RZ ;IF NOT MM MODE, OK TO GET OUT
;IF WAS SET, MUST DROP BACK TO MODE 4
CALL SETM4
CALL KCHR ;NON-PRINTING CHAR, ALSO TELLS HOST TO SWITCH MODES
.BYTE CNBCK ;"CONTROL-BACKSLASH IS THE MAGIC CHAR"
RET ;JUST LEAVE
;CONTROL-Z CODE...ENTER USER MODE
CNTZ: CALL SETUSE ;SET THE USER MODE
CALL BFRST ;BUFFER RESET..RE-INIT TTY INPUT BUFFER
CLRB KLNKSW ;FORCE LIGHTS TO GET FIXED AFTER ENTER USER
PLINE U ;PRINT "USER MODE"
LXI H,NULLJ ;LOAD "H,L" WITH A PLACE TO GO
JMP IOUT ;AND GET OUT
U: .ASCIZ /USR MOD\/
SETUSE:
;HERE IS THE DEPOSIT WORD 31 CODE..
WRD31: INTON ;DONT PRINT THIS STUFF
EXAM 31 ;MUST SAVE CURRENT STATE OF KEEP ALIVE & RELOAD BITS
INTOFF ;ITS OK NOW
LDA GOCODE ;BYTE 28-35 GETS THE REASON FOR RELOAD
LXI H,DMDAT ;MAKE H,L POINT TO THE DESIRED BUFFER
MOV M,A ;SET THE GOCODE BITS INTO THE BYTE "DMDAT"
LDA TRAPEN ;NOW GRAB THE TRAP BIT
RLC ;AND SHIFT IT TO THE APPROPRIATE POSITION(20 TO 40)
RLC ;(40 TO 100)
RLC ;(100 TO 200)
MOV B,A ;SAVE IT IN B FOR A WHILE
LDA MMFLG ;GET "MAINTENANCE MODE" FLAG
ANA A ;SET 8080 FLAGS
PUSH PSW ;SAVE THE STATE OF THE FLAGS FOR LATER USE
JZ WRD.PR ;IF NO MM MODE, DONT SET A BIT
;WAS MM MODE, MUST SET THE BIT
MVI A,^O100 ;A BIT FOR MM MODE
WRD.PR: ORA B ;THROW TOGETHER WITH THE TRAP BIT
INX H ;PUT INTO THE DEPOSIT BUFFER
INX H
MOV M,A ;THIS IS LOC "DMDAT+2"
LDA PARBT ;NOW FOR THE SELECTION OF PARITY BITS
RRC ;RIGHT ONCE TO FREE UP 200 WEIGHT
MOV B,A ;SAVE IN B REG
LDA CSLMODE ;GET CURRENT KLINIK MODE
ANI .MODE2!.MODE3 ;IF EITHER OF THESE MODES, MUST SET THE BIT
JZ WRD.DP ;JUMP IF NOT THOSE BITS
;HERE IF ONE OF THOSE MODES WAS SET
MVI A,^O100 ;A BIT TO SET
WRD.DP: ORA B ;THROW THIS BIT WITH THE OTHERS
RRC ;FINAL JUSTIFICATION
MOV B,A ;NOW SAVE THIS GOOD STUFF IN "B"
LDA EMBUF+3 ;GET THE BYTE THAT HAS CURRENT "KA" BIT
ANI ^O300 ;OFF EVERYTHING ELSE
ORA B ;NOW THROW WHOLE MESS TOGETHER AGAIN
INX H ;BUMP POINTER TO "DMDAT+3"
MOV M,A ;AND PUT DATA INTO RAM
DEPOS 31 ;PUT INTO MOS MEMORY AT LOC 31
CLRB GOCODE ;CLEAR THE RELOAD CODE
POP PSW ;THIS WORD HAS FLAGS SET FROM BEFORE WHEN WE TESTED "MM"
MVI A,-1 ;FLAGS WONT CHANGE WHILE WE SET THE USER MODE FLAG
STA USRMD ;SET USER MODE... NOW DO SOMETHING BASED ON THE FLAGS
RZ ;IF NOT SET, A SIMPLE OUT
;HERE IF SET, WE MUST SEND AN "ACK" DOWN KLINIK LINE BEFORE ANYTHING ELSE
CALL ACK ;"ACK" DOWN THE KLINIK
JMP SETM2 ;ALSO SET MODE 2 AND USE HIS "RET" TO RETURN
;TYPED "CONTROL-S" TO STOP CONSOLE OUTPUT
CNTS: LXI H,STPPD ;POINTER TO STOPPED FLAG
MOV A,M ;GET THE FLAG
CMA ;SET .EQ. 0 IF WAS ALREADY SET
ANA A ;NOW SET FLAGS, 'CAUSE CMA DOESN'T
RZ ;IF .EQ. 0 NOW, MERELY LEAVE..ALREADY SET
MOV M,A ;AND SET THE FLAG .EQ. -1 IF HERE
EI ;LET THE CNTL-Q THRU
CNTSL: MOV A,M ;GET FLAG STATUS
ANA A ;IS IT SET???
RZ ;IF NOT,THEN TIME TO QUIT
JMP CNTSL ;STAY IN LOOP IF FLAG STILL SET
.SBTTL **8080 TO KS10 CHARACTER SERVICE**
TENCHR: STA CHRBUF ;PUT CHARACTER IN A RAM BUFFER
MVI A,^O32 ;DESIRED ADDRESS FOR DEPOSTING CHARACTER
OUT A2835 ;WRITE ONLY RELEVANT PIECE OF THE ADDRESS
XRA A ;THEN CLR ACCUM
OUT A2027 ;AND CLR THE REST OF THE HARDWARE ADDRESS REGISTER
OUT A1219
OUT W1219 ;CLEAR PIECES OF DEPOSIT DATA WHICH MUST BE ZERO
OUT W0411
OUT W0003
MVI A,02 ;BIT TO SAY "WRITE FUNCTION"
OUT A0003 ;***** I/O WRT 113 *****
;THE FOLLOWING "ADD A" WORKS BY LUCK..I.E. 2+2=4
ADD A ;BIT INTO ACCUM FOR "COM/ADR CYCLE"
OUT BUSARB ;***** I/O WRT 115/4 *****
LDA CHRBUF ;NOW GET THE CHARACTER WE WANT
OUT W2835 ;PUT IT IN THE HARDWARE REGISTER
MVI A,1 ;AND GET THE VALID BIT TO GO WITH THE CHARACTER
OUT W2027 ;PUT IT IN THE HARDWARE REGISTER
;AND BY LUCK, THE ACCUM HAS JUST WHAT WE NEED FOR THE NEXT STEP
OUT DTARB ;***** I/O WRT 114/1 *****
MVI A,^O360 ;BITS FOR "CHECK NXM","CONSOLE REQ","T ENB FOR COM/ADR"
;"T ENB FOR DATA CYCLE"
OUT BUSCTL ;*****I/O WRT 210/360 *****
;DO THIS TWICE TO GUARANTEE THAT THE INTERRUPT HAPPENS
MVI A,1 ;BIT FOR SETTING INTERRUPT TO THE KS10
OUT INT2KS ;SET THE INTERRUPT
OUT INT2KS ;SET THE INTERRUPT
RET ;AND EXIT NORMALLY....
;ENTER HERE WITH THE CHAR IN THE ACCUM
.SBTTL **KS10 TO 8080 CHARACTER SERVICE**
;ROUTINE FOR HANDLING INTERRUPT CHARACTERS FROM A RUNNING KS10.
;ONLY CHARS FROM KS TO CTY IMPLEMENTED
CHRRDY: INTON ;SET UP INTERNAL MODE
DI ;COMMON CODE,NOT TO BE DISTURBED
;DISABLE INTERRUPTS FOR THIS OPERATION
LDA TRAPEN ;GET DEFAULT FOR THE TRAP ENABLE BITS
OUT DIAG ;*****I/O WRT/ TO CLR THE INTERRUPT*****
;FALL TO HERE IF YES WE ARE IN KLINIK MODE 2.. ITS POSSIBLE THAT THIS INTERRUPT
;IS FROM THE KLINIK COMM WORD, FOR THE KLINIK LINE
EXAM 35 ;EXAM THE KLINIK COMM WORD
INTOFF ;KEEP THIS FLAG IN STEP
LDA EMBUF+1 ;GRAB THE CONTENTS OF THE BYTE WITH THE CONTROL KEY
ANA A ;SET 8080 FLAGS
JZ CTYONLY ;IF CONTROL KEY CLEAR, NOTHING FROM KLINIK, TRY CTY
MOV B,A ;SAVE THE DATA IN THE ACCUM FOR A LITTLE WHILE
LDA CSLMODE ;GET CURRENT MODE..DECIDE IF MUST THROW AWAY CHARS, OR
ANI .MODE0!.MODE1!.MODE3 ; JUST ACT AS A NULL BIT BUCKET
JNZ NULKL ;JUMP TO A NULL ACTION IF ANY OF THESE 3 MODES
;NOW HERE IF CONTROL KEY IS .NE. 0
MOV A,B ;RETRIEVE DATA
CPI 1 ;IS IT THE KEY FOR A SIMPLE CHARACTER TO BE OUTPUT??
JZ KLPCHR ;IF YES, GO PROCESS THE CHARACTER
CPI 2 ;IS IT FOR A HANGUP
JNZ NOACTN ;NOPE, IGNORE ENTIRELY
CALL HANGUP ;YUP, HANG 'EM UP
EI ;IDENTICAL CODE TO LOCATION "NOACTN", BUT THE 2 BYTES
RET ; HERE ARE CHEAPER THAN A "JMP"..I'M OUT OF PROM SPACE
;CODE FOR PRINTING THE DESIRED CHARACTER ON THE KLINIK LINE
KLPCHR: TSTRDY REMCTL ;SEE IF THE LINE IS READY FOR THE NEXT CHARACTER
JZ KLPCHR ;IF NOT READY YET, BETTER WAIT LONGER
;HERE WHEN READY
LDA EMBUF ;GET THE CHARACTER
OUT REMDAT ;PRINT IT
NULKL: MVI A,^O35 ;NOW MUST CLEAR THE WORD, AND INTERRUPT TO SAY DONE
JMP TTOCOM ;GO COMMON CODE
CTYONLY: INTON ;DON'T PRINT THIS CRUD
EXAM 33 ;GET THE COMMUNICATION WORD
INTOFF ;INTERNAL MODE OFF
LDA EMBUF+1 ;GET THE INTERRUPT CODE
CPI 1 ;IS INTERRUPT CODE .EQ. 1??
JNZ NOACTN ;JUMP TO "NO ACTION" IF NOT, CODE OUT OF BOUNDS
LDA EMBUF ;ACTUAL CHAR TO ACCUM
MOV B,A ;AND SAVE IT IN THE B REG
;CODE TO PRINT A CHAR PASSED FROM THE KS-10 CPU. CODE INTERRUPTS
;THE 10 WHEN THE CHARACTER HAS FINISHED PRINTING
CTYPCHR: TSTRDY CTYCTL ;CHECK IS THE XMITTER READY??
JZ CTYPCHR ;LOOP UNTIL IT IS
;FALL THRU WHEN READY
;BUT BEFORE PRINTING, CHECK THE KLINIK LINE TO SEE IF IT GETS THE
;CHARACTER TOO
LDA CSLMODE ;CHECK THE KLINIK MODE
CPI .MODE3 ;IS THE KLINIK PARALLEL TO THE CTY LINE??
JNZ CTYOUT ;JUMP IF NO. KLINIK DOES NOT GET THIS CHARACTER
;FALL HERE IF YES, KLINIK LINE GETS A PIECE OF THIS CHARACTER TOO.
KLTOO: TSTRDY REMCTL ;SEE IF KLINIK LINE IS READY
JZ KLTOO ;IF NOT YET, GO BACK AND TRY AGAIN
MOV A,B ;CHAR TO ACCUM
OUT REMDAT ;PRINT IT ON THE KLINIK LINE
CTYOUT: MOV A,B ;GET THE CHAR WE SAVED IN THE B REG.
OUT CTYDAT ;SEND TO THE UART
;NOW CLEAR A DATA BUFFER FOR DEPOSITING 0'S INTO THE MOS MEMORY
;WE ARE USING IN LINE CODE HERE IN ORDER TO SPEED UP THE TYPE-OUT
;ON KS10 TO 8080 XFER'S..
MVI A,^O33 ;THIS IS THE ADDRESS WE WISH TO DEPOSIT
TTOCOM: OUT A2835 ;PUT IT INTO THE HARDWARE REGISTER
XRA A ;CLEAR ACCUM, BECAUSE THE REST OF THE ADDR MUST BE ZERO
OUT A2027 ;CLR THE OTHER HARDWARE REGISTERS
OUT A1219
OUT W2835 ;AND WE WILL MAKE ALL OF THE HARDWARE DATA REGS 0
OUT W2027
OUT W1219
OUT W0411
OUT W0003
MVI A,02 ;BIT TO SAY "WRITE FUNCTION"
OUT A0003 ;***** I/O WRT 113 *****
;THIS "ADD A" WORKS BY LUCK..I.E. 2+2=4
ADD A ;BIT INTO ACCUM FOR "COM/ADR CYCLE"
OUT BUSARB ;***** I/O WRT 115/4 *****
MVI A,1 ;BIT INTO ACCUM FOR "DATA CYCLE"
OUT DTARB ;***** I/O WRT 114/1 *****
MVI A,^O360 ;BITS FOR "CHECK NXM","CONSOLE REQ","T ENB FOR COM/ADR"
;"T ENB FOR DATA CYCLE"
OUT BUSCTL ;*****I/O WRT 210/360 *****
;DO THIS TWICE TO GUARANTEE THE INTERRUTP GETS THRU
POKE10: MVI A,1 ;BIT FOR SETTING INTERRUPT TO THE KS10
OUT INT2KS ;SET THE INTERRUPT
OUT INT2KS ;SET THE INTERRUPT
NOACTN: EI ;OK FOR INTERRUPTS NOW
RET ;AND OUT
.SBTTL **TTY HANDLER FOR SPECIAL CHARACTERS**
;WHEN HERE, "B" REG CONTAINS THE STATUS OF THE CTY LINE
TTERR: MOV A,B ;COPY CTY STATUS TO ACCUM
ANI ^O70 ;ANY ERRS IN THE CTY UART??
JNZ TTERR1 ;IF YES, GO CHECK THINGS ON THE CTY LINE
;HERE IF GOT KLINIK ERRORS
MVI A,^O25 ;BEFORE JUMPING, RESET THE UART SO IT WILL WORK
OUT REMCTL ;I/O WRITE TO RESET THE UART
LDA USRMD ;CHECK USER MODE.. WILL NOT REPORT ERR IF IT IS
ANA A ;SET FLAGS
JNZ INTCH ;IF WAS USER MODE, IGNORE OVERRUN AND HANDLE CHARACTER
RET ;DONE INT
TTERR1: ANI ^O50 ;SEE IF OVERRRUN OR A FATAL ERROR
;NOW MUST CLR ERROR FROM THE UART FIRST
MVI A,^O25 ;BITS TO CLR ERROR CONDITIONS IN UART
OUT CTYCTL ;*****I/O WRT 200/25 *****
JNZ TTERMS ;NOW JUMP IF FATAL
LDA USRMD ;BEFORE ISSUEING MESSAGE,IS USER MODE SET??
ORA A ;TEST USER MODE FLAG
JNZ INTCH ;IF YES, USER MODE, THEN IGNORE THE ERROR
;NOW MUST CLR OVERRUN ERROR FROM THE UART
TTERMS: LXI H,CSLMODE ;GET CURRENT MODE OF KLINIK
MOV C,M ;SAVE IT IN C
MVI M,0 ;NOW CLEAR CSL MODE
PUSH H ;AND SAVE "H,L"
PLINE TTM ;OUTPUT THE ERROR MESSAGE
POP H ;AND RESTORE MEM POINTER
MOV M,C ;REPLACE CSL MODE AND GET OUT
RET ;AND RESTART NULL LOOP
CNTC: LXI SP,RAMST+^O2000 ;GUARANTEE THAT CNTRL-C WINS
PCHAR UPARR
PCHAR CCHR
JMP REINI ;JUMP AWAY
;LOCAL SUBROUTINE TO RESET TTY INPUT BUFFER
BFRST: LXI H,BUFBG ;BUFFER BEGINNING
SHLD BUF. ;RESET CURRENT BUFFER POINTER
SHLD FIRST ;RESET CMD POINTER
CLRB RPEND ;CLEAR REPEAT KILLER
CLRB CMDS.. ;SAY LINE IS DONE.. AT BEGINNING OF THINGS
CLRB BFCNT ;CLEAR CHAR COUNT
RET ;AND RETURN
;THIS IS THE INITIAL MODE OF THE KLINIK LINE AFTER A POWER UP. ALSO, WHEN
;THE KLINIK LINE IS DISABLED, OR IN "PROTECT" MODE, BUT NO PASSWORD HAS
;BEEN SET BY THE OPERATOR
MODE0: CPI BELL ;NO ECHO IF RECEIVE BELL
RZ ;BELL, SO OUT
KLINE NOACCS ;PRINT A MESSAGE FOR THE KLINIK LINE ONLY
RET ;AND NORMAL EXIT FROM THE INTERRUPT
;THIS IS KLINIK MODE 1. THIS IS THE MODE OF THE KLINIK LINE WHENEVER
;THE FRONT PANEL SWITCH IS IN THE PROTECT POSITION, AND WE ARE WAITING
;FOR THE PASSWORD TO BE ENTERED.
MODE1: KLINE QPW ;BEGIN BY PRINTING "PW:"
LXI H,KPWBUF ;INITIALIZE THE BUFFER FOR SAVING TYPED PASSWORD
SHLD KPWPNT ;SAVE IN THE BUFFER POINTER
CLRB KPWCNT ;AND CLEAR THE PASSWORD CHARACTER COUNTER
LXI H,PW.WAIT ;NOW ADDITIONAL KLINIK CHARS MUST DISPATCH TO
SHLD MODDIS ; THE PLACE THAT WAITS FOR A COMPLETE PASSWORD
RET ;END OF INTERRUPT
;THIS IS THE ENTRY POINT WHEN THE PERSON IS IN THE PROCESS OF TYPING THE
;PASSWORD. WE STORE THE PASSWORD AS IT IS TYPED, THEN WHEN DONE, WE WILL
;VERIFY THAT IT IS CORRECT
PW.WAIT: CPI CRCHR ;IS IT AN END OF LINE CHARACTER
JZ PW.TST ;JUMP IF YES.. TIME TO VERIFY THE PASSWORD
CALL UP.LO ;GENERATE ONLY UPPER CASE FOR PROGRAM INTERNALS
MOV B,A ;SAVE THE CHAR IN B REG FOR A LITTLE BIT
;IF NOT END OF LINE, JUST ADD IT TO THE BUFFER OF CHARS THAT IS THE PASSWORD
LDA KPWCNT ;FIRST THINGS FIRST, SEE HOW MANY CHARS IN THE BUFFER
INR A ;UPDATE TO ACCOUNT FOR THIS ONE
CPI 7 ;IS IT TOO MANY
JZ PW.ERR ;JUMP IF YES. ITS A PASSWORD ERROR
STA KPWCNT ;ELSE SAVE THE UPDATED COUNT AND CONTINUE
LHLD KPWPNT ;GET THE BUFFER POINTER
MOV M,B ;PUT THE CHARACTER IN THE BUFFER
INX H ;UPDATE THE BUFFER POINTER
SHLD KPWPNT ;PUT THE POINTER BACK
RET ;AND END OF INTERRUPT
;CODE FOR VERIFYING THAT THE PASSWORD ENTERED IS THE CORRECT AND VALID
;PASSWORD
PW.TST: LXI D,PASSWORD ;D,E POINTS TO THE EXPECTED PASSWORD
LXI H,KPWBUF ;H,L POINTS TO THE TYPED IN BUFFER
MVI B,00 ;"B" WILL BE THE COUNTER
PW..: LDAX D ;FETCH UP AN EXPECTED CHARACTER
ANA A ;SET THE FLAGS
JZ PW.END ;IF "END", GO MAKE SURE TYPEIN IS TERMINATED
INR B ;ELSE UPDATE OUR COUNTER
CMP M ;AND COMPARE A CHAR
JNZ PW.ERR ;IF MIS-COMPARE REPORT IT AS ERROR
INX D ;UPDATE EXPECTED POINTER
INX H ;UPDATE TYPED IN POINTER
JMP PW.. ;CONTINUE
;END.. THIS IS ONLY TO VERIFY THAT TYPED TERMINATED AT THE SAME NUMBER OF
;CHARACTERS AS EXPECTED
PW.END: LDA KPWCNT ;GET EXPECTED COUNT
CMP B ;CHECK AGAINST THE CURRENT COUNT
JZ PW.OK ;AND JUMP IF COUNTS MATCH
;FALL THRU TO ERROR IF CHARACTER COUNTS DON'T MATCH
PW.ERR: KLINE CMDNG ;GIVE USER AN ERROR MESSAGE
LXI H,PWRTRY ;HAD ERROR. ONLY GET 3 CHANCES FOR ERRORS
INR M ;UPDATE ERROR COUNT
MOV A,M ;PLACE COUNT IN ACCUM FOR A TEST
CPI 3 ;SEE IF STRUCK OUT
JZ KLIRST ;GO RESET KLINIK LINE IF USER STRUCK OUT
JMP MODE1 ;ELSE GIVE HIM "PW:" MESSAGE AGAIN
;HERE IF EVERYTHING MATCHED
PW.OK: CALL SETM2 ;CHANGE LINE TO MODE 2
KCHAR 'O ;WHEN GOOD PW, SENT OUT AN "OK"
KCHAR 'K
PW.OUT: CLRB PWRTRY ;CLEAR ERROR COUNTER
RET ;EXIT
;KLINIK LINE RESET CODE. FOR RESETING KLINIK LINE AND HANGING UP THE USER
KLIRST: CALL HANGUP ;GO HANG UP THE KLINIK LINE
CALL SETM1 ;DROP BACK TO MODE 1
JMP PW.OUT ;ZAP ERROR FLAG THEN OUT
;KLINIK LINE MODE 2. THIS IS STREAM INPUT/OUTPUT. ALL CHARACTERS FROM
;THE KLINIK UART ARE SENT TO THE SPECIAL KLINIK COMMUNICATION WORDS
;AND ALL WORDS FROM THE KLINIK COMM WORDS ARE OUTPUT TO THE KLINIK LINE.
MODE2: CPI CNBCK ;FIRST SEE IF THE KLINIK USER WANTS A MODE CHANGE
JNZ KL3435 ;IF NOT, GO SEND INFO TO THE KLINIK COMM WORD
LDA MMFLG ;BEFORE GOING TO MODE 3, SEE IF MM MODE
ANA A ;SET 8080 FLAGS
JNZ END.USR ;IF YES, MM MODE, ACT LIKE FROM A CTY
;FALL THRU IF WANTS TO CHANGE MODES. BUT BEFORE CHANGING, CHECK IF HE'S
;ALLOWED TO CHANGE MODES.
LDA KLLINE.ON ;CHECK IF KLINIK IS ON, & USER IS ALLOWED TO CHANGE
ANA A ;SET FLAGS
RZ ;IF NOT ENABLED TO CHANGE, JUST IGNORE THIS INTERRUPT
;WELL, HE IS ALLOWED TO CHANGE. SEE IF THE FRONT PANEL SWITCH IS UNLOCKED
IN BOOTSW ;***** I/O RD 301 *****
;NOTE THAT BIT LO IS TRUTH, IF BIT HI IS FALSE(DISABLED)
ANI 4 ;CHECK THE CONSOLE ENABLE BIT
JZ SETM3 ;GO MODE 3 ONLY IF PANEL NOT LOCKED.LET SETM3 DO "RET"
;THIS IS WHERE YOU ACTUALLY WRITE THE DESIRED CHARACTER INTO THE KLINIK
;LINE COMMUNICATION WORD
KL3435:
STA CHRBUF ;PUT CHARACTER IN A RAM BUFFER
MVI A,^O34 ;DESIRED ADDRESS FOR DEPOSTING CHARACTER
OUT A2835 ;WRITE ONLY RELEVANT PIECE OF THE ADDRESS
XRA A ;THEN CLR ACCUM
OUT A2027 ;AND CLR THE REST OF THE HARDWARE ADDRESS REGISTER
OUT A1219
OUT W1219 ;CLEAR PIECES OF DEPOSIT DATA WHICH MUST BE ZERO
OUT W0411
OUT W0003
MVI A,02 ;BIT TO SAY "WRITE FUNCTION"
OUT A0003 ;***** I/O WRT 113 *****
;THE FOLLOWING "ADD A" WORKS BY LUCK..I.E. 2+2=4
ADD A ;BIT INTO ACCUM FOR "COM/ADR CYCLE"
OUT BUSARB ;***** I/O WRT 115/4 *****
LDA CHRBUF ;NOW GET THE CHARACTER WE WANT
OUT W2835 ;PUT IT IN THE HARDWARE REGISTER
MVI A,1 ;AND GET THE VALID BIT TO GO WITH THE CHARACTER
OUT W2027 ;PUT IT IN THE HARDWARE REGISTER
;AND BY LUCK, THE ACCUM HAS JUST WHAT WE NEED FOR THE NEXT STEP
OUT DTARB ;***** I/O WRT 114/1 *****
MVI A,^O360 ;BITS FOR "CHECK NXM","CONSOLE REQ","T ENB FOR COM/ADR"
;"T ENB FOR DATA CYCLE"
OUT BUSCTL ;*****I/O WRT 210/360 *****
;DO THIS TWICE TO GUARANTEE THAT THE INTERRUPT HAPPENS
MVI A,1 ;BIT FOR SETTING INTERRUPT TO THE KS10
OUT INT2KS ;SET THE INTERRUPT
OUT INT2KS ;SET THE INTERRUPT
RET ;AND EXIT NORMALLY....