// PrintDiskTrident.bcpl - handle queued I/O for Trident disk

// last modified by Butterfield, March 21, 1980 3:41 PM
// - InitBuffersTrident, tridentVec!disk is a TFSDSK,
// not a TFSKD, FUCKer - 3/21/80

get "PressInternals.df"
get "PressParams.df"
//FUCKFUCKFUCK: all the following files
//required for one fucking offset, namely "firstVTrack"
//FUCKFUCKFUCK
get "altofilesys.d"
get "disks.d"
get "tfs.d"

//outgoing procedures
external
[
ReadBufferTrident
PrintBufferTrident
InitBuffersTrident
SetDA//also used by PrintSlot
]

//incoming procedures
external
[
Zero
FileVDA
StartIO
CallSwat
DoRecovery//TFS
]

//incoming statics
external
[
FontTable
nextBogusChar
nDCBs
sysDisk
BitsFile
tridentVec
tridentUsed
]

// T R I D E N T D I S K defintions

manifest
[
diskWordsPerPage=1024
diskCheck = #4104; diskRead = #104; KCBseal = #122645
diskRestore=#12
diskSIOStart=#40
RTC=#430
Active=#453
parityInterruptBit=1
WakeupsWaiting=#452
]

static firstVTrack

//ReadBuffer pushes new dcbs onto KBLK for 4096 word read
let ReadBufferTrident(page,adr,dcb) be
[
let vDA=FileVDA(BitsFile,page)
let mydcb=dcb
for i=0 to 4096/diskWordsPerPage-1 do
[ mydcb>>KCB.AddrD=adr+i*diskWordsPerPage
SetDA(mydcb,vDA);vDA=vDA+1
mydcb>>KCB.StatusD=0
mydcb>>KCB.ID=KCBseal
mydcb>>KCB.nextKCB=mydcb+lKCB
mydcb=mydcb+lKCB
]
(mydcb-lKCB)>>KCB.nextKCB=0 //end of the line
//QueueDiskCommand
let np=@KBLK
if np eq 0 then [ @KBLK=dcb;return]
until np>>KCB.nextKCB eq 0 do np=np>>KCB.nextKCB
np>>KCB.nextKCB=dcb
if @KBLK eq 0 then @KBLK=dcb//race condition
]

and SetDA(p, DA) be
[
SetDA= table [//SetDA(p, DA)
#55001;//0: sta 3 1,2
#155000;//1: mov 2 3
#41402;//2: sta 0 2,3
#30424;//3: lda 2 sectors
#102400;//4: sub 0 0
#61021;//5: div
#77400;//6
#41403;//7: sta 0 3,3sector = DA rem sectors
#30420;//8: lda 2 heads
#102400;//9: sub 0 0
#61021;//10: div
#77400;//11
#30415//12: lda 2,firstVTrack
#147000//13: add 2 1track=firstVtrack+(DA/sectors)/heads
#31402;//14: lda 2 2,3dcb
#45000;//15: sta 1 0,2store track
#101300;//16: movs 0 0head = (DA/sectors) rem heads
#25403;//17: lda 1 3,3
#123000;//18: add 1 0head,,sector
#41001;//19: sta 0 1,2
#171000;//20: mov 3 2
#35001;//21: lda 3 1,2
#1401;//22: jmp 1,3
9;//23: Sectors
5//24: Heads
0//25: firstVTrack
]
SetDA!24=tridentUsed//nHeads
SetDA!25=firstVTrack//for T-300, additional file systems
SetDA(p, DA)
]

//PrintBuffer waits until the requested buffer is filled from the disk,
//and relocates the font pointers appropriately
and PrintBufferTrident(dcb,doneFlaglv) = valof
[ let inPtr=0
let adr=dcb>>KCB.AddrD
let mydcb=dcb
for i=0 to 4096/diskWordsPerPage-1 do
[ let stat=mydcb>>KCB.StatusD
if stat eq 0 then resultis false
mydcb=mydcb+lKCB
]
until inPtr ge 4096 do //fix up bogus characters
[ let n=-(adr!inPtr)
if (n eq 0) then [ @doneFlaglv=true;CancelQueuedRequests()]
if n le 0 then break //this page done
if (adr!(inPtr+1) ne 15) then
[ @doneFlaglv=true;CancelQueuedRequests();break] //bad read
FontTable!nextBogusChar=adr+inPtr
nextBogusChar=nextBogusChar+1
inPtr=inPtr+2+n
]
resultis true
]

and CancelQueuedRequests() be
[ let np=@KBLK
until np eq 0 do [ let n=np>>KCB.nextKCB;np>>KCB.nextKCB=0;np=n]
until @KBLK eq 0 do [ ]
]

and InitBuffersTrident(KCBs,firstBuff,nBuffs,headerBuff,labelBuff,pagelv)=valof
[ //get the disk set up to fill initial buffs
let page=@pagelv
let doneFlag=false
let disk=BitsFile>>F.Device-2
let drive=7-disk/3
firstVTrack=(tridentVec!disk)>>TFSDSK.firstVTrack

for d=0 to nDCBs-1 do
[ let dcb=KCBs!d
for blk=0 to (4096/diskWordsPerPage)-1 do
[
Zero(dcb,lKCB)
dcb>>KCB.drive=drive
dcb>>KCB.nextKCB = dcb + lKCB
dcb>>KCB.CommH = diskCheck
dcb>>KCB.CountH = 2
dcb>>KCB.AddrH = lv dcb>>KCB.diskAddress
dcb>>KCB.CommL = diskRead
dcb>>KCB.AddrL = labelBuff
dcb>>KCB.CountL = 10
dcb>>KCB.CommD = diskRead
dcb>>KCB.CountD = diskWordsPerPage
//dcb>>KCB.AddrD assigned in ReadBuffer
//dcb>>KCB.StatusD assigned in ReadBuffer
dcb = dcb>>KCB.nextKCB
]
(dcb-lKCB)>>KCB.nextKCB=0
//end of the line
]

// @KBLK=0
// KBLK!2=-1;KBLK!3=-1
//reset track memory
// StartIO(diskSIOStart)
// DoRecovery(tridentDisk,diskRestore)

let printCount=0
for bf=0 to nBuffs-1 do
[
if doneFlag then break
let adr=firstBuff+4096*bf
ReadBufferTrident(page,adr,KCBs!(bf rem nDCBs))
page=page+4096/diskWordsPerPage
if (bf-printCount) ge (nDCBs-1) then
[ until PrintBufferTrident(KCBs!(printCount rem nDCBs),lv doneFlag) do
[ ]
printCount=printCount+1
]
]
until doneFlag%(printCount eq nBuffs) do
[ until PrintBufferTrident(KCBs!(printCount rem nDCBs),lv doneFlag) do [ ]
printCount=printCount+1
]
@pagelv=page
resultis doneFlag
]