 Nice new brother WP1 word processor. I could connect the Raspberry Pi up to the UART. I am actually going to take the time to write a whole new terminal emulator. Yeah, what this is doing is it's drawing a few, it's updating a few rows. Then a character comes in to stops redrawing. The character is processed through the state machine. This causes the screen to scroll which dirties everything. Therefore when it does the redraw it starts again at the top of the screen. It's just not a very nice user experience. But we can do that by adding another ring buffer. What we're going to do here is we're going to use the same kind of ring buffer that we've got here for the keyboard but for the interface as well. We have enormous amounts of RAM available. We really don't need to worry about doing this efficiently so this should be easy. What this will do is it will allow us if I can find the display code again inside the flush code. Here if we see that the interface is readable we can read a byte and stash it in the ring buffer and then continue drawing. That should hopefully be pretty cheap only a handful of instructions. That way when we finish redrawing and go back to the main loop we will then process all the keys in the ring buffer in one go so that the screen should be ready to be displayed again in the next frame. The danger is that if we receive more than 256 characters from the interface while redrawing the ring buffer will fill up but I think that's very unlikely and we can probably work around it anyway. I added the parameters for the interface as buffer and we're going to add int push int pull. What are we going to do if there isn't anything? We will return a flag so here in the keyboard stuff this is the pull code so we can just copy this completely. The keyboard code returns it. If the buffer is empty we don't need to set that anymore. If the buffer is empty then we return with zset which allows the caller to detect this otherwise we read a byte into c and return it. The keyboard code returns zero if there's nothing to read. In this code we want to avoid treating zero especially in order to make this insert double quotes here eight bit clean. I can't imagine that we'll ever actually want to receive zeros from the interface and do anything with them but let's at least make the effort to do this correctly. And keyboard push push the key onto the king buffer into the keyboard type does it. We should rename that but anyway so interface push okay so let's export these push int pull sort right and in our main routine we are going to wait a minute this reads a byte from the interface and it returns zero if there's no byte pending. So this returns n z so because that's that's the result of this comparison. It would be rather nice if we could return z which is what we're using throughout for errors. How do I invert the z flag? Well the obvious thing is this is the error path so this shouldn't happen very often and if there's no byte pending then we've got nothing to do anyway so and actually right from the interface and push it into the ringing buffer. Okay so this is just going to fall through into the inter push code. So here in main all we're going to do is this. That will make sure that if there are any bytes in the interface they get read and put onto the ring buffer. So now we want to call int pull if z is clear call like this and I forgot that you can do conditional calls. So this is actually no we can't use it here because we need to make two calls in a row. Okay so we should now have our code working again via the ring buffer. Let me just look to see if I need to initialize the ring buffer. I do not zero is correct. So we go to the display code and what we're going to do is use the same logic we previously had and the conditional call so that if we're readable call key pending which will save the registers we care about which is bc and call like that. Do we care about any other parameters? I do not believe we do bc is the only one we're interested in so we only have to push bc. Yeah that should work. Okay it does not actually build because we need to import int pull then the display code int read okay and in fact because we have so much memory available I am just going to do a thing I'm going to get rid of adahl and add ade and inline things instead so so this is the most efficient way to do it by code size but instead we are going to do this so this will allow us to construct and inline the add whatever add a to whichever 16 bit register we want this is going to be one two that's not right right that should be one two three four five bytes but previously each call to add a hl would have been three bytes so this was two bytes longer but considerably faster as we don't have the overhead of call and read both of which hit memory and are therefore quite slow so in interface what we're going to do is to add a 60 h come around or maybe we're not back slash introduces a macro parameter wasn't it where did I put a macro oh yeah in the display code I didn't use any parameters at least I know the question mark contact uh syntax is correct what does this do that doesn't work either okay um each occurrence for the former parameter pk replaced by the corresponding value vk so I don't think I need to write any specific syntax for this so why doesn't it like it regular reg high question mark l1 well I think I'm doing it right so this would be add a 16 h come around again it seems to have inserted a new line where there shouldn't be one no no it's worked right I was looking at the error from the previous iteration through all right so let's actually take out these so we should get lots of errors we can't export these anymore we have add a hls everywhere there's one here a 60 h come around unfortunately I don't think yeah I have to have the parameter in a in order to add it so um I can't dispense with this move here which come around okay you've got something in keyboard z80 and we've got some in okay and we've got some in vt 102 add a 60 h come around here's one here just the two um because our add a 16 has got a label in it this means that it the state of automatic dot labels here has been reset so and we create one I don't think we can however I think we can do this I need to check the listing to make sure that that's produced the right code uh dollar should refer to the current a current program counter address but I can never remember whether it's the address of the next instruction or this one I think that's this one actually so that would make that plus three so um there's plenty of them in display right so this is where the macro is defined here is his here is where it is used yes I believe that has worked yeah it's jumping to address address hex two three which is three plus the current address the offset encoded into the instruction is one which is correct because this offset is applied after the instruction has been read so it's skipping one instruction which is this one all right now we also wanted to fix the delete key which was driving me nuts and I think I know what that is doing which is this routine here for inserting blank characters now I think that what this is doing is is that it's advancing the cursor one for each space printed and I don't think it should be doing that I think it should be leaving the cursor where it is so how to do this well the obvious thing is just save the cursor and restore it again afterwards um just a documentation say oh oh no it's an insert operation doesn't print blank characters he inserts them thus editing the line that's already present right now we can't do this without adding a back end primitive to do it because the state machine doesn't have access to the screen data that is in order to insert a character we have to change the entire line which cannot be done with the set of primitives we've got which is not there they are here insert line clear line delete line and print that's all we have so yeah what I want to do in fact is remove this completely and change the term info file not to support it that is not tell the term info file that we don't support it and it shouldn't try to use that it should be relatively straightforward is there anything else I wanted to do I don't think so I think that's a lot okay how big is our program this is the hex dump here you can see the repeated code for our draw routine got some tables more code more tables here is the end of the code and then it's all zeros from there on up c o o here is our limit so we can use code we can have another let me see this page is empty this page is about half full so that's 256 plus 128 which is 384 bytes we've got that much to spare in fact we also have the entire second track which we can put stuff into but I'd have to update the boot code to load that as well and honestly that's kind of full so I'd rather not anyway this should be fine there's plenty of space a ram of course isn't going to be in this table so let me just double check yeah I do have a d seg there and there this is displaying all the segments p is for programs d is for data or the data appears after the program starting at 7a 70 so this is the size so display is big because it's got the back buffer in it interface is big because it's got a new interface buffer in it keyboard is big because it's got the new keyboard by buffer in it and vt 102 is quite small I thought I had more state than that oh no just this all right I will write that a disk and let's give it a try yes I think it's fair to say that this is not working well this isn't gonna help well I found the stupid bug that was causing the garbage on the screen but now nothing does anything so yeah and if I use the raspberry pi to send serial to the well serial port again nothing happens I believe that we are sending bytes I will just double check this by oh yeah we are sorry I'm just looking at the output from the raspberry pi's own monitor so we haven't broken the keyboard to the outside world bit we've only broken the outside world to the interface to the brother bit so I'll go and try and figure out what's going on there I think well I fixed the stupid bug which was a typo of course it's always a typo I'd managed to invert a flag in a branch somewhere so it was failing to report correctly the bytes been read from the interface and it does seem to work and scrolling is reasonably fast there is snow at the top of the screen which is annoying because that means I'll have to reduce the number of scan lines drawn per frame and that's okay it does yeah the delete is still broken of course I haven't done anything about that I haven't done anything to the term info file yet scrolling looks a bit weird unfortunately you can see by the number of dropouts which that's where the rainbow appears that my hdmi capture is increasingly less happy with the the output from the ossc it might be overheating anyway if I do things like clear the screen we don't get a complete prompt which means that characters are being lost which is annoying it's because clearing the screen involves updating quite a lot of memory therefore it is a fairly slow procedure now unfortunately I did come up with a really cool way to enable hardware flow control in the interface uh that's not the unfortunate bit the unfortunate bit is that enabling hardware flow control on the Raspberry Pi turns out to be really complicated involving doing stuff like device trees there is software flow control where we can send back a byte saying don't send any more data and then go away and do stuff and then send another byte saying send data again but I don't think that would help here so I think we just need to make things faster so we spend less time doing things to the screen clear screen is a clear time sink because that doesn't work so we can certainly speed that up right now it's being implemented as lots of clear l calls we can certainly put in a primitive to actually clear the screen and make it optional that's what the cpm ish tcy driver does um it may be possible to speed up the brother to the interface communication using that cool trick I thought of but that's only going to save a handful of bytes per operation so I think clear screen is the way to go because everything else seems to work apart from that well apart from the the beep uh let's just try so if you set term to vt 102 whoops man so here's the man page scrolling through see there is something wrong at the bottom of the screen so let us do I have yeah so this is kind of garbage but infocump is the program that decompiles term info uh files so whoops if I do this that is going to produce I forgot to set the rows and columns rows 14 calls 81 so this is the term info file that describes the uh that describes the terminal we're currently using which is clearly wrong I thought it was working better than that actually and I'm not sure how much it's coming through but peering at the phone screen I can't read this text at all oh no no I can actually just about make sense of it but uh I was going to try and edit this online but I'm not going to I'm going to sort this out after the facts and tell you what happened um anyway let's see what we can do about clear screen it's working now because it's clearly marginal so what we're going to do to speed up things like arrays all is add a option so we say if emulate clear screen then uh we do all of this code if we do not then we are going to define do ed all to be the external constant constant or the external routine uh dpy clear screen so when we build that that of course fails because we haven't defined emulate clear screen so we're going to put into constants so emulate clear screen is zero meaning do not uh we now need to import dpy clear screen uh oh right we can't use equals for there we have to use eq u can we can we actually do that also it turns out that the routine we're using to do it is uh being used by other things so let's just shunt this out here so that it that's still a fall through but it could be not yeah I could just one that you could do that but apparently you can't so we're going to have to to be cleverer if emulate clear screen call that otherwise call dpy clear screen if emulate clear screen call that otherwise call dpy clear screen so then this just becomes a end if this goes away and it compiles apart from you know not having a dpy clear screen so we're going to put that in here dpy clear screen so what we're going to do is set all the dirty bits so that will be dirty buffer dirty buffer plus one screen height minus one like that and the screen itself back buffer back buffer plus one initialize it with a space and fill okay so that should be way faster than what we've currently got but we can still improve this this is a big enough chunk of stuff to clear that we can probably use the the dma engine for it but this should do for now okay however now I think about it I think I'm doing this wrong I don't think I want to emulate this I want to emulate this because this is used by arrays start to cursor and cursor to end of course if you erase cursor to end when the cursor is honed at the top left corner then that's actually going to do a lot of work so let's back out all the stuff we did by repeatedly pressing the u key okay go to constant emulate clear lines no let's call that clear a for clear area if emulate dpy clear area call our emulator routine otherwise call dpy clear area do the same there and do the same here so if emulate dpy clear area equals zero oh wait if it's one then we use our emulation routine okay so dpy clear area go here dpy clear area end of screen clears rows d to e d inclusive to e exclusive so first thing we're going to do is we're going to keep our dpy clear s routine because this is a really fast way to clear the whole screen which is going to be the common case so what we do is are we clearing the entire screen if so use optimized routine otherwise we want to clear only this area so how we're going to do this six dirty bits so d is the let me double check this yeah e is e is exclusive d is inclusive so this is right so okay the number of lines we want to erase are like that put this into b we now want to copy the dirty bit address into d e and increment it and go is this worth it that's quite a lot of code one two three four five six seven eight nine ten eleven twelve thirteen bytes and there's only 14 possible rows so i think this is better done the old-fashioned way so that is uh one two three four five six seven bytes per iteration this is 13 bytes plus two each iteration yeah let's go with the simple code now this however we are going to want to use ldir for so first we have to calculate the addresses so okay now we want to do the same for e get the last line however i do want to be sure that if somebody asks for because the the end range is exclusive somebody might ask for line 14 therefore this table here must have 15 lines in it the last entry of which points to one past the end of uh the back buffer we can't put that into d e because we will overwrite what we've got there i actually think we want to do this the other way around so we have to put this into bc because we have no other registers available and we can now put that into d e we're not actually going to need the the row data after this so in fact we can do this this swaps hl and d e which means that we now have our address in d e and our range in hl so the first row is going to be is now in h so this gives us the first row in hl here and the last row in d e so we swap again and then we subtract and we then put it in bc okay uh now our we however we have just lost last plus one because that was in hl but we don't need it anymore all we need is first which is still in d e so this then allows us to do this everything is set up for our copy and we can do ldir that is more code than i really want but uh hopefully it'll work right sbc and we want to clear the carry nope that is the uh that's the six of o two version now i just had this same question a little while back so here we go ccf let's have a quick code size check um that lot didn't compile into terribly much code this is all pretty efficient too actually nearly all of these instructions are one byte we're looking for clear a which is here so here's where we do the dirty bit stuff right here's our arithmetic and yeah most of this is what sbc is a two-byte extended instruction yep okay i am going to write that and see what it does and the answer is it crashes the system you know what i forgot to do i forgot to actually add on the two values to the back buffer address table oh dear well i found out why control g that is generating a beep was producing garbage and probably the reason for a lot of other garbage which is remember this optimization i did where i was using deck rather than actual comparisons doesn't work i mean the deck bits fine but stuff like this is not fine uh beep is a seven and of course if a is seven and we subtract eight then we get a minus one or an ff which means it's going to fall all the way through here and hit print printables so this test here for characters less than 32 isn't going to work so yeah i'm just going to take the whole thing out and replace it with old-fashioned compares it's slower and it's longer but it's much more likely to work this should be compared with 27 and this should be compared with 32 so this will probably improve things a lot i captured what it was doing when i tried pressing delete and it is indeed doing a csi it's doing a backspace and then a csi k which is here with no parameter so that will end up being a zero so that's doing a do csi l cursor to end so what's wrong with cursor to end looks okay to me so what this is doing is it's erasing everything below the cursor and then doing this i wonder if that seems more likely to be wrong because this is going to be implemented by printing spaces so this is actually printing spaces i decided to do it like that probably because i hadn't come up with the new semantics for dpy pranae okay we can simplify this lots so this is supposed to clear from the current cursor position to the end of the line so we load the current cursor position we then are going to do a loop the wireless yeah we need to load the current cursor position into d e now we're going to do a loop where you print a space and then see if we're at the end of the line we probably want to do the test first yeah so let's do the test first so can i just do a ret z there do i need to dirty the row cursor to end yes i do need to dirty the row but that can happen here and that takes the cursor position in uh no it doesn't because i'm getting my vt state machine mixed up with my display this stuff doesn't have to pay any attention to the row dirtying okay so all we need to do is we want to save a and de so push af push de load c with character we want to print pranae pop de pop af ink a jump back to dot one so that's smaller and simpler code and we are going to do exactly the same thing for this one so this is slightly different yeah so a is going to be easy with this we're comparing against a constant here we're actually comparing against e therefore we need a e we're comparing against e which contains the current cursor position so we need another register to put it in can we use a i think we could so compare with e return if equal otherwise push af push de call dpy pranae pop de pop af ink a jr dot one yeah that should work better i've also noticed that insul and dell don't seem to be working right so let's don't recall changing this code recently to be honest so it's possible it's trying to do something else these are both pretty straightforward okay i'll try this as is well there were some stupid typos to fix but if i type and then i press the delete key it deletes which is nice let's try come on as i control you fantastic okay so what does nano do well that looks like garbage see this is it is scrolling a section of the screen but i think what it's doing well of course it has to be doing is redrawing the that entire section of the screen which isn't particularly optimal but as i told it that we don't have scrolling windows that's the only way it has to do it that looks like it's working oh yes i forgot to say i did a term cap file so if i turn that off which is this let's try that again less that fast scrolling was not really what i wanted but i can't seem to go up and down either it's not right uh this is the a copy of the vt102 and that's definitely wrong a copy of the vt102 term cap file term info file but i took out the stuff that our terminal doesn't know anything about but it's clearly still not right but it's getting there i fixed a whole pile of term cap bugs and now vi works and in fact most things work or so although there is still some screen corruption now what's interesting is if you scroll down it works fine scroll up and that happens so yes something is very clearly wrong in the scroll up code so that is a good place to look for more bugs the problems with scrolling up are clearly due to insert line here which i think is you guessed it another stupid typo so looking at this lddr copies from location of hl to location of de and the way you set this up is that hl is pointing at the last line of the screen and de is pointing at the second last line of the screen so this is actually going to copy from the last line to the second last line in other words it's trying to scroll up rather than down so i think that these two are the wrong way round and that should be like that and as you can see it now seems to be working which is great unfortunately uh it's still not quite right i mean you can see like it appears not to have been clearing the entire line which is wrong so no no that's not quite right i mean that does seem to be the problem if i do ctrl l to force it to redraw everything you'll see what's different let's try that again scroll down to the bottom and go up yeah i don't think it's blanking the last line the other thing is if we try to scroll down that is also quite wrong luckily the scroll down issue seems to be fairly straightforward which is this code here so scrolling up means that deleting the top line so that all the text then moves up one scrolling down means not deleting the last line but inserting the first line so that should be fairly easy to fix now both of these however seemed to be failing to blank the last line which is this code here that looks straight forward so it's the back buffer it's the we set hl to be the address of the last line of the screen d to be d to be one plus that yeah that should be fine unless i'd wonder if zmac does precedence properly oh for 9f oh for a zero no that is correct code so it's this calculation wrong that's line screen height minus one is 13 yeah this should be fine so why isn't it updating i mean it's not a problem with dirtying the the row why am i doing it like that that's a slow way i just load uh or even do it like that that's much better so you see this is three four five bytes and doing it like this is one two three four five bytes which is therefore clearly better in every way in fact it saves a few cycles line here we go so why does it not seem to be blanking the last line up here we're loading hl with back buffer end minus screen width that should be the same value as this which we know is oh for 9f oh for 9f yeah there should be nothing at all controversial here oh i'm an idiot of course uh blank last line is correct for deleting the first line of the screen because everything scrolls up and the last line ends up blank inserting will need to blank the uh the current line so this is wrong in fact i don't know what is blanking but it's the wrong thing so uh we are going to want to save the line address that we calculate here let's just dash that on the stack we run out of registers so unless we use the alternate register set which we could but it's annoying yeah it would be too hard to do well it wouldn't be worthwhile the thing about the alternate register set is that it swaps hl de and bc with these which is great if you want three registers that you can use without corrupting anything else but copying from one to the other is ghastly you either have to go through the stack but you're doing a push a exx and a pop or you have to do a piecemeal through a which is even worse anyway we push the line address into hl we pop it back uh and then we are going to clear in hl like this so scrolling down works just fine as you can see scrolling up is a bit more problematic so the fact that we're getting uh partial command codes suggests to me that we're leaving it in the leaving things in the wrong state so the state machine is expecting or rather the program is expecting the state machine to be in waiting for character and it's not it's into something else so it receives the escape doesn't know what to do with it drops out of whatever state it was in and then prints the rest of the command code as letters this is almost certainly because one of our insert or delete line commands has forgotten to call set state waiting and that's going to be this one so these three are all executed from within the escape state that's not csi state that's just received an escape and they go to here which just does the thing and calls update cursor so let's just change those we're also going to rename these to something other something that doesn't have a tty prefix so that will be call set state waiting and we want one here to do reverse line feed we don't want one here because do line feed will do it for us tty new line to do new line uh now tty carriage return wait a minute wait a minute these all terminate through update cursor we only update the cursor at the end of a command uh but if we bail out without calling update cursor like we do here oh hang on hang on that's called set state waiting there i think we can simplify this so we do want to rename those things but let's not call set state waiting here and we're going to rename tty carriage return to do carriage return because uh symbol starting tty are exposed to the outside world well these are exposed to the outside world but we also want to reserve that prefix as well just avoid confusion so tty set x can become just set x tty set y can just become set y okay and these tty cursor x can become cursor x tty cursor y can become cursor y uh command flags it's just command flags current param is just current param and tty parameters is just parameters okay escape state no this has called set state waiting uh maybe it's happening in csi no we've called set state waiting here that's weird so um i was sure that was what the problem was so where are the places that say do line feed can be called from just make sure that compiles you said yeah yes that does compile okay do line feed happens from inside print ascii and we have called set state waiting advance cursor happens from print printable and we won't get here at all unless we are in set state in state waiting escape state waiting new line where do we call new line yep yep only two places in fact we know from trying the program that it only seems to do this when scrolling up which will happen through uh well it's called scroll down because that's the way the text moves which will happen through here so where is do reverse line feed coming from here we're in waiting those are the only places okay so about scroll down reverse line feed here so maybe it's using one of the other entry points to install for example this one that is the only one there is we're calling in a dpy install from here and from scroll down and nowhere else so do csi it'll happens from csi non private and we have call set state waiting we are in the waiting state here so we must be in the right state okay maybe it's something else maybe we're spending so much time doing that insert that we are dropping a byte and that bite would be escape because we're in the printing state without that escape it's then printing the characters remaining i think that is very likely and we can check for that by commenting out if you won't do it here we'll do it here by finding the install routine which is here and we are going to skip the bit that does the work so if this is a state machine issue we will still see the garbage printed on the screen if this is a timing issue then we will not see the garbage written on the screen all right let's see what this happens we're at the bottom of the screen so we scroll up and what do we get garbage i was honestly not expecting that i thought we were going to get nothing and there was a timing issue that's not what i was expecting and i am now slightly at a loss so what you're looking at here is a hex dump of vi doing it scroll up and here this these three bytes you can see where the cursor is flashing is a csil sequence which is insert lines so this is doing something wrong it's got it's somehow in the wrong state when it processes the escape following resulting in this position code being printed so we know this is going through csil with no parameters so here is the csil code and it's really simple we load a with our parameter set flags if it is non-zero do nothing otherwise increment it in fact thinking about it i can probably improve that to this so this will subtract one if the value was zero and only then it will set the carry flag this will add on the carry so that would be four bytes and this is one two three four bytes oh well anyway we do this we shunt it into a and then we call install the specified number of times which in this case should be once uh and dj nz makes it happen b times so that there's there's nothing particularly wrong there it's the same code we're using in lots of other places so what's wrong here well to get to csi non-private we have to have gone through here do we yes this is defined in exactly one place so we must have come through here we're in the right state so we just plain adjust plain return will deal with it hey look what's happened i can scroll up and i can scroll down what i did was i went into the interface firmware and i increased the serial buffer size from eight bytes to 256 bytes and now we have a big buffer on the interface which is uh storing up bytes while the brother is busy this kind of makes the entire ring buffer we put into the interface code on the brother useless because the brother is now doing it all for us so great and i have a bit of a suspicion that we might be able to do something similar with the output but anyway this is now looking like it's working there's still a few minor glitches but most things are all right so let's uh so nano works uh you can see that there's some overwriting problems here uh this could be my tab code not printing spaces but i thought i had just fixed that actually scrolling is not brilliantly fast in nano this is because nano does it scrolling by redrawing the screen so that's quite a lot of serial transactions if we do the same thing in vi i'm just trying to find a decently big file hang on i can make one so we can then scroll down and it's nice and fast because uh this is scrolling the entire screen using a single primitive and only redrawing one line it still can't quite keep up with the keyboard repeat key which is a little irritating and we still get that snow and the redraws are occasionally a bit glitched but this looks usable so i haven't tried this one yet let's try word grinder word grinder is a cursor's program and that looks plausible not bad not bad uh you notice that the this bar down the bottom takes more time to draw than the rest of it that's because it's unicode so each one of those characters is being transmitted as three bytes okay let's try a menu yeah that's a menu it should be a nice box but you know that that's more unicode file open uh yes i do want you to discard uh there's enough space on the screen for two no three lines of file browser which is working and scroll up and down so find the read me again the keyboard auto repeat is far faster than the ability of the terminal to keep up and scrolling up there's a few weird things these eyes look wrong it does occasionally fail to print the first character of lines but that's kind of working i could probably almost use this okay um i think i'm going to call this relatively complete i mean there's more little bugs to fix but i don't think i'm going to do those on video because it's just not very interesting i do wish i had hardware flow control because then i could crank the board rate all the way up to 115 kiloboard and we would get redraws as fast as physically possible that will transfer data to the brother faster than the brother can draw it uh but that's not safe without it now i have figured out how to turn hardware flow control on on the raspberry pi but i'd need to rework the interface to get enough space on the fpga to fit the uart because we can't use the built-in uart with flow control on this you have to build your own out of logic so i might do some exploring there also the one thing i haven't done anything about what you can see here uh is italicized underlined and bold text and of course reverse text to make that work we need to start working with the attribute area of the video memory this is like easy conceptually it's just another set of video memory that contains the bits per character and there are eight bits that do different things and i know that the brother controller has got quite a lot of different attribute bits you can use however this of course will double the amount of video memory that we need to update each frame and there's already a little snow at the top of the screen when scrolling so really it's currently set to seven lines of update per frame we need to switch that to six and of course doubling the amount of memory that gets updated switches it to three which is not a lot so i'm wondering what i can do about that i do have a few plans i think i am going to do some experimenting to figure out what it is that's worth doing with these various things and then i will come back and report so there's probably going to be more of a gap than usual until the next video as i figure this stuff out and then i'll do a summary anyway until then