HP11305 Disk Controller Microcode --------------------------------- 00 : 5ED18 Clear CtrlOut goto(18) 18 : 0BF19 Clear Data Path goto(19) 19 : 5FC1A Set CRC to WD ClrSktst goto(1A) 1A : 3FD1B Set SR A SOut En goto(1B) 1B : 7D71C Clear SR A Sout En goto(1C) 1C : 05A1D Clr SIn En Clear SR A En Clear A Sel goto(1D) 1D : 85B1E Clear B Sel Clear SR to D goto(1E) 1E : 74B7E Clear D to SR Clear CRC to WD goto(7E) Power on initialisation.Disable shift registers and data transfer. ---- ** Main Command Loop ** ---- 7E : 9BF1F ClrCacheAddr goto(1F) Start of main loop. Clear cache memory address counter 1F : ABF20 LdAddr goto(20) Clear drive selected flag flip-flop (ROM PCB U8b) 20 : 5ED21 Clear CtrlOut goto(21) 21 : FFF22 goto(22) 22 : FFF23 goto(23) 23 : FFFF8 goto(F8) Delay for 4 microcycles F8 : FFFE3 pause(Request),goto(E3) Wait for a calculator to request access to the disk controller. E3 : 5FD13 ClrSktst pause(CalcStb),goto(13) Clear seek error flag, wait for calculator to select drive 13 : FFF14 goto(14) 14 : FFFF5 goto(F5) Wait for a couple of microcycles F5 : AAE6F LdAddr SetHdEn if(AddrSel)goto(6f,4f) Strobe calculator outputs to address register. If AddrSel is asseted by the HP9830 at this point, the software has got out of step with the controller So treat this as an illegal command and do a restore, etc. 4F : FFF24 goto(24) THis is a valid command 24 : B7B25 Set Head Clr SR A goto(25) Set drive head and sector select. Clear first shift register 25 : BF7F3 Stat goto(F3) Send 'OK' to calculator F3 : FFF26 pause(CalcStb),goto(26) Wait for calculator strobe (to drive select latch). 26 : ABF27 LdAddr goto(27) Load Cylinder to address register 27 : 5BF28 Clear CycSel goto(28) Clear cycle length select 28 : BED29 SetCylEn goto(29) 29 : FFF2A goto(2A) 2A : BD72B SetCyl goto(2B) Set drive cylinder 2B : FFF2C goto(2C) 2C : DEECE SetCmd goto(CE) Set drive command CE : FFF6F if(CmdOK)goto(6f,2f) Is the command valid? Go to the illegal comamnd routine if the cylidner is out of range, or a similar problem. 2F : 37FE9 Tr On goto(E9) Enable data transfer E9 : FFFEF pause(SectorFnd),goto(EF) Wait for the sector to come round EF : FFF7F if(Format)goto(7f,7b) Is this an initialise command (Init switch setting is checked in hardware)? ---- ** Illegal Command Error ** ---- 6F : 9FD2D Set Calc Ib goto(2D) Restore. Send 'Command Error' to calculator 2D : BF72E Stat goto(2E) Send 'OK' to calculator. 2E : B577E Set Head SetCyl goto(7E) Asserting Set Cylinder and Set Head will cause the drive to restore to cylinder 0. Then go back to get another command ---- ** Initialise Command ** ---- 7B : 5FC30 Set CRC to WD ClrSktst goto(30) Disable Shift register serial outputs, clear calculator status signals and cycle counter 30 : 7CB46 Clear CRC to WD goto(46) Completely disable write data line to drive (other drivers disabled by previous instruction Go to write sector routine ---- ** Read and Write commands ** ---- First read the header and check the sector address 7F : 5FE31 Set CRC to WD goto(31) Disable shift register outputs 31 : 57D32 Tr Off ClrSktst goto(32) Force drive into read mode (even if it's a write command) 32 : FFF33 goto(33) skip a cycle 33 : DEE34 SetCmd goto(34) Load drive command 34 : 17EFA Set Inst SR Clock Clear SR A En goto(FA) Disable shift register A FA : A7F35 Set Ctrl Out pause(SectorPulse),goto(35) Start reading and wait for sector pulse 35 : 78B36 Set MClkSel Clear CRC to WD goto(36) Select PLL clock from data separator (for reading) 36 : 8BFE7 Clear SR B Load goto(E7) Disable shift register B E7 : 3CBC0 Set Rd Sync pause(RdFnd),goto(C0) Wait for '1' bit in preamble C0 : 1FD37 Set CCLk En pause(Cyc15),goto(37) Start cycle counter, wait for rest of preamble 37 : 1AD38 Set SR B En Set SIn En goto(38) 38 : FFFC1 goto(C1) C1 : FFF39 pause(HCyc7),goto(39) Read first address byte into shift register B 39 : 8AE3A Clear SR B Load Set SR A En goto(3A) 3A : FFFD1 goto(D1) D1 : FFF3B pause(HCyc7),goto(3B) And second address byte into shift register A 3B : 03E3C Clear Data Path Clr SIn En Clear SR A En goto(3C) Disable shifting 3C : 7EE3D Clear MClkSel goto(3D) Select the crystal clock 3D : FFF3E goto(3E) 3E : 5EDE6 Clear CtrlOut goto(E6) Stop drive reading E6 : FFF5F if(AddrEq)goto(5f,57) Is this the right sector? 5F : 37F6F Tr On goto(6F) No, go round again to get new address. ---- ** Sector found, now start data transfer ** ---- 57 : BF3D3 Clr SR A Stat goto(D3) Clear shift register A, send status signal to calculator D3 : 37F3F Tr On pause(CalcStb),goto(3F) Wait for calculator strobe (offset address) 3F : BFE40 ClrCRC goto(40) Clear CRC generator 40 : AAE42 LdAddr SetHdEn goto(42) Load offset address into address register, enable head address to drive Outbus 42 : FFF44 goto(44) 44 : B7FF2 Set Head goto(F2) Strobe head address into drive F2 : 5FDD9 ClrSktst if(DrWr)goto(d9,c9) Go to appropriate read or write sector routine ---- ** Read Sector ** ---- C9 : DEE63 SetCmd pause(SectorFnd),goto(63) Send (read) command to drive, wait for drive hardware to find the sector 63 : FFF64 goto(64) Wait for cable buffers to settle 64 : A7FEA Set Ctrl Out goto(EA) Strobe command into drive EA : 5BF65 Clear CycSel pause(SectorPulse),goto(65) Select short cycle counts and clear cycle counter. Wait for next sector pulse 65 : 7BF66 Set MClkSel goto(66) Select PLL clock from data separator (for reading) 66 : FFF67 goto(67) 67 : 3CBF7 Set Rd Sync goto(F7) F7 : FFFB0 pause(RdFnd),goto(B0) Wait for header word '1' to be found B0 : 1FC68 Clear SR A En Set CCLk En pause(Cyc15),goto(68) Read rest of preamble 68 : 67F69 Set Sin to CRC goto(69) 69 : 47FD0 Set CRC Clock En goto(D0) Start reading words into the CRC register D0 : 8BF6A Clear SR B Load pause(Cyc15),goto(6A) Skip address word 6A : 12D6B Set SR B En Set Inst SR Clock Set SIn En goto(6B) 6B : FFFFD goto(FD) FD : FFF6C pause(HCyc7),goto(6C) Read a byte into shift register B 6C : 8866D Clear SR B Load Set SR A En Set B Sel(b) goto(6D) Start reading into shift register A 6D : 6BF6E Set SR to D goto(6E) Enable transfer from shift register B to cache 6E : BE7BD CacheStart goto(BD) Start of data transfer loop. Write data into cache BD : FFF70 pause(HCyc7),goto(70) Wait for next byte to be transfered 70 : 1BE71 Set SR B En Clear SR A En goto(71) Start reading data into shift register B 71 : 87FEB Clear B Sel goto(EB) EB : 3FB43 Set A Sel(a) if(EoCache)goto(43,41) Enable transfer from shift register A to cache, check to see if entire sector has been read 43 : BE7DD CacheStart goto(DD) No, write next byte to cache DD : FFF73 pause(HCyc7),goto(73) Wait for byte to be read from disk 73 : 8AE74 Clear SR B Load Set SR A En goto(74) 74 : 3DB75 Clear A Sel goto(75) Read data into shift register A 75 : BC76E Set B Sel(b) goto(6E) Enable transfer from shift register B to cache and go round again 41 : BE7CD CacheStart goto(CD) Yes, all data bytes have been read. Write final byte to cache CD : FFF72 pause(HCyc7),goto(72) 72 : 89B76 Clear SR B Load Clear SR to D goto(76) 76 : FFFAD goto(AD) AD : 05B77 Clr SIn En Clear A Sel pause(HCyc7),goto(77) Disable data shift registers, read CRC field into CRC register 77 : 0BF78 Clear Data Path goto(78) Disable CRC register clock and cycle counter clock 78 : 7EE79 Clear MClkSel goto(79) Select crystal clock 79 : FFFF4 goto(F4) F4 : 5ED7D Clear CtrlOut if(CRCZero)goto(7d,7c) Check CRC to see if sector has been read correctly. If so, go to end of command routine 7D : 7EB17 Set Calc Ia goto(17) CRC error : Set calculator error flag. Ia = CWE (Check Word Error) 17 : BF716 Stat goto(16) And command completed flag 16 : FFF7E goto(7E) Go back and get another command ---- ** Write Sector ** ---- D9 : FFF46 pause(SectorFnd),goto(46) Wait for drive to find sector, then start writing ---- ** Write data to drive, used by write sector and initialise commands ** ---- 46 : DEE48 SetCmd goto(48) Send command to drive 48 : BCB49 Set CycSel goto(49) Select long cycle counts 49 : A7FF1 Set Ctrl Out goto(F1) Send drive control strobe, start drive writing F1 : 13D4A Set SR B En Set Inst SR Clock Set CCLk En pause(HCyc7),goto(4A) Enable clock to shift register B, enable shift register clock, enable cycle counter. 4A : 07F4B Clr SIn En goto(4B) Disable shift register B clock, force 1 so serial input 4B : FFFFC goto(FC) Skip a cycle FC : FFF4C pause(HCyc12),goto(4C) Wait while writing preamble 4C : 5994D Clear CycSel ClrSktst Set SR B SOut En goto(4D) Select short cycle counts, clear cycle counter, select SR B and enable path to write data encoder 4D : 23F81 Set SR A Load Set SR B Load goto(81) Enable loading of both shift registers, 81 : 3FD4E Set SR A SOut En pause(HCyc7),goto(4E) Enable shift register A to write data encoder, pause while transferred to drive -- write header sync word 4E : 12350 Set SR B En Set Inst SR Clock Set B Sel(a) Set Addr to SR goto(50) Enable clock to Shift register B, enable shift register clock, enable buffers from address registers to SR, load address words into shift registers 50 : BE791 CacheStart goto(91) Read a word from the cache for the first time in the data write loop 91 : 83F51 Clear SR B Load Clear B Sel pause(HCyc7),goto(51) Disable shift register B 51 : 9EC52 Set SR A En Set A Sel(b) goto(52) Enable shift register A, enable data transfer to A 52 : 413A1 Set SOUT to CRC Set CRC Clock En Set SR B SOut En Clear SR A Sout En goto(A1) Enable SR to CRC generator, start CRC generator running, select shift register B. Preamble written, address words in shift registers, cache read. Now start the data transfer loop to write the address and data words to the disk. -- A1 : 19A53 Set SR B En Clear SR A En Clear A Sel pause(HCyc7),goto(53) Transfer SR B to drive, disable SR A 53 : 26954 Set SR B Load Set D to SR Set B Sel(a) goto(54) Load SR B from cache. 54 : 3FD55 Set SR A SOut En goto(55) Enable shift register A to write data encoder and CRC generator 55 : 82E56 Clear SR B Load Clear B Sel Set SR A En goto(56) Start shift register A transferring to drive and CRC generator 56 : BE7B1 CacheStart goto(B1) Read next word from cache B1 : FFF58 pause(HCyc7),goto(58) Wait for shift register transfer to finish. 58 : 2BB59 Set SR A Load Set A Sel(a) goto(59) Load shift A from cache 59 : 7D3FB Set SR B SOut En Clear SR A Sout En goto(FB) Enable shift register B to write data encoder and CRC generator FB : 19A47 Set SR B En Clear SR A En Clear A Sel if(EoCache)goto(47,45) Start shift register B transfer, test if at end of cache 47 : BE7A1 CacheStart goto(A1) Round again if not at end of cache 45 : FFFE1 goto(E1) Skip a cycle E1 : 77F5A Clear D to SR pause(HCyc7),goto(5A) Disable cache transfers to shift registers 5A : 8BF5B Clear SR B Load goto(5B) 5B : 3FDED Set SR A SOut En goto(ED) ED : 9EE5C Set SR A En pause(HCyc7),goto(5C) Complete writing last byte from cache 5C : 1FE5D Clear SR A En goto(5D) Disable data shift registers 5D : 5D6F0 Set CRC to WD Clear SR A Sout En goto(F0) Start transferring CRC register to drive F0 : FFF5E pause(Cyc15),goto(5E) Wait for this to complete 5E : 7CB60 Clear CRC to WD goto(60) Disable CRC register 60 : FFFE0 goto(E0) E0 : FFF15 pause(Cyc15),goto(15) 15 : FFFA0 goto(A0) A0 : FFF61 pause(Cyc15),goto(61) Write postamble (2 words of zeros) 61 : 5ED62 Clear CtrlOut goto(62) Turn off drive write enable. 62 : 03F7C Clear Data Path Clr SIn En goto(7C) Stop CRC and cycle clocks ---- ** End of command ** ---- 7C : BF77A Stat goto(7A) Send command complete signal to calculator 7A : 5FD7E ClrSktst goto(7E) End of command, back to start of main loop. ---- ** Unused states ** ---- 01 : 0CF78 goto(78) 02 : 0CF78 goto(78) 03 : 0CF78 goto(78) 04 : 0CF78 goto(78) 05 : 0CF78 goto(78) 06 : 0CF78 goto(78) 07 : 0CF78 goto(78) 08 : 0CF78 goto(78) 09 : 0CF78 goto(78) 0A : 0CF78 goto(78) 0B : 0CF78 goto(78) 0C : 0CF78 goto(78) 0D : 0CF78 goto(78) 0E : 0CF78 goto(78) 0F : 0CF78 goto(78) 10 : 0CF78 goto(78) 11 : 0CF78 goto(78) 12 : 0CF78 goto(78) 80 : 0CF78 pause(Cyc15),goto(78) 82 : 0CF78 if(DrWr)goto(78,68) 83 : 0CF78 pause(CalcStb),goto(78) 84 : 0CF78 if(CRCZero)goto(78,78) 85 : 0CF78 if(AddrSel)goto(78,58) 86 : 0CF78 if(AddrEq)goto(78,70) 87 : 0CF78 pause(RdFnd),goto(78) 88 : 0CF78 pause(Request),goto(78) 89 : 0CF78 pause(SectorFnd),goto(78) 8A : 0CF78 pause(SectorPulse),goto(78) 8B : 0CF78 if(EoCache)goto(78,78) 8C : 0CF78 pause(HCyc12),goto(78) 8D : 0CF78 pause(HCyc7),goto(78) 8E : 0CF78 if(CmdOK)goto(78,38) 8F : 0CF78 if(Format)goto(78,78) 90 : 0CF78 pause(Cyc15),goto(78) 92 : 0CF78 if(DrWr)goto(78,68) 93 : 0CF78 pause(CalcStb),goto(78) 94 : 0CF78 if(CRCZero)goto(78,78) 95 : 0CF78 if(AddrSel)goto(78,58) 96 : 0CF78 if(AddrEq)goto(78,70) 97 : 0CF78 pause(RdFnd),goto(78) 98 : 0CF78 pause(Request),goto(78) 99 : 0CF78 pause(SectorFnd),goto(78) 9A : 0CF78 pause(SectorPulse),goto(78) 9B : 0CF78 if(EoCache)goto(78,78) 9C : 0CF78 pause(HCyc12),goto(78) 9D : 0CF78 pause(HCyc7),goto(78) 9E : 0CF78 if(CmdOK)goto(78,38) 9F : 0CF78 if(Format)goto(78,78) A2 : 0CF78 if(DrWr)goto(78,68) A3 : 0CF78 pause(CalcStb),goto(78) A4 : 0CF78 if(CRCZero)goto(78,78) A5 : 0CF78 if(AddrSel)goto(78,58) A6 : 0CF78 if(AddrEq)goto(78,70) A7 : 0CF78 pause(RdFnd),goto(78) A8 : 0CF78 pause(Request),goto(78) A9 : 0CF78 pause(SectorFnd),goto(78) AA : 0CF78 pause(SectorPulse),goto(78) AB : 0CF78 if(EoCache)goto(78,78) AC : 0CF78 pause(HCyc12),goto(78) AE : 0CF78 if(CmdOK)goto(78,38) AF : 0CF78 if(Format)goto(78,78) B2 : 0CF78 if(DrWr)goto(78,68) B3 : 0CF78 pause(CalcStb),goto(78) B4 : 0CF78 if(CRCZero)goto(78,78) B5 : 0CF78 if(AddrSel)goto(78,58) B6 : 0CF78 if(AddrEq)goto(78,70) B7 : 0CF78 pause(RdFnd),goto(78) B8 : 0CF78 pause(Request),goto(78) B9 : 0CF78 pause(SectorFnd),goto(78) BA : 0CF78 pause(SectorPulse),goto(78) BB : 0CF78 if(EoCache)goto(78,78) BC : 0CF78 pause(HCyc12),goto(78) BE : 0CF78 if(CmdOK)goto(78,38) BF : 0CF78 if(Format)goto(78,78) C2 : 0CF78 if(DrWr)goto(78,68) C3 : 0CF78 pause(CalcStb),goto(78) C4 : 0CF78 if(CRCZero)goto(78,78) C5 : 0CF78 if(AddrSel)goto(78,58) C6 : 0CF78 if(AddrEq)goto(78,70) C7 : 0CF78 pause(RdFnd),goto(78) C8 : 0CF78 pause(Request),goto(78) CA : 0CF78 pause(SectorPulse),goto(78) CB : 0CF78 if(EoCache)goto(78,78) CC : 0CF78 pause(HCyc12),goto(78) CF : 0CF78 if(Format)goto(78,78) D2 : 0CF78 if(DrWr)goto(78,68) D4 : 0CF78 if(CRCZero)goto(78,78) D5 : 0CF78 if(AddrSel)goto(78,58) D6 : 0CF78 if(AddrEq)goto(78,70) D7 : 0CF78 pause(RdFnd),goto(78) D8 : 0CF78 pause(Request),goto(78) DA : 0CF78 pause(SectorPulse),goto(78) DB : 0CF78 if(EoCache)goto(78,78) DC : 0CF78 pause(HCyc12),goto(78) DE : 0CF78 if(CmdOK)goto(78,38) DF : 0CF78 if(Format)goto(78,78) E2 : 0CF78 if(DrWr)goto(78,68) E4 : 0CF78 if(CRCZero)goto(78,78) E5 : 0CF78 if(AddrSel)goto(78,58) E8 : 0CF78 pause(Request),goto(78) EC : 0CF78 pause(HCyc12),goto(78) EE : 0CF78 if(CmdOK)goto(78,38) F6 : 0CF78 if(AddrEq)goto(78,70) F9 : 0CF78 pause(SectorFnd),goto(78) FE : 0CF78 if(CmdOK)goto(78,38) FF : 0CF78 if(Format)goto(78,78)