// DiskProms.bcpl // last modified January 18, 1982 11:22 AM by Taft external DiskProms get "DoradoProms.defs" external [ Min ] static addr manifest [ Pin1 = #200; Pin2 = #100; Pin3 = #40; Pin4 = #20 Pin5 = #10; Pin6 = 4; Pin7 = 2; Pin9 = 1 ] let DiskProms(mem) be [ let buff = vec 300 if StEq(mem,"DskEth") then mem!0 = DoAll if StEq(mem,"DiskWrite") & ICtype eq MC10139 then // define the write Prom [ MakeCont(buff,false) Header("DiskWrite",8,buff,32,8) PromCommand("Disk-a20") ] if StEq(mem,"DiskRead") & ICtype eq MC10139 then // define the read Prom [ MakeCont(buff,true) Header("DiskRead",8,buff,32,8) PromCommand("Disk-a21") ] if StEq(mem,"DiskTag") & ICtype eq MC10149 then // define the Tag Timing Prom [ MakeTagTiming(buff) Header("DiskTag",4,buff,32,12) PromCommand("Disk-d21") ] if StEq(mem,"DiskFifo") & ICtype eq MC10149 then // define the Fifo Pointers Prom [ MakeFifoPointers(buff) Header("DiskFifo",4,buff,256,12) PromCommand("Disk-b14") ] if StEq(mem,"DiskUnits") & ICtype eq N74288 then //now define the Drive Select Prom [ MakeDriveSelect(buff) Header("DiskUnits",8,buff,32,8) PromCommand("Disk-d05") ] ] and MakeCont(buff,ReadFlag) be [ //first define a bunch of constants manifest [ LoadSR = Pin1; ReadSR = Pin1 CompECC = Pin2//configure ECC generator for genoration NewBlock = Pin3//shift command reginster AT START OF THIS INSTRUCTIOM Tag = Pin4//Load value addressed by RAM into Tag register //otherwose load value addressed by RAM into the count register ] manifest [ //These define the LOCATION of parameters within the RAM register Count0 = 0 //Number of words in block 0. Count1 = 1 //Number of words in block 1. Count2 = 2 //Number of words in block 2. Count3 = 3 //Number of words in block 3. ReadComm=4+Tag //Tag Command to cause a Read operation. WriteComm =5+Tag //Tag Command to cause a Write operation. InitComm =6+Tag //Tag Command leading to a read or write. ResetComm =7+Tag //Tag Command to zero all bits of TAG register. WrDlyFirst=8 //Number of "0 words" to Write before the data of 1st block. WrDlyNext=9 //Number of "0 words" to Write before the data of other blocks. RdDlyFirst=10 //Number of words to wait before reading the 1st block. RdDlyNext=11 //Number of words to wait before other reads. Delay3=12 //used for ECC count plus 1 Delay2 = 13 //used for ECC count and Head select delay. Delay1=14 //Minimum count time. ] //~~~~~~~~~~~~ //now "Program" the READ/WRITE proms test ReadFlag ifso //define all the commands necessary to read all blocks of the disk [ //NOTE: the controller may sitch from Read to Write after executing "NewBlock" //Initialization buff!00 = InitComm // enable the heads buff!01 = Delay2 // wait for disk to settle //Commands for Reading the first Block buff!02 = RdDlyFirst //wait for heads over zeros buff!03 = ReadComm //waits for the "sync" pattern buff!04 = Count0 + CompECC + ReadSR //read in the "block" words buff!05 = Delay2 + CompECC + ReadSR //read the ECC words buff!06 = InitComm + ReadSR //read one word of ECC,turn off read buff!07 = Delay1 + ReadSR //read last word of ECC buff!08 = Delay1 + NewBlock //get the next block //Commands for Reading the second Block buff!09 = RdDlyNext //wait for heads over zeros buff!10 = ReadComm //waits for the "sync" pattern buff!11 = Count1 + CompECC + ReadSR //read in the "block" words buff!12 = Delay2 + CompECC + ReadSR //read the ECC words buff!13 = InitComm + ReadSR //read one word of ECC,turn off read buff!14 = Delay1 + ReadSR //read last word of ECC buff!15 = Delay1 + NewBlock //get the next block //Commands for Reading the third Block buff!16 = RdDlyNext //wait for heads over zeros buff!17 = ReadComm //waits for the "sync" pattern buff!18 = Count2 + CompECC + ReadSR //read in the "block" words buff!19 = Delay2 + CompECC + ReadSR //read the ECC words buff!20 = InitComm + ReadSR //read one word of ECC,turn off read buff!21 = Delay1 + ReadSR //read last word of ECC buff!22 = Delay1 + NewBlock //get the next block //Commands for Reading the fourth Block buff!23 = RdDlyNext //wait for heads over zeros buff!24 = ReadComm //waits for the "sync" pattern buff!25 = Count3 + CompECC + ReadSR //read in the "block" words buff!26 = Delay2 + CompECC + ReadSR //read the ECC words buff!27 = InitComm + ReadSR //read one word of ECC,turn off read buff!28 = Delay1 + ReadSR //read last word of ECC buff!29 = Delay1 + NewBlock //get the next block //Reset the Tag register and clear out commands buff!30 = ResetComm+NewBlock buff!31 = ResetComm+NewBlock ] ifnot //define all the commands necessary to write all blocks of the disk [ //NOTE: the controller may sitch from Read to Write after executing "NewBlock" //Initialization buff!00 = InitComm // enable the heads buff!01 = Delay2 // wait for disk to settle //Commands for Writing the first Block buff!02 = WriteComm //send a tag with write bit on buff!03 = WrDlyFirst //now wait for disk to settle buff!04 = Delay1 + CompECC+ LoadSR //send the "sync" word buff!05 = Count0 + CompECC+ LoadSR //send the "block" words buff!06 = Delay1 + CompECC //compute ECC on last word buff!07 = Delay3 //shift out ECC plus word of zero's buff!08 = Delay1 + NewBlock //get the next block //Commands for Writing the second Block buff!09 = WriteComm //send a tag with write bit on buff!10 = WrDlyNext //now wait for disk to settle buff!11 = Delay1 + CompECC+ LoadSR //send the "sync" word buff!12 = Count1 + CompECC+ LoadSR //send the "block" words buff!13 = Delay1 + CompECC //compute ECC on last word buff!14 = Delay3 //shift out ECC plus word of zero's buff!15 = Delay1 + NewBlock //get the next block //Commands for Writing the third Block buff!16 = WriteComm //send a tag with write bit on buff!17 = WrDlyNext //now wait for disk to settle buff!18 = Delay1 + CompECC+ LoadSR //send the "sync" word buff!19 = Count2 + CompECC+ LoadSR //send the "block" words buff!20 = Delay1 + CompECC //compute ECC on last word buff!21 = Delay3 //shift out ECC plus word of zero's buff!22 = Delay1 + NewBlock //get the next block //Commands for Writing the fourth Block buff!23 = WriteComm //send a tag with write bit on buff!24 = WrDlyNext //now wait for disk to settle buff!25 = Delay1 + CompECC+ LoadSR //send the "sync" word buff!26 = Count3 + CompECC+ LoadSR //send the "block" words buff!27 = Delay1 + CompECC //compute ECC on last word buff!28 = Delay3 //shift out ECC plus word of zero's buff!29 = Delay1 + NewBlock //get the next block //Reset the Tag register and clear out commands buff!30 = ResetComm+NewBlock buff!31 = ResetComm+NewBlock ] ] and MakeTagTiming(buff) be [ manifest [ TagStrobe = 4; TagDone = 2; CntOff = 1 ] Zero(buff,256) for adr = 0 to 31 do [ let Active = adr let Cnt = adr let output = 0 if (Cnt ge 3) & (Cnt le 13) then buff!adr = TagStrobe if (Cnt eq 12) & (Active ne 0) then buff!adr = buff!adr % CntOff if Cnt eq 15 then buff!adr = TagDone ] ] and MakeFifoPointers(buff) be [ manifest [ Full = #10; WriteEn = 4; ReadEn = 2; Empty = 1 ] Zero(buff,256) let InvertBits = WriteEn % ReadEn for adr = 0 to 255 do [ let Waddr = adr rshift 4 let Raddr = adr & #17 let Delta = (Waddr-Raddr) if Delta eq 0 then buff!adr = Empty if Delta eq 15 then buff!adr =Full // 14B. change to accommodate lost fix if Delta ge 2 then buff!adr = buff!adr % ReadEn if Delta ls 12 then buff!adr = buff!adr % WriteEn buff!adr = buff!adr xor InvertBits ] ] and MakeDriveSelect(buff) be [ structure Input: [ blank bit 11 select bit 1 // 1 => select addressed drive driveNum bit 4 // drive number ] structure Output: [ blank bit 8 select0 bit 1 // select drive 0 (unary encoded) select1 bit 1 // select drive 1 select2 bit 1 // select drive 2 select3 bit 1 // select drive 3 driveNum bit 2 // addressed drive (binary encoded) blank bit 2 ] for adr = 0 to 31 do [ let output = 0 // drive numbers greater than 3 address drive 3 output<<Output.driveNum = Min(adr<<Input.driveNum, 3) if adr<<Input.select then switchon adr<<Input.driveNum into [ case 0: output<<Output.select0 = 1; endcase case 1: output<<Output.select1 = 1; endcase case 2: output<<Output.select2 = 1; endcase default: output<<Output.select3 = 1; endcase ] buff!adr = output ] ]