; D1asm.asm -- Dorado resident interface procedures ; 11 May 1983 .get "MAsmCommon.d" .get "D1Instrs.d" .get "D1RegMem.d" .get "D1Dmux.d" ; OS .bext DoubleAdd ; MCMD .bext ErrorAbort ; MDATA .bext MDATAtab,MADDRtab,DWatch,CheckStoppedGlitches,MIRPE,VMBase ; MASM .bextz OddParity,MSave2 ; MGO .bextz CantContinue ; D1I0 .bextz SaveMIR,DMuxTab,DHistTab .bext BreakMIR,SaveBR36 ; D1I1 .bextz LDRMEM ; Points at word 0 of LDR memory ; D1ACTIONS .bext BadAText ; D1TABLES .bextz NMEMS,MEMLEN ; D1MEM .bext RdCACHEA,OldTPC,SaveTIOA,SaveSTKP .bextz OldTask,SaveLINK,SaveTPC,SaveTask,SaveRBase,SaveMBase,SaveT .bextz SaveSRN ; D1RES .bext BR36Saved,BreakTask ; D1MICASM .bextz MCXct ; D1CONFIG .bext log2pgsize,AColumnShift,DColumnShift,HaveControl ; Defined here .bext GFrameX .bext stReadOnly,stPassive,stUndAdr,stNotIMA,stNotInVM,stRunning .bextz D1In,D1Out .bextz MADDRH,MADDRL ; Unpacked AVec .bextz Xct,XctR16,XctR16C,XctR16Link,XctL16,XctL16C,XctL16T,XctL16Q .bextz DoStrobe,XctLFF,SetALUF,SetRSTK .bextz SelectTask,CheckStopped .bext LoadMIR,LoadCPReg,CertifyAV,ConvertAV .bext GetErrs,RBmux,ReadDMux,LoadDAddr,LoadDMD,LoadDWatch .bext ContinueProgram,Start,Stop,MIRtoIM,IMtoMIR,ReadIMX,SelFltSrn ; Stuff in D1In readouts--**Note: these are same names but different ; values from the ones in d1pe.d** IMrhPE = 100000 IMlhPE = 40000 MdPE = 20000 IOBPE = 100000 RAMPE = 40000 MemPE = 20000 Stopped = 20000 .zrel MADDRH: 0 ; **Do not reorder (used in DoubleAdd) MADDRL: 0 D1In: 177030 D1Out: 177016 DoStrobe: .DoStrobe Xct: .Xct AXct: .AXct ; For assembly code--returns non-skip XctL16: .XctL16 XctL16C: .XctL16C XctL16T: .XctL16T XctL16Q: .XctL16Q XctLFF: .XctLFF XctR16: .XctR16 XctR16C: .XctR16C XctR16Link: .XctR16Link SetALUF: .SetALUF SetRSTK: .SetRSTK CheckStopped: .CheckStopped SelectTask: .SelectTask .srel GFrameX: .GFrameX stReadOnly: .stReadOnly stPassive: .stPassive stUndAdr: .stUndAdr stNotIMA: .stNotIMA stNotInVM: .stNotInVM stRunning: .stRunning LoadMIR: .LoadMIR LoadCPReg: .LoadCPReg ReadDMux: .ReadDMux GetErrs: .GetErrs RBmux: .RBmux LoadDAddr: .LoadDAddr LoadDMD: .LoadDMD LoadDWatch: .LoadDWatch ContinueProgram: .ContinueProgram Start: .Start Stop: .Stop CertifyAV: .CertifyAV ConvertAV: .ConvertAV SelFltSrn: .SelFltSrn MIRtoIM: .MIRtoIM IMtoMIR: .IMtoMIR ReadIMX: .ReadIMX .nrel .stReadOnly: .txt "Read-only" .stPassive: .txt "Illegal to write while Passive" .stUndAdr: .txt "Undefined address" .stNotIMA: .txt "??Not IM address??" .stNotInVM: .txt "??Not in VM??" .stRunning: .txt "Illegal to write while running" ; Subroutine using new GetFrame instruction--replaces GetFrame procedure ; pointed to by 370 .GFrameX: GtFrame 77400 ; CallSwat() if stack overflow ; Arg1 is LDR address*4 of an instruction with 0 in RSTK; arg2 is a ; value for RSTK. Modify the instruction fixing up parity and store ; it in MKINS. Due to bit-scrambling in MIR the following: .SetRSTK: sta 3 1 2 sta 2 MSave2 lda 3 LDRMEM add 0 3 ; Pointer to instr being modified mov 1 2 ; Preserve value for RSTK lda 0 XR113151 ; Magic parity word cycle 0 lda 1 XR200 and 1 0 ; 0/ 200 if modifying parity lda 1 1 3 ; Mir1 and# 1 0 szr sub 0 1 skp add 0 1 mov 2 0 lda 2 LDRMEM sta 1 MKINS+1 2 ; Mir1 with modified parity cycle 14 ; Left-justify value for RSTK lda 1 XR200 movzl 0 0 szc add 1 0 lda 1 0 3 ; Mir0 Mir23Copy: add 1 0 ; Add in RSTK or ALUF.0 bits sta 0 MKINS 2 lda 0 2 3 sta 0 MKINS+2 2 lda 0 3 3 sta 0 MKINS+3 2 lda 2 MSave2 lda 0 XMKINS lda 3 1 2 jmp 1 3 XMKINS: MKINS XR200: 200 XR10000: 10000 XR113151: 113151 ; Arg1 is LDR address*4 of instr with 0 in ALUF; arg2 is a value for ; ALUF. Modify instr fixing up parity and store it in MKINS. Due to ; bit-scrambling in MIR the following: .SetALUF: sta 3 1 2 sta 2 MSave2 lda 3 LDRMEM add 0 3 ; Pointer to instr. mov 1 2 ; Preserve value for ALUF lda 0 XR113151 ; Magic parity word cycle 0 ; Position parity(ALUF) in bit 8 lda 1 XR200 and 0 1 ; 200 if change parity mov 2 0 ; 0/ ALUF lda 2 1 3 ; 2/ Mir1 and# 1 2 szr sub 1 2 skp add 1 2 ; 2/ Mir1 with parity fixed cycle 14 movzl 0 0 snc mkzero 1 1 skp lda 1 XR10000 add 2 0 ; 0/ Mir1 with parity and ALUF[1:3] fixed lda 2 LDRMEM sta 0 MKINS+1 2 lda 0 0 3 ; Mir0 jmp Mir23Copy ; Return 16 bits of external BMux to caller .RBmux: sta 3 1 2 jsr .RDin Mir0+InB03 Mir0+InB47 Mir0+InB811 Mir0+InB1215 lda 3 1 2 jmp 1 3 ; Return 16 bits of error status to caller .GetErrs: sta 3 1 2 jsr .RDin Mir0+InErr0 Mir0+InErr1 Mir0+InErr2 Mir0+InErr3 lda 3 1 2 jmp 1 3 Mask03: 170000 .RDin: sta 2 MSave2 lda 0 0 3 sta 0 @D1Out lda 2 @D1In lda 0 Mask03 and 0 2 ; 2 ← 1st 4-bit slice lda 1 2 3 sta 1 @D1Out lda 1 @D1In ands 0 1 add 1 2 ; 2 ← 1st + 3rd 4-bit slices lda 1 1 3 sta 1 @D1Out lda 1 @D1In and 1 0 cycle 14 add 0 2 ; 2 ← 1st + 2nd + 3rd 4-bit slices lda 0 3 3 sta 0 @D1Out lda 0 @D1In lda 1 Mask03 and 1 0 cycle 4 add 2 0 ; 0 ← all 4 4-bit slices lda 2 MSave2 jmp 4 3 saveDVec: 0 save3rl: 0 cClock: Clock cClockAB: Clock+UseCPReg ; Subroutine for turning off UseCPReg then doing XctR16, then turning ; UseCPReg back on again .XctR16Link: sta 3 save3rl sta 0 1 2 lda 0 cClock DStrobe ; Turn off UseCPReg lda 0 1 2 jsr .XctR16 1 lda 0 cClockAB DStrobe ; Turn UseCPReg back on again lda 0 @saveDVec lda 3 save3rl jmp 1 3 ; Arg1 is LDR address*2, arg2 is DVec ; Execute instruction and store 16 bits of data in DVec ; Also return value in 0 .XctR16: sta 1 saveDVec sta 3 2 2 jsr .AXct jsr .RDin Mir0+InB03 Mir0+InB47 Mir0+InB811 Mir0+InB1215 jmp XRC1 .XctR16C: sta 1 saveDVec sta 3 2 2 jsr .AXct jsr .RDin Mir0+InB03 Mir0+InB47 Mir0+InB811 Mir0+InB1215 com 0 0 XRC1: sta 0 @saveDVec lda 3 2 2 jmp 1 3 ; Arg1 is a displacement into LDRMEM (LDRaddr*4) of an instruction ; to execute with Arg2 added to the FF field. Because of bit-scrambling ; in LDRMEM, the following: .XctLFF: inc 3 3 sta 3 1 2 sta 2 MSave2 movzr 1 3 ; Compute parity of 5 bits in Arg2 movzr 3 2 add 2 3 ; (Arg2 rshift 2)+(Arg2 rshift 1) movzr 2 2 add 2 3 ; (Arg2 rshift 3)+(Arg2 rshift 2)+(Arg2 rshift 1) movzr 2 2 add 2 3 addr 1 3 snc ; Carry←sum of bits = xor of bits and skip if 1 sub 2 2 skp ; Parity is even--no change lda 2 X200 ; Parity is odd--will complement lda 3 LDRMEM addz 0 3 ; 3 = pointer to instruction, 0 into carry lda 0 0 3 sta 0 XLIns0 ; Copy byte 0 of instr. (no change) lda 0 3 3 and# 0 2 szr ; Xor P1631 sub 2 0 skp add 2 0 sta 0 XLIns3 ; Copy byte 3 with Xor'ed parity lda 2 1 3 lda 3 2 3 movzr 1 0 snc ; Skip if Arg2 is odd, 0 = FF rshift 1 jmp .+3 lda 1 X4000 add 1 3 ; Add 1 to FF.7 movs 0 0 add 0 2 ; Add (FF rshift 1) to FF[3:6] sta 2 XLIns1 sta 3 XLIns2 lda 2 MSave2 ; Restore stack pointer jsr XLFF ; 3 = pointer to instruction, continue inside Xct XLIns0: 0 ; 0th instr byte saved here XLIns1: 0 ; 1st XLIns2: 0 ; 2nd XLIns3: 0 ; 3rd XLFF: mov 3 1 jmp XLFF1 X200: 200 X4000: 4000 ; Subroutine to execute a microinstruction in the LDR memory. Arg is ; an address in LDR*4. .Xct: inc 3 3 .AXct: sta 3 1 2 Xct1: lda 1 LDRMEM add 0 1 ; Compute address of MIRvec in LDR XLFF1: lda 0 cNormal MIRLoad ; Special Alto microinstruction ; Check for PE's lda 0 xErr2 sta 0 @D1Out lda 0 @D1In movl 0 0 szc ; Know CIMPErh = 100000 jmp XctE2141 XctER0: movl 0 0 szc ; Know CIMPElh = 40000 jmp XctE020 XctX: lda 0 cXct ; Single-step DStrobe jmp @1 2 XctE2141: lda 3 @lvMIRPE isz 1 3 jmp XctER0 jmp XctER0 XctE020: lda 3 @lvMIRPE isz 0 3 jmp XctX jmp XctX cXct: Control+Freeze+SetRun+SetSS cNormal: Control+Freeze xErr2: Mir0+InErr2 Masklh: 177400 lvMIRPE: MIRPE ; For XctL16 and XctL16C, arg1 is LDR address*4, arg2 is 16 bits of data. ; Load CPReg with data, execute the instruction with UseCPReg true, ; then turn off UseCPReg. XctL16T and XctL16Q accept data as arg1 and ; do either LDT or LDQ as the instruction. .XctL16Q: mov 0 1 lda 0 xLDQ jmp .XctL16 .XctL16T: mov 0 1 skp .XctL16C: com 1 1 skp ; Complement the data first lda 0 xLDT .XctL16: inc 3 3 sta 3 1 2 sta 0 2 2 movs 1 0 ; l.h. 0←value for CPReg1, l.h. 1←value for CPReg0 lda 3 Masklh and 3 0 ; 0←Value for CPReg1 and 3 1 ; 1←Value for CPReg0 lda 3 cCPReg1 add 3 0 lda 3 cCPReg0 add 1 3 DStrobe ; Strobe CPReg1 mov 3 0 DStrobe ; Strobe CPReg0 lda 0 2 2 jmp Xct1 xLDT: LT xLDQ: LQ cCPReg1: CPReg1 cCPReg0: CPReg0 RCcnt: Clock+ShiftDMux RControl: Control ; Subroutine to read all machine state that can be read passively: ; 2048 DMux addresses, saved in DMuxTab; 16 BMUX bits via D1In, ; stored in DMuxTab!128; and 16 error status bits, stored in DMuxTab!129. ; The readout is then rearranged for convenient usage by the rest of Midas. .ReadDMux: sta 3 1 2 jsr @GetFrame 12 jsr @StArgs ; 0←Value, 1←Last, 3←-Count lda 3 R177600 ; 3/ -200 lda 1 DMuxTab adc 3 1 ; 1/ DMuxTab+177 mkzero 0 0 blks ; Zero(DMuxTab,200B) lda 0 RControl DStrobe ; Must clear SetRun to enable Alto muffler control lda 0 RCcnt ; Clock+ShiftDMux mkzero 1 1 lda 3 DMuxTab RDMux ; New read-DMux instruction in special microcode ; reads all addresses except 2047 jmp RDMo R177600: 177600 RB100000: 100000 R4: 4 RMir0: Mir0 RMir0x: Mir0+200 RMir1: Mir1 RMir1x: Mir1+200 R100200: 100200 R20000: 20000 R40: 40 ; Finished reading DMux--rearrange bits for registers that must be ; displayed independently RDMo: sta 2 MSave2 lda 3 DMuxTab ; Temperature sensors and BaseBoard lda 0 dCTASK 3 lda 2 RB100000 and 0 2 ; 2 ← CBTempSense in sign bit lda 1 dCLKRUN 3 lda 0 R4 and 1 0 sub 0 1 sta 1 dCLKRUN 3 ; CLKRUN with TBaseTempSense removed cycle 14 add 0 2 lda 0 dSCCON 3 lda 1 R100200 and 0 1 sub 1 0 sta 0 dSCCON 3 ; SCCON with TempSense stuff removed movzr 1 1 movzr 1 1 lda 0 R20000 and 1 0 ; ProcH TempSense in bit 2 add 0 2 lda 0 R40 ands 1 0 movzr 0 0 ; ProcL TempSense in bit 3 add 0 2 lda 1 dFFK 3 lda 0 R40 and 1 0 sub 0 1 sta 1 dFFK 3 cycle 6 ; IFUTemp in bit 4 add 0 2 lda 1 dKSTATE 3 lda 0 R100000 and 1 0 sub 0 1 sta 1 dKSTATE 3 cycle 13 ; DiskEthTemp in bit 5 add 0 2 sta 2 dTEMP 3 ; Control section rearrangements ; Get bdIM signals in MIR-loading format and put in 4-word IMOUT vector lda 0 dCTASK 3 cycle 4 mov 0 2 ; bdRSTK.0, bdIMLH, bdIMRH, bdJCN.7 left-justified lda 0 R170000 lda 1 dNEXT 3 ; bdIM[1:20] and 0 1 lda 3 dCTD 3 ; bdIM[21:40] and 3 0 lda 3 RMir0 ; Mir0 in address field, RSTK.0 false movl 2 2 szc lda 3 RMir0x ; RSTK.0 true add 1 3 cycle 14 add 3 0 lda 3 DMuxTab sta 0 dIMOUT+0 3 lda 0 R7400 lda 1 dCTD 3 and 0 1 lda 3 dNEXT 3 and 3 0 lda 3 RMir1 ; Mir1 in address field, P020 false movl 2 2 szc lda 3 RMir1x ; P020 true add 1 3 cycle 4 add 3 0 lda 3 DMuxTab sta 0 dIMOUT+1 3 lda 1 dCTD 3 lda 0 R17 ands 0 1 lda 3 dNEXT 3 ands 3 0 lda 3 RMir3 movl 2 2 szc lda 3 RMir3x add 1 3 cycle 4 add 3 0 lda 3 DMuxTab sta 0 dIMOUT+3 3 lda 0 R360 lda 1 dNEXT 3 ands 0 1 lda 3 dCTD 3 and 3 0 lda 3 RMir2 ; Mir2 in address field, JCN.7 false movl 2 2 szc lda 3 RMir2x ; JCN.7 true add 1 3 cycle 4 add 3 0 lda 3 DMuxTab sta 0 dIMOUT+2 3 ; Get MIR into MIR-loading format and put in the 4-word vector SaveMIR lda 0 dCTASK 3 lda 1 R17 and 0 1 sta 1 dCTD 3 ; CTD[0:3] cycle 4 lda 2 R3 and 0 2 ; bRSTK.0, IMLH right-justified lda 0 dBNT 3 ; MIR[21:40] lda 1 R170000 and 1 0 lda 3 dPENC 3 ; MIR[1:20] and 3 1 lda 3 RMir0 movr 2 2 szc ; IMLH tested lda 3 RMir0x add 1 3 cycle 14 add 3 0 lda 3 DMuxTab sta 0 dSaveMIR+0 3 lda 0 dPENC 3 lda 1 R7400 and 1 0 lda 3 dBNT 3 and 3 1 lda 3 RMir1 movr 2 2 szc ; bRSTK.0 tested lda 3 RMir1x add 1 3 cycle 4 add 3 0 lda 3 DMuxTab sta 0 dSaveMIR+1 3 lda 1 R360 lda 0 dBNT 3 and 1 0 lda 2 dCJNK1 3 ; bJCN.7, IMRH left-justified lda 3 dPENC 3 ands 3 1 lda 3 RMir2 movl 2 2 szc ; bJCN.7 tested lda 3 RMir2x add 1 3 cycle 4 add 3 0 lda 3 DMuxTab sta 0 dSaveMIR+2 3 lda 0 dPENC 3 lda 1 R17 and 1 0 lda 3 dBNT 3 ands 3 1 lda 3 RMir3 movl 2 2 szc ; IMRH tested lda 3 RMir3x add 1 3 cycle 14 add 3 0 lda 3 DMuxTab sta 0 dSaveMIR+3 3 jmp RConZ R100000: 100000 RMir2: Mir2 RMir2x: Mir2+200 RMir3: Mir3 RMir3x: Mir3+200 R170000: 170000 R7400: 7400 R360: 360 R17: 17 R40000: 40000 R3: 3 R177400: 177400 R140: 140 R37777: 37777 R377: 377 R14: 14 R10400: 10400 RConZ: lda 2 dCTASK 3 lda 0 R360 and 2 0 cycle 14 sta 0 dCTASK 3 ; CTASK complete (bSWd' remaining in ac2) sta 0 SaveTask lda 0 dCJNK1 3 lda 1 R37777 and 1 0 ; Flush bJCN.7 and IMRH (was put into MIR) lda 1 R40000 and 2 1 ; bSWd' add 1 0 ; 0/ CJNK1 with bSWd' added lda 1 dTOPE 3 lda 2 R100000 and 1 2 ; Call sub 2 1 sta 1 dTOPE 3 ; ToPE[1:15] (Call removed) add 0 2 ; 2/ CJNK1 with bJCN.7, IMRH removed, ; bSWd', Call added lda 0 R14 and 2 0 sub 0 2 ; 2/ FF=UseDMD and FF=TOffIsOk removed sta 2 dCJNK1 3 movzl 0 1 movzl 1 1 lda 2 dFFEQ 3 lda 0 R377 and 2 0 ; 0/ Bnt and bPEnc sub 0 2 ; 2/ BNT and bPEnc removed add 1 2 ; 2/ FF=UseDMD, FF=TOffIsOk added lda 1 R17 and 0 1 sub 1 0 sta 1 dPENC 3 ; bPEnc[0:3] complete cycle 14 sta 0 dBNT 3 lda 0 dCJNK0 3 lda 1 R17 and 0 1 sub 1 0 sta 0 dCJNK0 3 ; FF= bits removed add 1 2 ; FF= bits added lda 0 R10400 and 2 0 sub 0 2 ; FF= with Link←BMuxa, B←Link' removed sta 2 dFFEQ 3 cycle 7 lda 1 RA10 and 0 1 lda 2 dCJNK1 3 add 1 2 ; Link←BMuxa added cycle 4 lda 1 RA10 andzr 1 0 add 0 2 ; B←Link' added sta 2 dCJNK1 3 lda 2 dCJNK3 3 lda 0 R170000 and 2 0 sub 0 2 sta 2 dCJNK3 3 ; CJNK3 complete cycle 4 sta 0 dNEXT 3 ; NEXT complete ; MemC rearrangements lda 0 dMAPAD 3 lda 2 RA377 and 0 2 sub 2 0 cycle 14 sta 0 dAAD 3 ; Aad with 4 zeroes to the right lda 0 dPAIR 3 lda 1 RA200 and 0 1 sub 1 0 sta 0 dPAIR 3 movzl 1 1 add 2 1 sta 1 dMAPAD 3 ; MapAd[0:8] right-justified lda 1 dPVAL 3 lda 0 RA100000 and 1 0 ; MemB.0 sub 0 1 lda 2 RA10000 and 1 2 ; MemB.1 sub 2 1 movzl 2 2 movzl 2 2 add 2 0 ; MemB[0:1] in bits 0:1 sta 1 dPVAL 3 ; PVAL with MemB[0:1] removed cycle 5 lda 2 dHIT 3 lda 1 RA7 and 2 1 sub 1 2 ; 2/ HIT with MemB[2:4] removed add 1 0 sta 0 dMEMB 3 ; MemB[0:4] right-justified lda 0 RA777 and 2 0 sub 0 2 ; 2/ Mcr stuff from MemC sta 0 dHIT 3 ; HIT with Mcr and MemB stuff removed lda 0 RA17000 and 2 0 sub 0 2 cycle 14 add 0 2 ; 2/ Mcr stuff from MemC in position lda 1 dHOLD 3 lda 0 RA170000 and 1 0 sub 0 1 sta 1 dHOLD 3 ; Victim' and NextV' removed com 0 0 lda 1 RA170000 and 1 0 cycle 15 add 0 2 ; 2/ Mcr stuff with Victim & NextV added (high-true) lda 1 dFLTMEM 3 lda 0 RA160000 and 1 0 ; 1/ other Mcr bits from MemX sub 0 1 sta 1 dFLTMEM 3 cycle 3 add 0 2 sta 2 dMCR 3 ; Complete Mcr lda 0 dPVAH 3 lda 1 RA60000 and 0 1 ; true, WantCHDly' sub 1 0 movzr 1 1 lda 2 dHOLD 3 add 1 2 sta 2 dHOLD 3 ; HOLD complete lda 2 dPVAL 3 lda 1 RA60000 and 2 1 sub 1 2 ; 2/ ProcVA[20:31] right-justified add 1 0 ; 0/ ProcVA[4:19] cycle 14 lda 1 RA170000 and 0 1 sub 1 0 add 1 2 sta 0 dPVAH 3 ; ProcVA[4:15] right-justified sta 2 dPVAL 3 ; ProcVA[16:31] jmp RCMemD RA377: 377 RA200: 200 RA100000: 100000 RA10000: 10000 RA7: 7 RA777: 777 RA17000: 17000 RA170000: 170000 RA160000: 160000 RA60000: 60000 RA177767: 177767 RA10: 10 RA100003: 100003 RA60: 60 RA40: 40 RA2: 2 RA1: 1 RA1000: 1000 RA2000: 2000 RA177377: 177377 ; MemD rearrangements RCMemD: lda 1 dEC 3 lda 0 RA170000 and 1 0 sub 0 1 sta 1 dEC 3 ; EC with MDMad[0:3] removed cycle 4 sta 0 dMDMAD 3 ; MDMad[0:3] right-justified lda 0 dFD 3 lda 1 RA177767 and 1 0 ; Clear possible garbage bit lda 1 dMEMD0 3 lda 2 RA10 and 1 2 sub 2 1 ; 1/ MEMD0 with DontWriteMDM removed add 2 0 sta 0 dFD 3 ; Move DontWriteMDM bit into FD lda 0 dDAD 3 lda 2 RA100003 and 0 2 sub 2 0 movzl 0 0 sta 2 dDADE 3 ; D0BCE'c, D0ACE'c, and WriteD0'e scrambled lda 2 RA7 and 1 2 sub 2 1 ; 1/ MEMD0 with DAD1.10b-12b removed add 2 0 sta 0 dDAD 3 ; DAD complete lda 2 RA60 and 1 2 ; 2/ D1BCE'c and WriteD1'd sub 2 1 sta 1 dMEMD0 3 lda 0 RA40 and 2 0 add 2 0 ; Move the D1BCE'c bit left 1 cycle 6 ; 0/ D1BCE'c and WriteD1'd in position lda 2 RA100000 lda 1 dDADE 3 andzr 1 2 add 0 2 ; D0BCE'c, D1BCE'c, & WriteD1'd in position lda 0 RA2 and 1 0 cycle 16 add 0 2 ; D0ACE'c also in position lda 0 dDADE 3 lda 1 RA1 ands 1 0 cycle 3 add 0 2 ; WriteD0'e also in position lda 1 dEC 3 lda 0 RA1000 and 1 0 sub 0 1 sta 1 dEC 3 ; EC with D1ACE'c removed cycle 4 ; D1ACE'c in pos. add 0 2 sta 2 dDADE 3 ; DADE complete lda 1 dFD 3 lda 0 RA200 and 1 0 ; 0/ Fout.00 sub 0 1 ; 1/ FD with Fout.00 removed lda 2 dMEMD0 3 lda 3 RA1000 and 2 3 ; 3/ Dbuf←' sub 3 2 ; 2/ MEMD0 with Dbuf←' removed movzr 3 3 movzr 3 3 add 3 1 ; 1/ FD with Dbuf←' added movzr 0 0 movzr 0 0 add 0 2 ; 2/ MEMD0 with Dbuf←' added lda 3 DMuxTab sta 1 dFD 3 lda 0 RA2000 and 2 0 sub 0 2 ; 2/ MEMD0 with EcInD.0 removed sta 2 dMEMD0 3 ; MEMD0 complete cycle 16 lda 1 dEC 3 lda 2 RA177377 and 2 1 ; Clear garbage bit add 1 0 sta 0 dEC 3 ; EC complete lda 2 MSave2 jsrii lvRBmux 0 lda 3 DMuxTab sta 0 dBMUX 3 ; BMUX in extended DMuxTab jsrii lvGetErrs 0 lda 3 DMuxTab sta 0 dESTAT 3 ; ESTAT in extended DMuxTab ; left-shift DHIST bits into 32-bit accumulators lda 3 MEMLEN lda 0 DHISTx+DHISTx+1 3 sta 0 4 2 ; Iteration count lda 3 DHistTab HisLp: sta 3 5 2 lda 0 2 3 ; Selected DMux address in left 12 bits of 3rd wrd lda 3 RA177400 ands 0 3 ; Right-justify word number lda 1 DMuxTab add 1 3 cycle 14 ; Right-justify bit number mov 0 1 lda 0 0 3 ; Word from DMuxTab cycle 0 ; Left-justify selected bit lda 3 5 2 ; Recover pointer into DHistTab lda 1 1 3 movl 0 0 ; DMux bit into carry movl 1 1 ; Left-shift into low wrd, bit out into cry sta 1 1 3 lda 1 0 3 movl 1 1 ; Left-shift bit out into high wrd sta 1 0 3 inc 3 3 inc 3 3 inc 3 3 dsz 4 2 jmp HisLp jsr .LoadDWatch 0 jsr @Return RA177400: 177400 lvRBmux: RBmux lvGetErrs: GetErrs ; Load 12-bit DMux address in AC0 and then execute it with UseDMD. ; **Doesn't restore DMux address to DWatch .LoadDMD: sta 3 1 2 cycle 4 mov 0 1 lda 0 LDControl DStrobe ; Clear SetRun to enable CP muffler control lda 3 LD177764 LDMDlp: lda 0 LDMDc0 movl 1 1 szc lda 0 LDMDc1 DStrobe inc 3 3 szr jmp LDMDlp lda 0 LDMx DStrobe jmp LDMDf ; Turn off UseDMD and return ; Subroutine to load the DMux address with DWatch[20:37] in MDATA for ; scope observation. .LoadDWatch: sta 3 1 2 lda 3 @lvDWatch lda 0 1 3 mov# 0 0 skp ; Procedure to load the DMux address selected by arg 0 .LoadDAddr: sta 3 1 2 cycle 4 ; Left-justify 12-bit number mov 0 1 lda 0 LDControl DStrobe ; Clear SetRun to enable CP muffler control lda 3 LD177764 LDWlp: lda 0 LDMDc0 movl 1 1 szc ; Skip if next bit is 0 lda 0 LDMDc1 DStrobe ; Strobe next bit into DMux address inc 3 3 szr jmp LDWlp LDMDf: lda 0 ClockN DStrobe lda 3 1 2 jmp 1 3 LDMx: Clock+UseCPReg+UseDMD LDMDc0: Clock+ShiftDMux+UseCPReg LDMDc1: Clock+ShiftDMux+UseCPReg+DAddrBit lvDWatch: DWatch LDControl: Control LD177764: 177764 ClockN: Clock+UseCPReg ; IMtoMIR(MIRvec,IMvec) transforms IMvec into MIRvec where MIRvec is the ; four-word vector such that four DStrobe's load MIR with the IM data .IMtoMIR: sta 3 1 2 jsr @GetFrame 12 jsr @StArgs lda 3 5 2 ; 3/ IMvec lda 1 2 3 movzl 1 1 movzl 1 1 ; IMLH bad parity bit into sign lda 0 1 3 movl 0 0 ; ASEL.2 into carry lda 0 0 3 movl 0 0 snc ; 0/ IM[1:20], skip if RSTK.0 true jmp IMtoMIRa movl 1 1 snc ; Skip if bad parity into IMLH mkzero 1 1 skp mkone 1 1 lda 3 mMir0x jmp IMtoMIRb IMtoMIRa: movl 1 1 snc mkone 1 1 skp mkzero 1 1 lda 3 mMir0 IMtoMIRb: sta 3 6 2 ; Mir0 control with RSTK.0 fixed sta 0 7 2 ; IM[1:20] jsr @OddParity ; Returns -1 if P020 is odd, 0 if even 2 lda 3 m200 and 0 3 ; P020 in pos for Mir1 lda 0 7 2 cycle 4 lda 1 m170000 and 0 1 add 3 1 ; 1/ partial Mir1 control lda 3 4 2 ; 3/ MIRvec sta 1 1 3 ; Partial Mir1 control cycle 14 lda 1 m170000 and 0 1 lda 0 6 2 add 0 1 sta 1 0 3 ; Partial Mir0 control lda 0 7 2 ; IM[1:20] again cycle 10 lda 1 m170000 and 0 1 sta 1 2 3 ; Partial Mir2 control cycle 4 lda 1 m170000 and 0 1 lda 0 mMir3 add 0 1 sta 1 3 3 ; Partial Mir3 control lda 3 5 2 ; 3/ IMvec lda 1 2 3 ; JCN[6:7], IMLHbad, IMRHbad lda 0 1 3 movzl 1 1 movl 0 0 ; 0/ IM[21:40] sta 0 7 2 movl 1 1 snc ; Skip if JCN.7 true jmp IMtoMIRc movl 1 1 movl 1 1 snc ; Skip if bad parity into IMRH mkzero 1 1 skp mkone 1 1 lda 3 mMir2x jmp IMtoMIRd IMtoMIRc: movl 1 1 movl 1 1 snc mkone 1 1 skp mkzero 1 1 lda 3 mMir2 IMtoMIRd: sta 3 6 2 ; 6,2/ Mir2 controls with JCN.7 fixed jsr @OddParity 2 lda 1 m200 and 0 1 lda 3 4 2 ; MIRvec lda 0 3 3 add 0 1 sta 1 3 3 ; Mir3 control barring JCN[3:6] lda 0 7 2 ; IM[21:40] lda 1 m7400 and 0 1 lda 0 1 3 add 0 1 lda 0 mMir1 add 0 1 sta 1 1 3 ; Mir1 controls complete lda 0 7 2 cycle 4 lda 1 m7400 and 0 1 lda 0 6 2 add 0 1 lda 0 2 3 add 0 1 sta 1 2 3 ; Mir2 controls complete lda 0 7 2 cycle 14 lda 1 m7400 and 0 1 lda 0 0 3 add 0 1 sta 1 0 3 ; Mir0 controls complete lda 0 7 2 cycle 10 lda 1 m7400 and 0 1 lda 0 3 3 add 0 1 sta 1 3 3 ; Mir3 controls complete mov 3 0 ; resultis MIRvec jsr @Return mMir0: Mir0 mMir0x: Mir0+200 mMir1: Mir1 mMir2: Mir2 mMir2x: Mir2+200 mMir3: Mir3 m200: 200 m170000: 170000 m7400: 7400 m20000: 20000 ; MIRtoIM(IMvec,MIRvec) transforms MIRvec into IM format and leaves result ; in IMvec .MIRtoIM: sta 3 1 2 jsr @GetFrame 12 jsr @StArgs lda 3 5 2 ; 3/ MIRvec sta 2 MSave2 lda 2 0 3 ; MIR[0:3], MIR[16:19] in l.h. lda 0 m170000 and 0 2 lda 1 2 3 ; MIR[8:11], MIR[24:27] in l.h. ands 0 1 add 1 2 lda 1 1 3 ; MIR[4:7], MIR[20:23] in l.h. and 1 0 cycle 14 add 0 2 lda 0 3 3 ; MIR[12:15], MIR[28:31] in l.h. lda 1 m170000 and 1 0 cycle 4 add 2 0 lda 2 MSave2 sta 0 6 2 ; IM[1:20] lda 2 1 3 lda 0 m7400 and 0 2 lda 1 3 3 ands 0 1 add 1 2 lda 1 0 3 and 1 0 cycle 4 add 0 2 lda 0 2 3 lda 1 m7400 and 1 0 cycle 14 add 2 0 lda 2 MSave2 sta 0 7 2 ; IM[21:40] lda 0 2 3 lda 1 m200 ands 0 1 ; Sign of 1 ← JCN.7 lda 0 0 3 movs 0 0 ; Sign of 0 ← RSTK.0 movzl 0 0 lda 0 6 2 movr 0 0 ; 0 ← IM[0:17], carry ← IM[20] lda 3 4 2 ; 3 ← IMvec sta 0 0 3 lda 0 7 2 movr 0 0 ; 0 ← IM[20:37], carry ← IM[40] sta 0 1 3 movr 1 1 ; 1 ← JCN[6:7] with trailing 0's sta 1 2 3 lda 3 5 2 ; 3 ← MIRvec lda 0 1 3 movs 0 0 ; Sign of 0 ← P020 lda 1 0 3 movs 1 1 ; Sign of 1 ← RSTK.0 ; Strobe bit to the right of P020 and RSTK.0 is 0 so no carry-in to bit 0 addzl 1 0 szc ; Skip if RSTK.0 xor P020 is 0 mkzero 0 0 skp mkone 0 0 lda 1 6 2 jsr @OddParity ; -1 if IM[1:20], RSTK.0, P020 is odd parity 2 lda 1 m20000 and 1 0 ; 20000 if parity wrong else 0 lda 3 5 2 sta 0 5 2 lda 0 3 3 movs 0 0 ; Sign of 0 ← P2141 lda 1 2 3 movs 1 1 ; Sign of 1 ← JCN.7 addzl 1 0 szc ; Skip if JCN.7 xor P2141 is 0 mkzero 0 0 skp mkone 0 0 lda 1 7 2 jsr @OddParity ; 0 if IM[21:40], JCN.7, P2141 is even parity 2 lda 1 m20000 ; 100000 if parity wrong else 0 andzr 1 0 lda 1 5 2 add 1 0 lda 3 4 2 ; 3 ← IMvec lda 1 2 3 ; JCN[6:7] add 1 0 ; JCN[6:7], PE[0:20], PE[21:41] sta 0 2 3 ; Save PE bits in IMvec!2 mov 3 0 ; resultis IMvec jsr @Return riLLINK: LLINK riRLINK: RLINK riRIM0: RIM0 riRIM1: RIM1 riRIM2: RIM2 riRIM3: RIM3 ; ReadIMX(DVec,DVX) reads the IMX location in MADDRL into DVec using ; the vector DVX as temp storage .ReadIMX: sta 3 1 2 jsr @GetFrame 10 jsr @StArgs lda 0 riLLINK lda 1 MADDRL jsr @XctL16C ; XctL16C(LLINK,MADDRL) 2 lda 0 riRIM0 jsr @AXct ; Xct(RIM0) lda 0 riRLINK lda 1 5 2 jsr @XctR16Link ; DVX!0 = RIM0 readout 2 isz 5 2 lda 0 riLLINK lda 1 MADDRL jsr @XctL16C ; XctL16C(LLINK,MADDRL) 2 lda 0 riRIM1 jsr @AXct ; Xct(RIM1) lda 0 riRLINK lda 1 5 2 jsr @XctR16Link ; DVX!1 = RIM1 readout 2 isz 5 2 lda 0 riLLINK lda 1 MADDRL jsr @XctL16C ; XctL16C(LLINK,MADDRL) 2 lda 0 riRIM2 jsr @AXct ; Xct(RIM2) lda 0 riRLINK lda 1 5 2 jsr @XctR16Link ; DVX!2 = RIM2 readout 2 isz 5 2 lda 0 riLLINK lda 1 MADDRL jsr @XctL16C ; XctL16C(LLINK,MADDRL) 2 lda 0 riRIM3 jsr @AXct ; Xct(RIM3) lda 0 riRLINK lda 1 5 2 jsr @XctR16Link ; DVX!3 = RIM3 readout 2 lda 3 5 2 lda 1 -1 3 lda 3 ri777 and 3 0 and 3 1 jsr @OddParity 2 com 0 0 lda 1 ri100000 andzr 1 0 ; PrhOK lda 3 4 2 sta 0 2 3 lda 3 5 2 lda 0 -3 3 lda 1 -2 3 lda 3 ri777 and 3 0 and 3 1 jsr @OddParity 2 com 0 0 lda 1 ri100000 and 1 0 ; PlhOK lda 3 5 2 lda 1 0 3 lda 3 ri3 and 3 1 ; JCN[6:7] add 1 0 lda 3 4 2 lda 1 2 3 add 1 0 cycle 16 sta 0 2 3 ; DVec!2 complete lda 3 5 2 lda 0 -3 3 lda 1 ri777 and 1 0 cycle 7 lda 1 -2 3 lda 3 ri377 andzr 3 1 add 1 0 lda 3 4 2 sta 0 0 3 ; DVec!0 complete lda 3 5 2 lda 0 -1 3 lda 1 ri777 and 1 0 cycle 7 ; 9 bits left-cycled 1 lda 1 -2 3 mkone 3 3 and 3 1 add 1 0 ; 10 bits left-cycled 1 lda 3 5 2 lda 1 0 3 lda 3 ri374 andzr 3 1 add 1 0 cycle 17 lda 3 4 2 sta 0 1 3 ; DVec!1 complete jsr @Return ri777: 777 ri100000: 100000 ri377: 377 ri374: 374 ri3: 3 ; Special kludge to allow address eq length to default the address to ; some reasonable value: SaveTask for task-specific registers or ; MemBase[SaveTask] for BR. ; Have 1/ Length and 0/ AddrVec!1. CertX: sub# 1 0 szr jmp CertBad ; Error if address # memory length jsr CertX1 jmp CertBad ; $ABSOLUTE jmp CUseST ; TPC jmp CUseST ; TLINK jmp CUseST ; OLINK jmp CertBad ; IMBD jmp CertBad ; IM jmp CertBad ; IMX jmp CertBad ; ALUFM jmp CUseST ; T jmp CUseST ; RBASE jmp CUseST ; TIOA jmp CUseST ; MEMBASE jmp CertBad ; RM jmp CertBad ; STK jmp CertBad ; PIPE jmp CUseMB ; BR jmp CertBad ; CACHEA jmp CertBad ; CACHED jmp CertBad ; MAP jmp CertBad ; VM jmp CertBad ; IFUM jmp CertBad ; LDR jmp CertBad ; MDATA jmp CertBad ; MADDR jmp CertBad ; DMUX jmp CertBad ; DHIST jmp CertBad ; VH jmp CUseST ; MD jmp CertBad ; TASKN jmp CertBad ; DEVICE jmp CertBad ; STKX jmp CertBad ; MSTAT jmp CertBad ; $ABS jmp CertBad ; ROW jmp CertBad ; BRX CertX1: lda 0 5 2 add 0 3 jmp 0 3 CUseST: lda 1 SaveTask sta 1 MADDRL ; MADDRL = SaveTask jmp CertOK ; Return MemX CUseMB: lda 1 SaveMBase sta 1 MADDRL jmp CertOK ; CertifyAV(AVec,MemX) returns true if AVec is a legal address in MemX ; else false. .CertifyAV: sta 3 1 2 jsr @GetFrame 10 jsr @StArgs lda 1 5 2 ; MemX lda 3 NMEMS subl# 1 3 szc ; Skip if legal MemX 77400 ; else CallSwat lda 3 4 2 ; AVec lda 0 1 3 sta 0 MADDRL ; MADDRL = AVec!1 lda 0 0 3 sta 0 MADDRH ; MADDRH = AVec!0 lda 3 cVMx sub# 1 3 snr jmp CertVM ; Offset by VMBase if VM Cert2: lda 3 MEMLEN add 1 3 add 1 3 lda 1 0 3 ; MEMLEN!(MemX+MemX) sub# 1 0 szr ; Skip if high parts equal jmp Cert1 lda 1 1 3 ; MEMLEN!(MemX+MemX+1) lda 0 MADDRL Cert1: adcz# 0 1 snc ; Skip if Usc(Addr,Length) < 0 jmp CertX ; Check address eq length kludges CertOK: mkminusone 0 0 skp CertBad: mkzero 0 0 jsr @Return lvVMBase: VMBase pMADDRH: MADDRH lvDoubleAdd: DoubleAdd cVMx: VMx CertVM: lda 0 pMADDRH lda 1 @lvVMBase jsrii lvDoubleAdd 2 lda 0 MADDRH lda 1 5 2 ; MemX jmp Cert2 ; ConvertAV(AVec,MemX) used by PutMemData and GetMemData to error-check ; AVec and perform setup common to both Put and Get .ConvertAV: sta 3 1 2 jsr @GetFrame 10 jsr @StArgs lda 0 4 2 ; AVec lda 1 5 2 ; MemX lda 3 MEMLEN add 1 3 add 1 3 lda 3 1 3 sta 3 6 2 ; Save length for CACHEA/D jsr .CertifyAV ; Check for legal address and leave high part in 2 ; MADDRH, low part in MADDRL mov# 0 0 snr jmp ConM1 lda 1 5 2 ; MemX jsr CAV1 ConABSOL-. ; $ABSOLUTE ConXit-. ; TPC ConST-. ; TLINK ConST-. ; OLINK ConIMBD-. ConXit-. ; IM ConXit-. ; IMX ConXit-. ; ALUFM ConST-. ; T ConST-. ; RBASE ConST-. ; TIOA ConST-. ; MEMBASE ConRM-. ConSTK-. ConSRN-. ; PIPE ConBR-. ConCACHEA-. ConCACHED-. ConMAP-. ConVM-. ConIFUM-. ConLDR-. ConMDATA-. ConMADDR-. ConXit-. ; DMUX ConDH-. ; DHIST ConVH-. ConST-. ; MD ConUnImp-. ; TASKN ConUnImp-. ; DEVICE ConSTKX-. ConMSTAT-. ConABS-. ConUnImp-. ; ROW ConBRX-. CAV1: add 1 3 lda 1 0 3 ; Self-relative pointer add 1 3 lda 0 MADDRL mov 0 1 jmp 0 3 ; Dispatch to setup routine lvErrorAbort: ErrorAbort lvBadAText: BadAText ; Should never get here ConUnImp: ; jsr ConUI1 ; .txt "Ill. memory" ConM1: lda 3 @lvBadAText ConUI1: mov 3 0 jsrii lvErrorAbort 1 77400 ConMSTAT: add 0 0 inczl 0 0 skp ; Address*4+2 ConABS: add 0 0 ; Address*2 sta 0 MADDRL ConABSOL: lda 3 cav177400 ands 3 0 lda 1 cvMCLdHi add 1 0 jsr @MCXct 1 lda 0 MADDRL lda 1 cav377 and 1 0 lda 1 cvMCLdLo add 1 0 jsr @MCXct 1 jmp ConXtX cav177400: 177400 cav377: 377 cvMCLdHi: BCLdHi+BHoldInt+BInt cvMCLdLo: BCLdLo+BHoldInt+BInt lvMDATAtab: MDATAtab lvMADDRtab: MADDRtab ConMDATA: lda 3 @lvMDATAtab ConXt3: add 3 0 ; AVec!1 * 3 + disp add 1 1 jmp ConXt0 ConMADDR: lda 3 @lvMADDRtab add 3 0 ; MADDRtab+(2*AVec!1) jmp ConXt0 ConDH: lda 3 DHistTab jmp ConXt3 ConLDR: addzl 1 1 ; AVec!1 * 4 lda 0 LDRMEM ConXt0: add 1 0 sta 0 MADDRL jmp ConXtX ConVH: lda 3 cv17 and 1 3 sta 3 MADDRL ; Shift count so that DMuxTab!I rshift MADDRL cycle 13 ; right-justifies the bit movl 0 0 snc ; Skip if in word 1 mkone 0 0 skp mkzero 0 0 sta 0 MADDRH ; 0 for addresses 16 to 31, 1 for 0 to 15 ConXtX: lda 0 5 2 jsr @Return ConRM: lda 3 cv17 and 1 3 sta 3 MADDRL ; MADDRL ← RSTK value lda 3 cv360 and 3 0 cycle 14 mov 0 1 lda 0 cLRB0 jsr @XctLFF ; XctLFF(LRB0,(orig. MADDRL rshift 4) & 17B) 2 jmp ConXtX ConM1R: mkminusone 0 0 jsr @Return ConSTKX: lda 0 @lvSaveSTKP lda 3 cav77 and 0 3 ; Only 100 words of STK accessible at-a-time sub 1 0 ; 0/ address if ok sub 1 3 ; negative if off end of stack movl# 3 3 szc jmp ConM1R ; return -1 (an illegal MemX) if off end ConSTK: jsr @XctL16Q 1 lda 0 cSTKPFQ jsr @AXct mkzero 0 0 ConST: jsr @SelectTask 1 sta 0 OldTask jmp ConXtX cSTKPFQ: STKPFQ cLRB0: LRB0 cv360: 360 lvSaveSTKP: SaveSTKP cav77: 77 cv17: 17 cLMBSX0: LMBSX0 ; Midas uses task 17 for everything because ASRN changes, so only ; tasks 0 and 17 are feasible, and smashing the pipe state of task 17 ; is less frequently harmful. ConBRX: jsr SelT17SRN1 lda 0 cLMBSX0 jmp ConBX1 ; XctLFF(LMBSX0,MADDRL) ConBR: jsr SelT17SRN1 lda 0 cLMB0 ConBX1: lda 1 MADDRL jsr @XctLFF ; XctLFF(LMB0,MADDRL) 2 lda 0 McrBR jsr @XctL16T ; XctL16T(DisHold+DisCF+NoWake) 1 lda 0 cMCRFT ; Xct(MCRFT) jmp ConXX ConCACHEA: ; 0,1/ 2-bit column..n-bit row, n = 6 (4k) or 10 (16k) lda 1 6 2 ; CACHEA length neg 1 1 com 1 1 ; CACHEA length-1 movzr 1 3 movzr 3 3 ; 3/ word mask sub 3 1 ; 1/ column mask and 0 3 ; 3/ word (row) bits and 1 0 lda 1 @lvAColumnShift ; 5 (4k) or 3 (16k) cycle 0 sta 0 MADDRL ; MADDRL/ 2-bit col in pos for UseMcrV mov 3 0 cycle 4 ; Position address bits to address a munch (= row) sta 0 MADDRH jsr SelT17SRN1 jmp ConXit ConCACHED: ; 0,1/ 2-bit column..n-bit row..4-bit word lda 1 6 2 ; CACHED length neg 1 1 com 1 1 ; length-1 movzr 1 3 movzr 3 3 ; 3/ word mask sub 3 1 ; 1/ column mask and 0 3 sta 3 MADDRH ; MADDRH/ word bits = row..word-in-munch and 1 0 ; for Fetch/Store lda 1 @lvDColumnShift ; 1 (4k) or 17 (16k) cycle 0 sta 0 MADDRL jsr SelT17SRN1 lda 0 lvMADDRH ; DVec of MADDRH and MADDRL jsrii lvRdCACHEA 1 lda 3 McrCD0 ; NoWake+DisHold ; **Used to use just Vacant for CACHED reads, Vacant+WP for writes lda 1 FlagsCD0 ; Vacant+WP and# 1 0 szr lda 3 McrCD1 ; NoWake+DisCF+DisHold mov 3 0 jmp ConCD0 ; Rest of setup same as VM ; Left-shift the Map address by log2pgsize; then rest of setup is ; identical to VM references. ConMAP: lda 3 @lvlog2pgsize neg 3 3 lda 1 MADDRH movzl 0 0 ; left-shift low part of address movl 1 1 ; left-shift high part inc 3 3 szr jmp .-3 sta 1 MADDRH sta 0 MADDRL ConVM: jsr SelT17SRN1 ; OldTask = SelectTask(17) ; ProcSRN←1, MemBase←36, Save BR 36 if necessary lda 0 McrVM ConCD0: jsr @XctL16T ; T←NoWake 1 lda 0 cMCRFT jsr @AXct lda 0 MADDRH jsr @XctL16T ; T←MADDRH 1 lda 0 cvBRHIFT jsr @AXct ; BRHI←T lda 0 MADDRL jsr @XctL16T ; T←MADDRL 1 lda 0 cvBRLOFT ; BRLO←T jsr @AXct mkzero 0 0 jsr @XctL16T ; T←0 1 mkzero 0 0 ; Noop ConXX: jsr @AXct ConXit: lda 0 5 2 ; resultis MemX jsr @Return ConSRN: jsr @XctL16T 1 lda 0 cSRNFT jmp ConXX ; Xct(SRNFT) cvBRLOFT: BRLOFT cvBRHIFT: BRHIFT cBRKINSFQ: BRKINSFQ cMCRFT: MCRFT cSRNFT: SRNFT cLMB0: LMB0 cISEVFQ: ISEVFQ cIFRES: IFRES cv40000: 40000 cv36: 36 cv177400: 177400 cv100000: 100000 McrCD1: McrBR: DisHold+DisCF+NoWake McrVM: NoWake lvAColumnShift: AColumnShift lvDColumnShift: DColumnShift lvlog2pgsize: log2pgsize lvMADDRH: MADDRH lvRdCACHEA: RdCACHEA McrCD0: NoWake+DisHold FlagsCD0: Cvacant+Cwp cav17: 17 SelT17SRN1: sta 3 6 2 lda 0 cav17 jsr @SelectTask 1 sta 0 OldTask mkone 0 0 jsr @XctL16T ; T←1 1 lda 0 cSRNFT jsr @AXct ; ProcSRN←T ; BR 36, used for memory system access, is saved the first time a memory ; system word is accessed rather than by ReadAllRegs because a consequence ; of saving BR 36 is that pipe entry 1 is smashed. This means that ; fault task breakpoints are ok provided that none of CACHEA, VNV, CACHED, ; MAP, or VM is displayed, and other task breakpoints are always ok unless ; they use SRN 1 (which would violate the programming convention). lda 1 cv36 lda 0 cLMB0 jsr @XctLFF ; MemBase←36S 2 lda 0 @lvBR36Saved mov# 0 0 szr ; Skip if haven't saved BR 36 since b.p. jmp @6 2 ; Done if already saved lda 0 @lvBreakTask lda 1 cav17 sub 0 1 szr ; Skip if breakpoint for task 17 jmp srn1a lda 0 CantContinue lda 1 cMemDisplayed and# 0 1 snr add 1 0 sta 0 CantContinue ; Indicate that "Continue" is illegal srn1a: lda 0 McrBR jsr @XctL16T ; T←DisHold+DisCF+NoWake 1 lda 0 cMCRFT jsr @AXct ; Mcr←T mkzero 0 0 jsr @XctL16T ; T←0 1 lda 0 cDUMMYFT jsr @AXct ; DummyRef←T mkzero 0 0 jsr @AXct ; Noop lda 1 @lvSaveBR36 lda 0 cRVAHI jsr @XctR16C ; XctR16C(RVAHI,SaveBR36) 2 lda 1 @lvSaveBR36 inc 1 1 lda 0 cRVALO jsr @XctR16C ; XctR16C(RVALO,SaveBR36+1) 2 mkminusone 0 0 sta 0 @lvBR36Saved ; Indicate BR 36 saved jmp @6 2 cDUMMYFT: DUMMYFT cRVAHI: RVAHI cRVALO: RVALO lvBR36Saved: BR36Saved lvSaveBR36: SaveBR36 lvBreakTask: BreakTask cMemDisplayed: 100 ; **Should be symbolic but def in mcommon.d cIFUMdisplayed: 400 ; **Should be symbolic but in mcommon.d ; Needed by MGetMemData for ROW to setup for victim/next-victim read. .SelFltSrn: sta 3 1 2 jsr @GetFrame 10 jsr @StArgs jsr SelT17SRN1 jsr @Return ConIFUM: lda 0 cIFRES jsr @AXct ; Xct(IFRES) lda 1 MADDRL lda 0 cv177400 and 1 0 ; 0/ insset in bits 6:7 lda 1 cv100000 add 1 0 ; 100000+(insset lshift 8) jsr @XctL16Q ; XctL16Q((MADDRL & 1400B)+100000B) 2 lda 0 cISEVFQ jsr @AXct ; Xct(ISEVFQ) lda 0 CantContinue lda 1 cIFUMdisplayed and# 0 1 snr add 1 0 sta 0 CantContinue lda 0 MADDRL movs 0 0 jsr @XctL16Q ; XctL16Q(MADDRL lshift 8) 1 lda 0 cBRKINSFQ jsr @AXct ; Xct(BRKINSFQ) mkzero 0 0 jmp ConXX ; Xct(NOOP) and return ; Have to make BNPC have 0 during the test. To do this, arrange for ; PEnc eq #17 and TPC[#17] eq 0. Do Notify[#17] with Freeze off to get ; Ready.15 true. For restore, must reload task 17's TPC and do ClrReady. ConIMBD: mkzero 0 0 jsr @SelectTask 1 sta 0 OldTask ; OldTask = SelectTask(0) lda 1 cav17 lda 0 cvRTPC jsr @XctL16C ; ReadTPC←17 2 lda 1 lvOldTPC lda 0 cvRLINK jsr @XctR16Link ; Save old TPC[17] for restore 2 mkzero 1 1 lda 0 cvLLINK jsr @XctL16C ; Link←0 (value for TPC[17]) 2 lda 1 cav17 lda 0 cvLTPC jsr @XctL16C ; LoadTPC←17 (loads 0 into TPC 17) 2 mkzero 0 0 jsr @AXct ; Noop lda 0 cWAKE17 lda 1 LDRMEM add 1 0 jsr .LoadMIR ; LoadMIR(WAKE17) 1 lda 0 sControlSS DStrobe ; Single-step with Freeze off lda 0 cvRLINK mkminusone 1 1 jsr @XctL16 ; XctL16(RLINK,-1) puts 0 on BMux for write 2 ; lda 0 cvClearMIR ; DStrobe ; Clear MIR so TNIA is 0 (necessary?) ; lda 0 cvControl ; DStrobe ; DoStrobe(Control) turning off ClrMIR lda 0 MADDRL lda 1 cv77 and 1 0 lda 1 cvIMAddr1 add 1 0 jsrii lvLoadDMD ; LoadDMD(IMAddr1+(MADDRL & #77)) 1 lda 0 MADDRL cycle 12 lda 1 cv77 and 1 0 lda 1 cvIMAddr0 add 1 0 jsrii lvLoadDMD ; LoadDMD(IMAddr0+((MADDRL rshift 6) & #77)) 1 lda 0 MADDRL cycle 4 lda 1 cv3 and 1 0 lda 1 cvIMAddr2 add 1 0 jsrii lvLoadDMD ; LoadDMD(IMAddr2+((MADDRL rshift 12) & 3)) 1 ; (needed after expansions to 16K microstore) lda 0 5 2 jsr @Return ; resultis MemX cvRTPC: RTPC lvOldTPC: OldTPC cvRLINK: RLINK cvLLINK: LLINK cvLTPC: LTPC cWAKE17: WAKE17 ;cvClearMIR: Control+ClrStop+ClrMIR cvControl: Control lvLoadDMD: LoadDMD cv77: 77 cvIMAddr0: IMAddr0 cvIMAddr1: IMAddr1 cvIMAddr2: IMAddr2 cv3: 3 ; Subroutine to load MIR, pointer to 4-word MIR vec in 0 .LoadMIR: sta 3 1 2 mov 0 1 lda 0 sControl MIRLoad ; **Check for MIR parity disagreeing with load ; lda 0 SStopped ; sta 0 @D1Out lda 3 1 2 jmp 1 3 ; Subroutine to load CPReg .LoadCPReg: sta 3 1 2 movs 0 1 lda 3 z177400 and 3 0 ; 0←value for CPReg0 and 3 1 ; 1←value for CPReg1 lda 3 zCPReg1 add 3 1 lda 3 sCPReg0 add 3 0 DStrobe mov 1 0 FStrobe: lda 3 1 2 ; DoStrobe(Value) does a three step strobing sequence using value .DoStrobe: DStrobe jmp 1 3 zCPReg1: CPReg1 z177400: 177400 ; Stop() halts the D1 which must be or have been running .Stop: lda 0 sStop jmp .DoStrobe sStop: Control+SetRun+SetSS ; Procedure returning true if D1 has stopped, else false .CheckStopped: lda 0 SStopped sta 0 @D1Out ; Point D1In at ESTAT word containing "Stopped" lda 1 CStopped lda 0 @D1In and 1 0 snr jmp CSret0 ; Check again to make sure (suspected flakiness here at one time) CSyes: lda 0 SStopped sta 0 @D1Out lda 0 @D1In and 1 0 szr jmp CSret1 sta 3 1 2 lda 3 @lvCheckStoppedGlitches isz 0 3 jmp .+1 lda 3 1 2 CSret0: mkzero 0 0 skp ; return 0 if not stopped CSret1: mkminusone 0 0 ; -1 if stopped jmp 1 3 SStopped: Mir0+InErr2 CStopped: Stopped lvCheckStoppedGlitches: CheckStoppedGlitches ; ContinueProgram(GoVec) .ContinueProgram: sta 3 1 2 jsr @GetFrame 10 jsr @StArgs lda 0 @lvBreakMIR jsr .LoadMIR ; Load MIR with break inst, clearing Freeze 1 jmp CGo1 lvBreakMIR: BreakMIR sClock: Clock sControlSS: Control+SetRun+SetSS sControl: Control sControlC: Control+ClrStop sClockUC: Clock+UseCPReg+ClrReady sClockU: Clock+UseCPReg cSTARTX: STARTX ; Start(GoV) sets up to start the microprocessor at a new address. ; GoV!1 is the address .Start: sta 3 1 2 jsr @GetFrame 10 jsr @StArgs lda 0 sClockUC DStrobe ; Turn on UseCPReg (needed for Rep-Go and Rep-SS) ; Clear Ready flipflops lda 0 sClockU DStrobe ; Turn off ClrReady ; *Cannot do a SelectTask here for Rep-Go or Rep-SS because finding ; *out the current task by ReadDMux takes too long lda 3 4 2 lda 1 1 3 ; GoV!1 = address for start lda 0 STLLINK jsr @XctL16C ; XctL16C(LLINK,GoV>>Go.Addr) 2 ; Following code = XctL16C(STARTX,SaveLINK) except that Freeze is ; turned off lda 0 cSTARTX lda 3 LDRMEM add 3 0 jsr .LoadMIR ; MIR←STARTX instruction, clear Stop and Freeze 1 ; Note that LINK is loaded with GoV>>Go.Addr while TLINK is not, but don't ; care about TLINK since the branch computation is from LINK. lda 0 SaveLINK com 0 0 jsr .LoadCPReg ; CPReg←SaveLINK 1 lda 0 sControlSS DStrobe ; SingleStep RETURN, B←RWCPREG with Freeze off lda 0 sControl DStrobe ; DoStrobe(Control), clearing SetRun first lda 0 sControlC DStrobe ; DoStrobe(Control+ClrStop), clearing Stop lda 0 sControl DStrobe ; DoStrobe(Control), clearing ClrStop CGo1: lda 0 sClock DStrobe ; Turn off UseCPReg jsr @Return sNorm: Control+Freeze sCPReg0: CPReg0 cRTPC: RTPC cRLINK: RLINK cRT: RT cTFPTRS: TFPTRS STLLINK: LLINK cLTPC: LTPC cTFTIOA: TFTIOA ST17400: 17400 ST17: 17 STClear: Control+ClrCT STJam: Control+Jam STGetTLINK: Clock+UseCPReg+GetTLINK ; SelectTask(Task) .SelectTask: sta 3 1 2 jsr @GetFrame 10 jsr @StArgs lda 0 4 2 lda 1 SaveTask sub# 0 1 snr jsr @Return ; if (Task eq SaveTask) then resultis Task sta 1 6 2 sta 0 SaveTask lda 1 SaveTPC sta 1 5 2 mkzero 0 0 jsr @AXct ; Xct(NOOP) to finish t3 and t4 of last instr lda 1 SaveTask lda 0 cRTPC jsr @XctL16C ; XctL16C(RTPC,Task) 2 lda 0 cRLINK lda 1 lvSaveTPC jsr @XctR16Link ; SaveTPC = XctR16Link(RLINK,lv SaveTPC) 2 lda 0 STLLINK lda 1 SaveLINK jsr @XctL16C ; XctL16C(LLINK,SaveLINK) 2 mkzero 0 0 jsr @AXct ; Xct(NOOP) lda 0 4 2 movs 0 3 cycle 14 add 3 0 lda 1 sCPReg0 add 1 0 DStrobe ; DoStrobe(CPReg0+(Task lshift 8)+(Task lshift 12)) lda 0 STClear DStrobe ; DoStrobe(Control+ClrCT) lda 0 STJam DStrobe ; DoStrobe(Control+Jam) lda 0 sNorm DStrobe ; DoStrobe(Control+Freeze) lda 0 STGetTLINK DStrobe ; DoStrobe(Clock+UseCPReg+GetTLINK) mkzero 0 0 jsr @AXct ; Xct(NOOP) lda 0 cRLINK lda 1 lvSaveLINK jsr @XctR16Link 2 com 0 0 sta 0 SaveLINK ; SaveLINK = not XctR16Link(RLINK,lv SaveLINK) lda 0 cRT lda 1 lvSaveT ; PE here goes undetected and the machinations with reading and writing ; T cause bad parity to be rewritten correctly so that ScanForPE won't ; work. jsr @XctR16 ; XctR16(RT,lv SaveT) 2 lda 0 cTFPTRS jsr @AXct lda 0 cRT lda 1 lvSaveRBase jsr @XctR16 2 lda 1 ST17 and 0 1 sta 1 SaveRBase ; SaveRBase = SaveRBase<<Pointers.RBase lda 1 ST17400 ands 0 1 sta 1 SaveMBase ; SaveMBase = XctR16(RT,lv SaveRBase)<<Pointers.MemBase lda 0 cTFTIOA jsr @AXct lda 0 cRT lda 1 lvSaveTIOA jsr @XctR16 ; SaveTIOA = XctR16(RT,lv SaveTIOA) 2 lda 0 SaveT jsr @XctL16T ; XctL16T(SaveT) 1 mkzero 0 0 jsr @AXct ; Xct(NOOP) lda 0 STLLINK lda 1 5 2 jsr @XctL16C ; XctL16C(LLINK,OldTPC) 2 ; Since we don't need TLINK valid, ok to not do NOOP here lda 0 cLTPC lda 1 6 2 jsr @XctL16C ; XctL16C(LTPC,OldTask) 2 ; **This NOOP may be unnecessary mkzero 0 0 jsr @AXct ; Xct(NOOP) lda 0 STLLINK lda 1 SaveLINK jsr @XctL16C ; XctL16C(LLINK,SaveLINK) 2 mkzero 0 0 jsr @AXct ; Xct(NOOP) lda 0 6 2 jsr @Return ; resultis OldTask lvSaveTPC: SaveTPC lvSaveLINK: SaveLINK lvSaveT: SaveT lvSaveRBase: SaveRBase lvSaveTIOA: SaveTIOA .end