 Day 12 Let's see if we can get the random access stuff done, but first You'll notice the text is smaller. That's because I finally figured out how to make the BBC master Emulator work which has extra memory to put the video memory in which means you can use 80 column mode without Using up most of the RAM. So if I start it up and do free We have loads more space. I mean it's still Not brilliant, but it loads more I Also did a whole bunch of fixes to stats stat now works so we can Get a disk summary which shows how much disk space you've used we can get more detailed information and these numbers are now correct It's 256 records per directory entry rather than the normal 128 because we're using a 2k block size Which now I look at it should actually be listed here somewhere Hmm. Yeah, I caught stole all this from the original PLM version we can Get a summary of the User locations, this will show you if you have files on users other than the current one Which is useful, but the most common thing is this Which shows you information about the files in particular How many records are in the file? This is the length of the file How many bytes are used in the file? This shows you the number of blocks of disk space and because these files are spars This means that these two numbers are not necessarily related You can see that because we're using a 2k block size Nearly all these files use a single block This one uses for because that is huge 53 records Submit is smaller using two blocks and dat down here uses no blocks This shows the number of extents all these files are one and the access mode whether it's what various access flags are and We're gonna have to do that one as well, but let's tackle read write read write random access first So over here. I made this little C program this opens a file and It attempts to write random junk to a record well to record 80 Which because there are 128 records per extent this should be halfway through the first record Right random just seeks to this record position There are 64k records in a file giving you a total of eight megabytes per file and If I run it And that It says unimplemented So let's kill this off and go find the BDoS code Okay, right random So this is actually going to be You see read sequential Right sequential Right to a random record So this is actually going to be similar code to this So we are going to common sum of this out So where did I put read here we go? So this Gets the block value reads it Okay, so we're going to Wait, this moves the FCB on to the next block. I Don't really want That in here. Yeah, that's that's I'm getting distracted by read. Let's look at right So a lot of this code is fairly common So for right sequential we want this stuff We want this stuff and all the rest is common Sorry this stuff and the rest is common. So right sector down here. This is trivial This is This can be commoned out. So we can have Hmm, I think there should be some error reporting here Actually, and this will This will set the sector number here to the appropriate sector for the block in the current FCB And in fact, we can put this down here No, we don't we want to do this before we modify the these fields seats to the block Ah So it's the current sector to the block pointed to by the FCB Okay, so let's take this code and shunt it down here. So right Random so we convert the FCB we now want to Take at the record number in the our parameter and convert this into The the module extent current record parameters so Convert Random access record number to module extent record and Okay, so the record number is simply going to be well It's a value from zero to one to seven Offsetting into the current extent. So this is just going to be FCB Zero Y that reads the bottom byte of the record number and It current record store The extent number is going to be the next five bytes so that is the top byte of the bottom so the top bit of the bottom byte and Then the next four so so And we can't modify the value Because that has to stay as is so We are going to Rotate the bottom bit left we get the high byte We are then going to rotate its left carry into bottom bit and It with the extent Mask and right Okay, and now for the top we just want to Rotate right to get rid of the top The bottom four bits because those were part of the extent number This gives us the module number so LSA four times CB This goes into s2 Ever you could just write but we only want to do this if the We don't want to disturb the The bit in here that controls whether the FCB is modified or not Let me just have a look at right sequential and see what that's doing read sequential Right sequential so that's here Close extent and move to the next one So this is not Quite hang on second. How does this work? Oh? Yeah, move to the next one, but doesn't open it Okay, so the flag is irrelevant because we've just closed the file In fact, we know that because we've closed the file the flag is not set So we don't need this In fact, we know the flag is set. Sorry. It's when the flag is set. It means it's not modified So we do need that okay, so Yeah, okay, so in right random so stash in a And we can't do arithmetic on any of the index registers so we can stash it in X But then we can't do anything with it But we don't need to Okay, roll a put Not modified fit into carry if carry is set then Or or in eight zero I Do not think So there are I think L s are So we need to get the carry into the top bit. I'm just wondering if there's a better way to do it I was thinking that maybe I could shift the value left by one Discarding the top bit then I could rotate it right by one to get the carry in but no the shift left does Put the value in carry So what's the difference between a oh ASL and roll are different Because with roll the carry goes in the bottom. So I think that's as good as we're going to get okay so We have now updated the FCB But we shouldn't have done that yet Because we would need to close the old FCB So actually rather than writing this stuff directly into the FCB We are going to Dash these intents so that now we are going to See whether things have changed So starting with the module we are going to then we check the extent Byte so if we get here then we know that We do not have to switch Extents Let's do it like this. So the Z if if the module number is Hmm now let's do it like this so if the Values are different then we want to Close the current extent then we're going to update the FCB now it's safe and We do not care about the not modified bit at this point No, we do care about the not modified bit because you need to preserve the not modified bit for the case when we Do not need to switch FCB's So then here we want to Open or create the file Sorry open or create the new dear end so Oh, yeah, it also occurs to me that we can actually Write the current record back We don't need to stash this as we can this isn't relevant to the Which extent we're using so okay, if the module number Has not changed Then compare the extents if either of them has changed Then we follow this code path that this which changes us to a new Extent So now We can Seek to the appropriate Block at what point do we create a block here? So we should just be able to Do this so we seek to the appropriate block actually we can put this here and We want to load the current record Here The current record of course is set up there So this will update the record count of the FCB then we seek and Right, so let me just take one more look at right sequential Yes We can't put seek to block down here because seek to block is going to use the current record to figure out where to go to Okay, I think That is code so Rand that Okay, it did a thing and returned Zero However, nothing happened because my test program has not closed the file Incidentally one cool thing about CPM is that because all the data about open files is stored and managed by the application You can have as many open files as you have memory for there are no file handles There are no Kernel side resources to need allocating. In fact the kernel doesn't allocate anything. It's got no Dynamic memory storage at all it only ever has one thing of each type Which is quite cool Okay Rand that Get a zero we get a dat file Oh, oh So 80 records Because we've written to record 80 Should that be 81 and We have allocated a single Block and I was kind of expecting there to be another F Here, let me just remove that Okay, that was working so rand that if we dump it we get nothing because Unallocated blocks aren't readable in CPM Unlike Unix where they read zeros and allocated blocks are treated as end of file Okay, so here is our dat file and Here is our allocated blocks. You see these are all spars So that's zero one two three four block five and here is our 80 bytes of junk at the beginning of block 80 You know what I'm going to just change that to zero. I'm wondering if I've got an off-by-one error in the Block numbering, okay And that Dump that. Oh, I think we do you know Because you see we have written to the burst block Hmm. You see You see the record count needs to be One more than the current record. This is right sequential We have incremented current record here so The same code here needs to be the same and that dump that Right, we have one record like so if I do if I then change this to Two and that That that we have written Yes to the third record because it's zero based So we see that we still have allocated the first block But if we go down here This is the beginning of block F so that zero one Two So that has written to the right record If we write to block 80 as before and that that that 81 records one block So still is block F Here is the data Right, let's now try and write to record a hundred and fifty. That's above a hundred and twenty eight Therefore it will be in another extent Okay, so we still have a dat file Well, that's wrong. It should have created another extent, but it hasn't let's take a look at the file system Yeah What it's done, I bet is That it's just ignored the fact that this is a new extent probably my maths are wrong So this is this we Mean it looks okay so we copy temp plus one into param we copy temp plus two into into Extend field we copy temp plus two into s2 with not modified bitset Oh, you don't want to do that We don't want to do that because we open file here will set it for us We only care about that bit when doing the comparison in fact in fact We are going to ignore the not modified bit here because if we write it If we do need to change extents Then we update it while the fcp is closed and therefore we don't care about the bit If we don't need to change extents. We're not updating it. The only place we do care is When doing the comparison so not there here Like so So if they are equal Then we test for quality here if they're not equal We go through this Okay, and that stat that Okay, that's still not worked. Let's hit the debugger. I Actually fire filed a bug report for the feature request with The emulator I'm using for an easier way to enter the debugger and they have actually done it in a branch It's just I haven't got round to checking it out and building it yet So I'm still doing it the old way and that Hangs debug break one three six delete that Reset continue and that okay convert user FCB We are now converting the random access record number so Our FCB is at one a1d Which is here, so this is the current record This is these two bytes are the random access Pointer there is actually a third byte as part of the random access pointer, but only one function ever uses it So at this point we're ignoring it So nine zero zero nine six, okay, so fetch it fetch the low byte 96 This gives us the current record of 116, okay, and right back so that's put one six here We next fetch the low byte again 96 Rotate left to put the top bit Which is set into the carry there you go carry is set Get the high byte which is zero Shift left gives us a one and with 1f that gives us the extent number which is one and Stash Okay Now we fetch the R1 Which is the top byte that's a zero Shift off to get the top four bits still zero. Why am I putting a in X here? I think I had a plan Okay, so that should be ignored Put it in the s2 Put it we don't want to write that back Okay, anyway we Stash That was changing it changing s2, which is That one From zero to zero Wait, we don't want that either We just want to store it and we don't want that But we do want that Okay, so we now do the comparison We do want this but why is pointing at the right thing so Compare it It's zero because we just overwrote it by mistake But it was zero to start with and with 7f and compare They are equal So we go here Load the extent which is zero compare with what's in 11, which is one because we want to change extent They are not equal So close the file Well close the DRN done These are using temp. That's what the problem is Great, so we actually want to lda10 plus 2 pha Push s2 Ex this is going to be just to go here This wants to go here Okay, we haven't done any error checking from internal close files if that fails then all kinds of bad stuff happened I'm going to need to overhaul how errors work Still one extent. I Didn't save this Okay And that stat dat Still not working great. I Shouldn't have quit this because now I don't know where my breakpoint was One three six Okay, let's try this again We know this stuff will works so convert user FCB update the current record field Calculate the new extent number Which is one and put it in temp one Calculate the high byte Which is zero Put into temp two now compare s2 We see they are equal So now we compare EX and we see they are different So we push them first EX Then s2 Then we close the file So now we update s2 now we update EX Which is one So here we can see the new FCB With a one here in the extent field So we try to open it Carrie is clear It thinks it successfully opened the file. I'm Surprised We do want to match all the bytes including s2 so Here's temp That is param dph Directory buffer so this contains the DRN that is just found Which is this one That does not match so We should be here EX s1 unused s2 Okay, let's try this again You see one extent round that convert Go through the maths. Do we need to switch for a different extent? We know that we do Okay, we close the file Hang on our extent is We haven't updated the extent yet, so that's fine. So we now update the extent Now we call open file here Okay, so we call find first here A is f the number of bytes we want to match So a Read directory entry check pause No more files We do want to do the fast check. This isn't one In fact, we're going to want to go through this four times we reach the relevant We want to go through four records so I just wonder how I can speed this up a bit So here is where it is comparing extents So let's put a breakpoint at one four F three Okay We're here. We're now trying to compare Extents. So if I look at four One a1d we see we are looking for extent one so Things we have successfully read sequential files of more than one extent this should work We get the extent mask inverted I Think we only tested multiple extent files with the small file system. So I bet this stuff is wrong so for the big file system There can be two extents per directory entry So what we do is we mask off the bottom bit, okay, okay, this is working We're wanting Yep, so we are correctly opening the file What this is doing is it masks off the bottom bit of the extent? Because extents zero and one are both in the same dear end wait a Minute wait a minute there are 8 2k yeah game there are 8 2k blocks per dear end a 2k block contains four records There are 128 records per extent so 16 by 2k is 32k of data Per dear end which is two extents each of which are Hmm now hang on 8 by 2 2k blocks 8 values 16k per Dear end this should be one extent this value here is wrong We get the extent mask from the value in the bios Which we get from here So blocks on disk is less than 256. Have I got this completely wrong? Are we using 2k blocks or not? Have I managed to get myself very muddled? three four five six seven eight nine a we are using a small disk and with one byte per block so there are 16 Byte here Therefore two extents right that is correct. We are we it is actually doing the right thing okay So it's we're trying to extend the dear the dear end for that from one extent That to two extents to do that What we do is we bump the extent number from zero to one Thus indicating that this dear end represents the second extent of the file That's the top half here It's assumed that the bottom half is going to be full It's just you you always put the extent number of the maximum extent so We do want to find extent zero and We do want to as However, we do want to update the version in the FCB with see if you open Extent zero Seek to extent one then seek to extend zero and close the file The the value in the FCB represents the extent you're currently looking at So when you close the file the extent will be zero even though the file is longer than one extent its file is two extents So that will in fact Corrupt the disk This will write back a zero where there should be a one I don't think that's relevant for what you're doing here what we're doing here But this merge FCB into dear end code needs to take care not to make the Extent value smaller. I think Anyway, I don't that's I'm look at that next. I don't think that's relevant here So we are Still trying to open our file. We expect this to work We are comparing the extents down here. So we mask the FCB extent to do the comparison. See that's turned into zero So we Door it. Why am I not using the X registers X being used by something? I don't think it is It's not. Oh Because we need to subtract it here and we can't do that with X. Okay so stash Pull the mask apply the mask again to the one in the dear end Which is also zero do the comparison. Are they equal? Yes, they are and Go around again because we want to compare First s1 which we ignore Go around again now we compare s2 which is zero But that's just a bite. So we compare it Yeah, we pull the top bit We reach the end. This was a success. We found a file and we return back to Open file not that one That one so we do have a matching extent so we are going to We're going to just finish through this code. You know this works. I am however Going to step through this stuff So that's here here This is the fourth first time we've actually exercised this code. Okay So we are loading the extent in the fcb In the deer ant sorry because we've copied the deer ant into the fcb and The the extent value there is zero that tells us that the file is one extent long Well, the deer ant is one extent long. We then compare this with the value the user asked for which is one No Zed because they're different so We fall into this code Now we should be hitting this condition Indicating that we are now looking after the end of the file so Don't set That okay record count Get updated Update the extent value with one the value the user first thought of so our open fcb looks like this We have extent one record count zero and The allocation map for extent one is here Nothing is allocated okay, so That's done. We now go to Write random We have just opened the file Harry is clear that worked So we skip on to here make we make sure that The record count is Is updated Because the current record Is updated with respect to the current record so Current record is one six So we are updating the fcb With the new current record value, which is going to be one seven And we mark the fcb as being modified. Okay So there we go We've extended the fcb. We now want to Seek to the relevant block and allocate a new one. I Think this will work because this stuff does work so let's just do a next and We should be able to see in the fcb That we have in fact not Allocated a block so that does not work So we want to stop at one for 50 and go again Okay, we're here. We Get the fcb block value So Fetch as the current block number In the fcb in xa So get block index is going to be doing work Which is here when you look at the current record Okay, okay, this is not Updating it for multiple extents All right, so we actually want to We're going to want to fetch the extent mask again is this code Get fcb block index. So this is the Actually, I think we're doing this wrong Okay, so this tells us whether we are on extents zero or one Or more for larger block sizes So we now need to figure out how much to offset the Index so we need the value of the number of blocks per Extent So this is for converting from records to blocks and vice versa We know that a block Sorry an extent is always 16k So we should be able to figure out How many record how many blocks per extent By taking two to the 16 not 16 and Subtracting block shift here. Yeah, you see this is turning records Into blocks so But block block shift is not actually Right, this is more complicated than it looks No, let's take a look at the documentation again By us functions cell disk dph Dpb right block shift so Three is one k Yes, so this is you are 128 bytes Shifted left three Gives one k so 16 k is Going to be another four so that's seven so sir Seven minus three Gives five hang on five is 4k eight is 8k Nine is 16k so five is 4k six is 8k seven is 16k so Seven minus three is four one two three four Okay, seven minus three there is a shift Okay, so Okay, so we're getting four Here so we go through the loop four times we shift one left four bits Which goes to two to four to eight to six Dean Which is the wrong number? We wanted to get eight in fact we wanted to get four because we're looking for The number of indexes the num the index of The relevant bit of the allocation map This is the kind of math stuff. I am very bad at can you tell? Okay, so there are four oh wait a minute wait a minute. That's not a shift. This is an index seven minus Three gives us the four we want if the if we're using 4k blocks rather than 2k blocks which we are then each extent is for a Wait if Sorry, I keep getting this wrong. This is a small disc Each of these is a bite. It's this zero zero oh F here that keeps throwing me off. Okay if we are using 4k blocks then a Each extent is four bites So for a 4k block the shift is four So four Five six seven is three not right So we want we write this down So if you're using 1k blocks then the shift the the index is zero for a 2k block It's a four for a 4k block For 2k block. It's an eight for a 4k block. It's a four For an 8k block. It's a two for a 16k block. It's a one You know what would be easier than doing a than doing maths Just using a lookup table however We might actually have some of these here already There's some better documentation for this I will go and find the better documentation Okay, here is the original digital research system alteration guide documentation and The one thing I really notice is That none of these tables actually corresponds to what we've got here So I am I was hoping that we'd be able to trivially Get this from one of these tables We probably could but honestly it's much more reliable For me to Simply simply this isn't simple So the block shift here is One of these values Okay, so if you start at four Which is Corresponds to 2k that gives us a table of eight four two one So to get the to get the shift value it Get block shift sec Sbc For Tax Lda start index table comma X So then we get the current record and we want to after we've done the shift We then want to add on this value No, we want to multiply this value by this of half and sake Okay, so this is actually How is the original code doing? Okay, read the next directory entry Not that one. This is Block shift Okay Compute disk map position for v-records to HL So in order to we want to multiply our extent by one of these 0 1 2 3 So in fact we can get this by 7 Minus the block shift Subtract the block shift this gives us the Appropriate amount that we need to shift left the extent number In order to turn the extent number which we have here stashed on the stack Into The index into the Allocation map So we don't need to look up table We just put this thing in X Then we are going to use a dex Count this many times now if the extent mask Hang on you want to Pull that stashed value from here in fact. We don't need to we can do this Now if our block shift is 3 then Because our block size is 1k We can only In order to get an extent we need to use all 16 bytes of the allocation map Therefore the index is always going to be zero so 7 minus 3 I got that just take a look at my table again back this stuff out. Okay, so here's our table So block shift minus 4 Gives us Yeah We want 7 minus the block shift So a block shift of 7 it gives us 0 1 2 3 4 so the extent mask here for 4 Is going to be Stent mask See later There's a table of extent masks. There should be one somewhere rather than having to understand what the actual values mean But I now occurs to me I have this in My bios lookup table here we go extent mask and extent mask of zero means that we are actually going to and The FCB's Extent value with zero which will produce zero so we're going to shift it for shift that zero four times So this will all work Okay, we then want to Figure out which block the actual index is on and add the two together So we are going to have to stash this here then We shift it according to whether we're a big disk or not Add on the allocation map. Yeah, and then get the thing right. I hope this works. This was a nightmare So Let's get rid of that brand that Stat that Still doesn't work. What is it actually written? Nothing useful however We now have our block allocated in what I think is the right place I say I think it's the right place because this is clearly block 8 And block 8 is actually being used over here As part of stat So that this should be block F. It's allocated block F, but it's written block 8 So that's wrong. I Wonder whether Using temp zero has confused things was in very easy way to test this which is use a different temp and we also want to Trigger it to regenerate the file system because the file system is invalid, okay Rand that Start that 23 records and yeah, that looks wrong So if Yeah That's changed to OF. I bet that if I did this again with for 10 plus zero that would be Back to O8 again So that's something that's using get FCB block index is Using temp zero Such as set FCB block here, okay? Well, I don't believe we're using block temp 2. So let's just put 2 and I think we can do better than this So we need a First and it's going to push a and x onto the stack, but I have to in order to push x I need a so I can do Transfer a to y to x to a push Y to a Push your PLA there Another PLA there does PLA set any flags Yes, it does So I can't do a PLA there or I will Upset this conditional, but I can put a PLA here So I don't need that anymore So that's a miserable piece of code with lots of register shuffling This would be trivial on the 65 co2 because as I have mentioned many times before I don't need that The 65 co2 lets you push x and y Anyway, not using temp there is useful Okay Okay, ran that Still only using one extent. That's because I haven't fixed clothes yet So here we have that We have a this block has been allocated in extent one, which is correct It hasn't updated the deer end to say there is one extent, which is why the value is not being reported correctly okay, so We fetch the directory entry for this extent check the FCB has actually changed Find the directory entry for the extent which is we got it here up date it now when My thing I think right, okay See I was worried about the user Trying to doing something like writing here and then seeking back to extent zero But without writing back the FCB changed the disk this value would be wrong But you're not allowed to seek back to extent zero from extent one without first Closing the file syncing it rather So the value in the FCB should be correct So all we need to do is This should be a why Okay, we generate because the file system is Suspicious and that stat that To extents one hundred and fifty one records good. That is the right answer So here we see one extent Well, this is an extent fine a maximum extent of one indicating that this deer end is for Extents zero and one and we see a block here good Let's go back to my test program and I am going to set a good high number so Rand that Stat that Twelve extents one five oh one records, which is exactly what we expect after writing to record one five oh oh One disc block. So what do we have in the file system? We have two deer ends one for extent zero and one for extent Eleven is that correct should that be extent one? I think it's all right because if we try to do anything with extent one Then the value will be bumped when we write back any modified FCB So I think that's good. I think that is actually working which is honestly about damn time Okay, uh just I Don't actually know whether I Don't hang on. I can't think about more than one thing at a time at the moment. I don't know whether LLVM moss has got a to I it does not have a to I unless I haven't Allocate it Haven't declared it stood live. Yeah, it's not there. Let's try Sturred hole No They must LLVM moss doesn't have a awful lot of runtime library like this is it your few string functions We've got a tiny amount of studio. We've got a tiny amount of stud live Okay, but we don't have an eight. We don't have a sturthole or an a to I so let's just write one V equals V times 10 V Plus equals C minus Zero and like you to admire all the amazing error detection there Okay Because that made our program Not so bad The code produced Varies enormously from very good to not good And it's also in line day to I There's a multiply and struck a multiply routine. It's pulled in there This is our main which is I hope it's our main because it's huge You can see it calling open file Make file here it's Fetched command line It's interesting Let's fetch the first byte at command line It should be putting it into a pointer here it is it's putting it into a pointer. It sometimes does very odd things Here it's doing the multiply by 10 Yeah Anyway, it'll work Okay, so That was stupid We're using the fcb here for the file name and the which means that the command line is actually contains the file name so let's just make a Fcb so Zero E four five six seven eight nine ten eleven nought nought nought Empty nought nought nought So I should be able to type now a record number Good. We've got our file So round 100 That seems odd okay, uh I was hoping to get more done, but No, actually, I thought that I had forgotten to call a to I here and was not setting the Value properly So this will print the record number it has passed So this will keep reading characters until the end of the line It's more or less right to be honest. Okay, it has tried to write to That's getting the right value See, it's it's got the record number correctly and Write random is returning a zero which means everything should be fine But that is never getting bigger See, it's only ever writing the first record Also, why is there garbage up at the top here at the top of the file system? That's wrong That's extremely wrong. I mean Yeah, you see it cannot load the bedoss something terrible has happened and It's written garbage everywhere So here's our program Here is the FCB That we've created that looks right allocation map Four bytes. Yeah, that's fine Then we have the relocation data. So my thought now is that this is going wrong Yeah, that's corrupted the file system again. You can see that this has disappeared That this has gone wrong because It's trying to write to a file already exists that we have actually been testing But this was kind of working previously Okay, well, let's go and Let's find Do we have our deep? We do have a debug. Does it print numbers? No Facts, let's just get rid of debug because we've probably passed that at this point Just simple trace messages won't be terribly useful and also We should have This should be an improper error message by us We have a routine for writing strings, I know because I wrote it here Okay, well that hasn't actually helped but It's nice a bit of cleanup now and again Okay, let's put a Stop there. Okay brand 1000 Continue a round 1000 Converts the random access record number to M. E. R. Well, let's take a look at our FCB. Oh That's kind of interesting There is no record number here because Because I screwed up this But this does mean that writing to record zero is Corrupting the file system So so happens that we are in just the right place to debug this. So let's go through this So we get the parameter and we do all the maths we know this math bit works Okay, so we've put them in 11 and 12 so extent zero module zero and The current record is Zero so do we need to switch from another extent? Well you compare these They are equal we compare these They are equal therefore We skip this whole chunk code here and go straight to here Update the record Count Mark the FCB as modified Here's our FCB record count of one Current record zero no blocks allocated. So we seek to the block. I bet my seek code is What's the phrase? bollocks Okay, get the FCB block get the block index Okay, so we figure out the shift value the shift is three This is how much we need to shift the extent number put in X Get the current extent mask, which is oh one Get the current extent and and the two together Oh Shift left to get the allocation map start by three We get a zero and stash in temp to Get the current record, which is the which is going to be zero Yep Get the block shift into X Which is four and shift it right to get the the index into the allocation map We now add on The extent start index zero Are we a big disc? We are not So we get the index into the allocation map by adding on the offset Which is now 16. Yep and return What's wrong about that? So we're now getting the fcb block into x a It's this isn't it I screwed this up that starts at one two bc Okay Set the current block number in the fcb To x a right x a is oh f. This is the block number. We are trying to write so a to y x to a Push Y to a Yep push Get the block index in Y Which is one zero Pull oh f. That's the low bite Actually, we know this worked because we saw the oh f in the allocation map But the actual sector right was happening in the wrong place So where do we go from set fcb block? here seek to block so get sequential sector number is Compute the sex a number of the block into x of the block currently in x a X a zero okay, okay That's why it's not working So x wants to be the high bite But we're using x here. This is a waste of time We know these are free because that's what we were using before okay, so LDA 10 plus zero Plus one that goes Here One I mean it's miserable, but it should at least work Well, that is the wrong value. It's just parsed But it hasn't corrupted the file system and we have a Okay, so the print routine I'm using has obviously got this wrong No, it's nascent. No, it hasn't this is the same mistake. I made before This is printing the wrong fcb Okay, but that's worked that has created multiple extents It's also just new file system Number of records is correct number of blocks is correct. So let's 10,000 Okay start that And that's that number too big I think it was actually too big This is showing the number of records in the file Which can go up to? Well, it should go up all the way up to 64k See see that's allocated another block and Lots more extents. Ah I know what happened No, I don't know what happened I was about to say that I think it ran out of directory entries But no, it shouldn't have created consecutive directory entries. We should have gone from Zero all the way up to Yeah, here we go. So we go here's a dat with extents zero o e o seven One f so it doesn't have to create the ones in between so let's make a Bigger one doesn't like 8,000 Interesting Very interesting. Okay, that worked that worked Um Just thinking about random numbers. I bet this will work Yep bet this won't yeah This means that my arithmetic is wrong. Oh, yes, let's take a look at the file Yes, it is trying to create Modules But I believe it's getting confused in places Yeah, here's a module to Okay Let's just wipe the file system Okay Rand 10,000 and it hangs right one three F F Reset continue 10,000 okay, we're here now Our FCB is at still one ADC and here we can see The current record and here is the random access pointer so quite a large value So we take the we figure out the current record and Put it in the Current record field We get the low byte of the extent and I believe this works by Doing this stuff Okay, now we fetch the high byte to seven of the the record number Shift it for gives us two and stores We saw actually The relevant values in the file system So I kind of think this code that the arithmetic works and it's something that's wrong with open file create file Anyway, we are now doing the comparisons We have decided that we need to switch DRNs, which is correct So we push those we call close file We update S2 With to which is the value we wanted we call open file this should fail it has We call create file that should succeed it has no error So we go here Okay, let's take a look at our FCB. We see that We are indeed on module to extent OE Current record 1.0 it should have created that file on disk because that's what create file should have done it should have Allocated a directory entry for it wait a minute wait a minute. I think This might be working and this is actually stat bug So this is the stat source code Here here is where we Here is where we are calculating the We are scanning the directory and we are completely ignoring the S2 field Okay So Let's fix this Extents can now be a 16-bit value Here we are loading. We're scanning the directory figuring out what all the file systems are here We are determining the number of records and extents in the on the file When scanning the file system, we're looking for the highest extent number and we're just looking at the extent field so We actually want to do a directory entry S2 times 32 plus DEX So and I will put this here No member named S2 in there and Yep, I called it something else So this should be That actually needs fixing in the header wait a minute Because calling S2 S brackets one is confusing Okay black file system grand ten thousand You got a file and that's wrong interesting This is producing Tirely the wrong Why is that getting a zero wait a minute? I'll control block. Okay, so we want S2, which is the second S byte Which would be this one? Is my dear instructor wrong user number 11 bytes of file name EX S1 S2 You know what? I am gonna fix that which involves rebuilding the MOS SDK, but that's a matter of moments Doesn't rebuild LLVM. Oh, that does not take mere moments. Okay, and Change that to S2. Oh, I know what it's doing. I know what it's doing It is It only it skips file names it's seen before which of course happens Before it does this calculation, so it's only ever looking at the first No, that's not right It does indeed look for files in the Array and deduplicate and We then Yes, we actually Look up the No, it should be going through this every time So why are we only seeing the file once? Have a routine here Okay, so this should print the file name of every dear entities so we should be able to do stat star star and It sees bitmap lots of times. I seriously need to clean up those headers They should be called the same thing. Okay, that's that star star Right and there it's seen the files and then it prints them Okay, so Rand 10,000 stat that Sees that once Should be seeing it more often star Sees that once Okay, my guess is I do think I know what's going on So putting a question mark in the extent field Causes it to return well as it says in the comment all extents not just the first and that is to find in the Documentation If the expite is also checked normally it should be set to zero if it's set to question mark then all suitable extents are matched If the expite is set to zero we also and this is important Want to put a question mark in the s2 byte But we don't we can't rely on the user doing this because the documentation doesn't say the user has to do this So we're going to find our Set up fcb for find Get all extents clear module byte in fcb Get all extents put a wild card byte in fc in fcb In fact, we know that a is a question mark so Okay, and there is my dat at 79 extents 10,001 Records so that file is actually Technically 10,001 times 128 bytes long Let's try adding another No, I can't add another zero because we'll run out of Bit but that should work. So that is a long file You should go all the way up to 65535. That's a bug I Can tell by the fact that it is allocated one block that it has I believe actually worked However the arithmetic in stat for Here we go fe records has just rolled over so So, yeah, that was bad. I think I can change that by doing this at the expense of much worse code 65535 stat that And it's still not right something's doing arithmetic in 16-bit precision I am going to just leave that for now because this is stupid and I'm getting tired But I believe that we are now correctly writing Random access files Reading is basically the same but easier The one I don't want to do is filled right, but we're going to have to But I'm going to deal with this next time. So good night