 So there's one major piece of work left apart from of course the bug fixing Last time we got the pen controller working so that we can now detect touches on the screen and Get back the raw values from the touchscreen controller Unfortunately these don't do us a lot of good because we have no way to turn them into pixel coordinates that gem wants So what we have to do is to figure out how to calibrate and map the touchscreen into pixel coordinates now This is actually pretty hard, but luckily Cyprus has this handy document Which goes into all the physics and all the maths and eventually comes up with this convenient page full of formulae and Rather more usefully this sample code so what this is is There's a routine here Which converts the touchscreen controller values into pixel coordinates and there's this routine here That calculates the vector of coefficients that C index here That this routine needs so what we're going to have to do is To integrate this code into our pen controller stuff So that when something happens we can read the touch screen turn into pixel coordinates and pass it to gem and We're also going to have to write a program that allows the user to calibrate the touch screen Because the calibration coefficients will be different from device to device So that's going to be fun The way I'm going to do that is to write a standalone Atari ST program that runs under TOS I've got here some boilerplate for a very simple program that simply opens a connection to the graphics system clears the screen and then waits for mouse press Turns out that Atari TOS has quite a sophisticated abstract graphics system Called VDI all these V underscore prefixes are talking to VDI and It will handle bitmap displays printers off-screen bitmaps Metaphiles etc so We're going to be working with that. I'm not going to write a full-on AES program because that seems hard However, in order to speed things up a bit, I'm not developing on the Alva smart itself instead. I've got The satari ST emulator running emutos so that I can simply Compile our program turns into this binary here, which is actually Surprisingly big due to the tool chain. I'm using but that's fine and if we run it Get a blank screen wait for a mouse click Exit back to gem So I think this has got all we need to actually make the thing work. So Let's actually Start some work on this so let's copy our our program into Utils Utils isn't quite right tools. I think so Tools Dana Cal see Here is the command line needed to actually build the thing It uses the Atari Mint tool chain. This is why the binaries are so big There's quite a lot of mint POSIX emulation code that we're not using Luckily the binaries it makes are still compatible with TOS There's a gem library that is actually a third-party thing. It's not part of emutos and We just compile the program into a PRG Copy it into our Atari ST hard disk image and we're done. So let's just Little Oh, yeah, I put it in Tools Okay Run the emulator Try see Dana Cal prog it is intact the same binary Okay So what are we going to do here? Well? Here's the existing boilerplate code first create a SVDI application and we get back a handle that I don't think we use Open a handle to the graphic system. This takes Four parameters, which are the screen bounds that we get back that we're ignoring Then we open a virtual workstation a workstation is a VDI thing you draw on and A virtual workstation is a workstation. That's multiplexed on top of the actual screen The interface is kind of primitive it takes and returns an array of shorts and Here we are setting up the the input block which contains information about what screen type we want the coordinate system and here we're using native pixels and All these ones indicate the the default types of Things like drawing patterns and so on we have some documentation here so let me find the VDI control open virtual workspace So line type color markers fonts etc etc and what we get back are Some stuff that we really don't care about No, hang on. This is still input. Oh, right. This is for printers. We don't care about that Right. This is what we get out and the two things we care about are the first two coordinates Which is width and height So let's just These are all short Sign 16 bit values and we don't just care about any of this We might care about things like Character sizes don't think those are returned actually. Oh Here we go Now that's minimum a maximum. No, I don't think we care about that These two lines of code are where you actually draw on the screen first we turn the mouse pointer off If you draw on the screen with the mouse pointer enabled it'll corrupt the area under the mouse pointer Then we clear the workspace completely Then we enter a simple loop that just keeps pulling the mouse until a button is pressed and then we exit So let's actually make some of these things global WK is the handle for our workspace and Let's try and draw a line so VDI Do you want graphics library? these Do not do what I think they do These are all to do with drawing gem user interface elements So I think we want here we go VDI output functions, and I believe not all of these are available out of the box. We might need to load extra Modules to make things like ellipses work, but luckily we don't care about any of them all we want is to draw a line P line Connects all points with lines that draws a polygon bar filled rectangle cell array Draws a rectangular array defined by the input parameter Okay, not sure that's for This is drawing text Justified text that'll be useful Interesting should be a line somewhere. Oh, I think I know where the line stuff is Oh, no, these are the ones that you need to load the extension module for So there's the line a Interface this users Virtual op codes to allow a program to do things without having to go to the trap interface And I have a bit of a feeling that lines are in there unless you're supposed to do it with this I Don't want to use line a if possible from C because it's tricky But I think Yeah, let's just try this. Let's make a helper So Assuming that this is XY pairs. We're just going to do No, it's one y1 V P line workspace handle number of points and The address of the array Okay, so let's now just try doing from naught naught to X max Y max and let's see what this does Well it compiles which is a good start. Hooray, we have a line excellent so What we are going to do is if I find that That document This will actually calibrate any three points provided you can give it the pixel coordinates and the touchscreen values But it works best if The points are arranged approximately like this So that you end up having ten percent of the screen margin on all sides The The palm os it the palm os's own Calibrator Once a point there and a point there and then a point in the middle I think it's actually doing two-point calibration But we're going to follow the instructions here so we need to calculate where our three points are and We are going to so this green X's three and Touchscreen X's three So this is going to be first point ten percent of the X and Ten percent of the Y second point Fifty percent of the X ninety percent of the Y That should be a one third point 90% of the X 50% of the Y and we are going to Create a helper that draws a touchable crosshair at the location given so This is actually pretty straightforward. It's just going to be X minus ten to Y to X plus ten Y and the same for the other direction So that will be crosshair SX naught S Y naught like this see so much faster than Downloading something to the board and that produces Garbage crosshairs That should be a plus. Okay So we have some crosshairs now We want to be able to tell the user which one to touch so we're going to put a Another parameter on Which I can find my documentation again is here Can we draw Yes draws an unfilled rectangle with rounded corners, and I'm guessing this is to Coordinate so X minus 15. This is top left and the points of this input And this shall be true false false And in order to get proper booleans and see you need to include stud bull Okay, that is pretty much what we want. Although I have forgotten to This okay, so one of them is now highlighted and that's quite a nice rounded rectangle to be honest okay, so Let's do a bit of refactoring. We're going to want to draw the screen multiple times So let's make a function to actually do it so and we are going to Make a counter which is the Which targets the user's pointing at and we want C99 in order to get the nice for loop structure So that compiled Okay It'd be nice to have a message show. So let's Figure out how to draw text. I'm betting we want this one. Oh, no, this does Justified text. I thought this would allow centered text. So to draw Text you want this In the default font But we want this centered So we're going to have to figure out how wide that string is Oh, do you do this? Sounds like an inquiry function to me is Put back the cell width for the specified character. So just one character stent Returns the minimal bounding box of the string. Okay, so so let's calculate the Bounding box and we should get in the output array the size and The string is in the first quadrant That's a mathematical term and I can't remember which one it is it Go coordinates. This is the BBC bite size stuff This is not really what I was looking for but it'll do so given a set of crosshairs you can divide the There's a proper set of crosshairs does not Given a set of crosshairs you get four zones which are quadrants and They have here we go and they have Characteristic names. So the first quadrant is Here this means that the text will have its bottom left corner at zero zero and So we are looking for the Other coordinate will contain the width and the height However, the documentation does not actually say Touches both the x and y axes Hmm Yeah, because it's possible that the two coordinates given are in fact Here and here So I think we're going to need to do width is Output three minus output one height is Output two minus output zero So therefore the We want to draw our text at That location So let's try that This should be Dent, okay, well It has abjectly failed to center our line of text unfortunately and getting tracing from here is A little bit trickier than it looks, but let's just try this And seeing what it says If it says anything at all. Yeah, the console's just vanished off somewhere We might be able to use Beacon out But honestly, I'm not sure if this particular library's got it that will send text to the The bios where it should come out somewhere useful Okay, we're gonna have to do this the hard way It's not what I oh That explains why That didn't work just change this function prototype to be the same as the Other texturing functions Okay So that's width and height Honestly, that's not what I expected from the width. So gem normally works in Unicode to UCS to Where each character is two bytes and I believe that this function converts from characters to UCS to Using this thing, but why are we getting a width of zero X Y? X Y not one two Well for a start I've got my width and my height the wrong way around So now I'm puzzled as to why the height is zero however At least this should now be centering our text like so so the idea is the user will then touch here and Well here and here and that will then Calculate the calibration coefficients Okay, so To Actually do the calibration What we're gonna do is we simply spin waiting for a mouse touch When a mouse touch occurs We need to Well, we know where the user is touching Because they're the values we pre-calculated earlier. We're assuming the user is touching the appropriate target So we don't need X or Y So what we're going to do is Read the touchscreen somehow going to get on to that bit later Advance to the next target if we've run out of targets stop and redraw however Before we do anything we are going to Wait for the user to lift the stylus up again and in fact this will happen After reading the touchscreen So So, so let's run this so click Then moves on to the next target click click and the program exit Okay, this is Actually proceeding more quickly than I thought and we may have to move on to the next stage of testing more quickly Anyway, once we've got to this point we now have an array containing screen coordinates and touch coordinates so we need to calculate the Coefficient and then program the Touchscreen so we go to our Data sheet the coefficients are signed long So this Is our code Can I copy this? Apparently I can't at least not with this tool So I know Just see if I've done this from If I can do this from here The Chrome PDF viewer is slow and really annoying But it's got a few nice features. Yes, and this is one of them. Okay, so we have some really garbled text so Calibrate this we're just going to need to Copy the code Which is What are these? So TP is the touch point DP is the display Okay, so TP TP arrow X is TX TP arrow Y is T Y DP arrow Y is SY and DP arrow X is SX and we do need to put in Indexes to everything so this is TX to Y1 I2 one And it's worth doing this TP TP plus 2 arrow X is TX 2 and the same for Y plus 1 TY1 same for X same for D Is that all of them? Could be so this is C index becomes C SX is zero minus SX See now the code's shorter on all the one line you can begin to see the commonalities between all the various Calculations, I'm very glad I wanted to understand this. Okay, and now the same again for This axis Now actually this is smaller and much simpler code. Okay, this is the complex one No, it's not no six is the complex one This could probably be cleaned up if the touch coordinates were all in longs rather than short Wonder if that's worth doing probably Okay, that compiles Yeah, let's change these so then I can simply go through this and Move all of those right these are actually there are There are bracketed expressions in these which now become much more obvious So I can put these in the right place. I've assembled that Yes, but it's lost all the symbols. Yeah, I'm just curious to see what this code turns into probably not brilliant But anyway, this now calculates the seven coefficients so we then need to set the Set the charts in coefficients and then we're done And that is all the program we need for the touchscreen Calibrator And this will turn into once compiled with a smaller tool chain a very small program that can just stick in your Auto folder and it will get automatically executed on system startup. So Click click and it's done However, we do need a way to be able to read the raw value from the touchscreen without going through the calibration layer and to Set the coefficient vectors and the way we do this is By adding a system call to the To the BIOS and there's a bioslayer and x bioslayer and Apparently the x bioslayer is where you're supposed to put it and here is the lookup table for them Yeah, it's just a simple table. So adding No, actually we can use this Vec Thing I think we can No, we can't Okay, I was hoping that this would be a two-way lookup table where you could give it to the vector number and a callback but actually The this is only used for debugging Right, that's annoying maybe a BIOS call instead this works exactly the same way. I was hoping to be able to allocate a new Entry point a new number somewhere up high. There is that array used from yeah BIOS x bios appears to be doing the work given the and it gets passed in the The number of entry points and the table of vectors and Then this is the code that goes and looks it up Blast so if I were going to add more They would need to be At the bottom and I bet that something's already using these Let me go and look to see if I can find a table of x bios entry points so here is the list of allocated x bios entry point number and who they're used by and Actually, it looks like we're lucky Because this block here that ends in 8d and is at the bottom of the emu task table is Here and there is actually a gap until the next allocated one. So we will just claim 80 in 8f so I Think this is right If with no expression that should be if death in fact, we're going to do to define a new Configuration symbol Good, and now we want to put something down here probably at the bottom x bios comf with x bios zero and if Okay, and in x bios to see we want and this is going to be Raw read is going to is going to pull this the raw state of the touch screen without going through the calibration layer and Calibrate is going to Set the the calibration vectors And this is going to be x bios unimple 8f Okay, and now up here Touchscreen x bios and then we need the two prototypes But the two trampolines for debugging 80 and 8f and our values are going to be Why state And calibrate is going to be a pointer to Our seven vectors Calibrate okay, so this should fail to build Correct, we do not have prototypes of These two and so we're going to put these in here, I think No Do we need a new Touchscreen header rather not Mouse dot age will do Okay, and that's now fails to build because we do not have implementations of these so these are going to Well, really they should go in mouse dot see Yeah, let's put them in mouse to see so if with Phoenix bios in Dana Dana TS raw read x-y state in Dana Dana TS calibrate Okay, and now this will fail to compile because we don't have these So let's go back to mouse dot age Copy these Go to here Where are we going to put the touch screen stuff next to here, probably We have to these need to go in Here and these should be void and now we need to update these change the prototype Okay. All right. So what this is going to be doing is Is just this essentially and does pen send receive? Yes, it's it is atomic it turns interrupts off across the call and this is going to be PF data and Whatever pin this was connected to I Forgot to note down which was did I Pen interrupt good. Okay. That is TS raw read So TS calibrate is basically a matter of copying the seven longs into a Array that we're about to define up here. So this is just going to be Seven no previous prototype for Dana TS raw read Dana TS calibrate Good, and we have an image. So now we have Hopefully the x-by-off part of things and I'm just going to So this isn't not actually using the calibration vector for anything But it should give us something to test with Okay, so now if we go back to the calibration Here we need to call raw read Which we need to call a raw x-bios function? I'm going to have to go and look at how to do that So it's gruesome, but I think this is it so this makes a trap 14 or x-bios call taking a word which is the trap number and Three longs which are the three pointers for the parameters So down here for the coefficients, we're going to want to do trap 14 wl 8f is the opcode and It takes a single parameter, which is the pointer to our coefficients. So this compiles into a binary and Let's just try running it this will probably oh, yeah, I know what I did I I'm using this version of emu tasks for the Aronim image and because I did the make clean to build the The Dana version that got rid of the ROM. So let's run this. Okay click Okay, it appears to be ignoring the The extra traps which is correct. That's what we wanted to do Okay, so Now We need to copy Dana cowl on to the Dana's memory stick and Try running this kernel with it and seeing what happens So here we have the usual rather muddy video This time using a cell phone. I hope that will make things better. So if I steer the cursor Over to here very carefully We're using the keyboard and run it good good. So This is the point where we would normally touch the screen However, I haven't actually done the code that hooks up the touchpad yet, which is a bit stupid So the only way to interact with it is using the keyboard mouse So let's just touch Touch touch and back to gem Okay Was good to program works We didn't get anything here. I would expect to see more tracing So this should be set correctly. It should have hit TS raw read three times Although there's no tracing there yet. It should have hit TS calibrate Which should have gone to Here we should have called Dana TS calibrate and yes that has actually compiled the code in So that should have worked and then Dana TS calibrate should have gone to Here so we should have seen something come out Yeah, and there is code here, too. I can see it Calling K printf so that should have worked Why is it not worked? Well Let's go over here and Turn x bios debugging on this will be quite spammy But we should see every call to an Espa x bios function. Is this being called? Yes, it is Okay. Well before we do that Let's just do the other half of the keyboard stuff now We have to pull the touch screen. So every time a tick We are going to Dana poll touch screen so Paul keyboard Paul touch screen Dana Paul Touchscreen so this will be called every time a tick and what we're gonna do is look to see whether There's a pending mouse event At which point we will decode it calibrate it well convert it and Send it to the system So the first thing we need to know is Was the pen being touched the previous tick the reason we need to know this is because while detecting when the pen is down is easy because we just look at the pen interrupt When the pen comes off the screen we stop getting interrupts and we still need to send one more event with the mouse button up and To do this we need to keep track of whether The previous touch was pressed so if we were pressed or We are pressed Then go and do the logic At the end of the logic Detect to see whether we were pressed Sorry detects see whether we are pressed So we now need to fetch the X and Y from the Controller we are then going to Do the mapping and We are just going to do So you notice that there's this division by the zero coefficient We're going to detect for that Because if we haven't been calibrated yet, this will be zero and therefore all the stuff coming out of well We can't do this mapping to lend up dividing by zero. So that's not going to work So we actually want to do Screen X is coefficient one timed X plus coefficient two Times Y Plus coefficient three Divided by coefficient zero in fact, let's do so s y is going to be that's not right See for timed X Three of five Times Y plus C six divided by C zero Okay Calculate whether we're pressed or not So that the last time through we were pressed But we're not now So pressed here will be false But of course as soon as the pen comes up the value from the touchscreen is Incorrect, so we're actually going to want to So this will be the old coordinate So if we are pressed and we're calibrated Calculate the New coordinate and Press will therefore be true If we were pressed, but we're not now then Hang on hang on we are pressed now Therefore update the coordinates if we were pressed or are pressed now send the state and This is actually done through mouse through call mouse feck and this is So this is a packet of Bytes and the packet can contain either absolute or relative coordinates And I believe that this is sending relative coordinates So let's go and try and find someone who's doing absolute Okay, this is always sending relative coordinates. I wonder if we can do this so mouse rail pause Are we allowed to send Absolute packets So this is sending relative Coordinates hmm mouse monitoring two teams can be the Can return relative or absolute because of course the pen can only ever send absolute packets We can fake relative packets, but only if We know where the pen currently is I'm going to have to go and look something up. I think So here's what an absolute packet looks like it's an f7 followed by a byte for the buttons Followed by x and y The actual button reporting is a little bit More complicated it looks because we need to track the new state as in the old state So Okay, so if we're pressed now Update the state if we were pressed or we are pressed then we need to make our packet of six bytes so Left button down since last report is going to be true if We are pressed and we weren't pressed Left button up since last report is going to be true if we Are not pressed and we were pressed, okay X coordinate most significant bite X coordinate least significant bite Same for why send Okay, and and update our state variable Okay, I think that will do it Does not bill. Oh, yes. This doesn't want to do booleans. It wants a Atari ST style booleans Okay, so let's write to this and see whether it works Okay, and run doesn't start up immediately because there is now a Decompression stage to make uploads faster Okay Drive C Program gone. There it is Okay, touch the target Well, that ain't working Anyway, let's let's try the manual buttons to see if I can see No calls to the bios are being made So it is just not working. I wonder why So this is the This is our program I Think I put debug information in capital D Right, it doesn't have any Symbols and Yeah, yes, okay, so if we instead of trying to compile everything Let's just do that that will then create a Day the cal dot oh which we can disassemble D. I was disassembling stuff before RDS Okay, so look for main which is here. So trap 14 WL trap 14 The opcode is 8f. Let me check to make sure I got that right 8f calibrate the single parameter is An address. So why is that using the data register? Yeah, see it should be a pointer. Oh Here it is because it's an absolute value That's being fixed up to an actual address. Why did I make that static? It doesn't need to be static. There we go better code So opcode here is the address of the Coefficient array here it is Clearing lots of stuff. Let's take a minus g in Yeah, we go So every single one of these calculations has turned into a clear operation Why has that happened? So s x s y t x and t y are all longs and These are operating in all of those. Oh well for a start. This should be a seven Don't think that will help but still not generating any code So the reason it's doing this is because the compilers figured out somehow that None of these values are being set which they're not because I forgot to set them up here So this is actually going to be touch x target Touch y target There we go and now we have lots of code for that computation This still does not explain why it wasn't Calling the traps at all Lots and lots of code. Yeah, lots of calls to Multiply as you would expect Because this thing does not have a reasonable hardware multiply So at least we should now be generating the right coefficients, but it does not explain why it's not actually passing in the right value Passing in the right value why it's not calling the trap in the first place Let me scroll up here So this is where it actually touches the touch screen. So we load target multiply it by four By doubling it twice That's the that's Tx that's T y and yeah, we push the values. Okay, that should work to one for two is 80 so is This Wrong somehow. I don't think it could be You got lots of references to x bias unimple and at the end we have three References to the local text segment B4 8 before There's managed to whack microphone It doesn't say what they're referring to Even I assume it's pointing at these. I mean there isn't really anywhere else. It could go So my suspicion is that it's not actually Calling the right thing at all Now are the the binding I've found M68 K sorry mint include mint Boss binders H. So this comes from the the mint STK Because that's what I'm actually compiling against and it has lots of bindings to the x file stuff So I'm just using those now it possible that the traps are different in mint than they are in Ordinary toss this would surprise me but that would explain what we're seeing X bios trap trap 14. So it's falling into this code bios x bios After having set up the various vector tables and the number of entries well, I will Try doing a clean build and also copy the new program and See what happens Okay, let's try this So runs on the program run the program. Okay Press now Let's try a mouse click Nope, so this is the program that I built the timestamps right if I build the iron in ROM and This has got debug x bios enabled in it. We can see x bios stuff show up So when we run our program here, right? This is showing the calls so this suggests that The program is right 121321 Select it and do control I Yeah, that is showing the same thing that the emulator screen is showing I've added some tracing here. I think my logic is not quite right So it thinks the screen is pressed. Ah, you see the red light that indicates serial traffic this is Inverted Okay, now we run it and see what happens Okay, so if you charge the screen Now we get our tracing good. Okay, so you run the program Still nothing Fantastic, so it's possible that the desktop is only desktop of the VDI is only listening to Relative mouse reports Okay, anyway, let's try Here and Nothing, but we were getting it from Aranim, but we're not getting it from Emutos, but it's the same code compiled in the same way Okay, I'm gonna go look into how the VDI handles mouse movement So I did a bit of research and I think I have managed to solve both my major problems Or at least figure out the solution to the major problems now the first one is Trying to call the x bios vector and I think that what's going on here is that this chunk of vectors comp with DMA sound is Missing all the unimplemented bios chunks That would then cause if this was disabled and this was enabled that would cause all these numbers to be in the wrong place So that should be easily solvable by just adding lots of these So to start with eight zero and we want 13 more The correct solution here is switched using C99 designated initializers that would make all of this so much simpler Now the other issue was the fact that all the pen events weren't showing up in gem and So what I'm doing here is I am sending Absolute reports indicating Where the mouse pointer is unfortunately the VDI doesn't understand these it only understands relative reports so what we're going to have to do is to switch to sending relative reports and This involves figuring out where the mouse pointer was and then generating the appropriate delta so that code is in It's in the VDI S mouse in to mouse in Here we go So it is Somewhere around here. Here we go If the opcode is not f8 give up luckily the actual Current mouse pointer is stored in these global variables So if I do So we can see this is these are defined in the VDI So if we go to here This is a violation of layering, but never mind VDI H might be able to do the Get the current state of the mouse pointer as well. That would be nice. I was also doing that all wrong Okay, X and Y, but no mouse pointer. Yeah, we'll just track that ourselves so this is F8 relative report if the Pen is down then set the left button therefore Packet 2 is going to be the x delta, which I believe is going to be this and Packet 3 is the y delta, which is going to be that and the packet is only 4 bytes wide So that may or may not work The tricky thing is that as the screen is 560 pixels wide and 160 pixels deep Then if the user touches the left side of the screen and the right side of the screen the delta here is going to be too big So Let us Calculate the delta While dx is not not and dy is not not Then We're going to repeatedly send deltas until something happens and The actual amount we want to send is going to be the maximum value that we are allowed to send which is Minus 127 to 128 for a signed byte and actually before I do that. I will just go and check Yes See here It is reading a byte from the data packet sign extending it to a word And then adding it on to the existing coordinate So what we are going to want to do is greater than less than minus 128 greater than 127 227 Ddx dx then we do the same thing again for Y Then we send the packet then we Subtract What we've sent and loop again? Now This is still not quite right. This is slightly trickier than it appears The reason why it's not right is that what we're sending here is We're setting the button depending on whether the screen is currently pressed The issue is that if the user touches the left side of the screen and then touches the right side of the screen The first time through the loop when we send the maximum possible delta The button will be pressed and then the second time through the loop the button will still be pressed So the effect will be that the user has just dragged the mouse pointer right very rapidly So sending was pressed is actually more correct But this will of course not have the button pressed at all what we could do is Use was pressed and then Once we finished the loop we send yet another packet Using is pressed and zero zero. I mean it's ugly What happens if the mouse point was coming up? Well if the mouse point was coming up then The stylus is touching the screen and therefore the user can't move it particularly quickly So I don't think we need to worry about that case So this is actually sending too many packets Is there a better way to do this? What we could do is use a flag variable to say whether we're going again. We know where we're going again because of These will be out of bounds Then we can use the flag variable to decide whether the packet should be Was or is here So that on the last loop round when we know that the Delta is going to work It's going to fit in a single mouse packet Then we use the current pressed state the effect there is In the situation where the user is pressing the left and then the right side of the screens The mouse pointer would be moved rapidly to the right Then the mouse button goes down however No, now I don't like that either Because the the first loop will be a move the second loop will be a press But the mouse pointer could still be moving very far very rapidly So if you if you start at coordinate zero and you touch at 560, which is the right side of the screen so the mouse We're going to get a move then we're going to get another move to two five four and and Move to 381 Move to 508 and then the mouse button will go down as the mouse pointer moves to 560 So the last Delta will be a big drag and I think that is wrong so This I believe is more correct and I think No, let's leave it like that so this will Always be a move and a press When dragging with the stylus down this means that every move every mouse motion will be a Drag with the mouse down and then a zero Delta which should be cheap so Does this build? Apparently it does. That's an air spite for it because it's signed That's better and let's send it and see what happens Okay and run Optimistically grab the stylus. Okay. It's started Find the program is there. Okay, of course, of course, it's not working. Okay. Let's try the mouse click Fantastic who are still not seeing the x bios calls come through. I did save this What's this? Oh good grief Yeah, I'm not a fan of This particular piece of code however Yeah, the day node has no TT shifter no vidl no DSP no DMA sound So last entry will be o x 40 So the entire table will be the wrong size. Let's try this one again although That was not the only bug so Let's just do And let's see what happened now. Okay. Well the good news is I can see DX's and dy's appearing But the numbers very quickly Went all the way up to the maximum possible 560 by 159 of course it hasn't been calibrated yet so Sx and sy should be zero We should still get an actual mouse Touch. Okay. Well, let's try keyboard mouse click Right. It's it's now calling raw read the third one and This is the calibration vector that it's set Which is invalid? Okay, so we are actually getting somewhere is this the right Value for a left click. Well, actually I stole this from the Amiga So we should be able to So button one the left button is To hang on Wait, that goes in the opcode bite Fair enough. I'm explaining why that wasn't working. Okay Let's try this Okay, so execute in the program. I'm heartily sick of that mouse keyboard keyboard mouse Okay Oh, we got something so here are our calibration numbers which all look completely bogus so and Screen calibration zero is zero. That's not right, but I can see All these numbers are approximately correct Let's just change this to sx and sy since we know the deltas look Actually, that's not let's just add these Okay, so Where's our calibration code? Here we go now These look like complete junk so Why are they complete junk? This should be a pointer to an array with seven elements Is there something funny about the calling convention? I need to check up on code doesn't look right to me However, the big printf in the middle is making it hard to read so by removing it. I get much simpler code So you see there it is fetching the pointer parameter of the stack the C compiler has Figured out Wow, that's pretty cunning So it's managed to figure out what I'm doing and it's removed the loop counter completely That's I notice. There's no seven in any of that code. What it's done is It's here, it's loading the screen calibration Address into a zero it's figured out that the loop terminates at the seventh element therefore it's reusing The destination pointer as the loop counter, which this comparison here is doing So the entire loop has become one two three four instructions That's not bad Okay, so Here I can see it's called TS calibrate So we receive a long Pointer and we just pass it into TS calibrate is That valid I do not see a lot of addresses in here Here's one that's a pointer here's one. Okay, so you're obviously allowed to do that So this is calling TS calibrate which is in in Bios mouse Here so if I go and look at that code It's just a jump. It's left the parameter on the stack and likewise if we go into X bios Here's the TS calibrate shim There's just a simple trampoline that displays the A Message when an x bios thing comes in here it is Wait That's pushing D2 Alright, this is then loading our pointer into D2 Which is at stack pointer plus eight because this has pushed the old D2 We then push this string called K printf we retract over the old value of D2 I Am not sure what that code is doing. I'm going to assume. It's correct This is no, no, sorry. I thought I understood it, but I didn't okay. I'm just going to assume that's correct If we turn this off Then all that code will disappear well, most of that code will disappear and Instead our jump table will point at the actual functions. So the other thing that could be wrong is In tools is that we are incorrectly Calling the trap you see I do believe that's pretty much right my that command line will Build the program as a object file. So I can find the code Here it's doing the compilation FP minus 34 is the address of the pointer push onto the stack Push the The trap the the opcode which is 143 which is 8f call the trap But the numbers we got back were complete garbage. It's possible that one reason why they were complete garbage is because raw read This Was returning complete garbage now. I just happen to notice that this is passing in the addresses of The TX variables which are longs But I think the values such are actually shorts, so so I think we want to do that and I need to Copy the new program to the SD card Okay, so once again, we run the program and let's try calibrating Right and we now get an actual calibration vector Let's see if it works That would be a no So the sx and sy coordinates are garbage But as I move the mouse, you can see the move going in cycles. So Right, so what could be wrong here? This is returning three shorts as far as we all were Raw read here is passing back Three shorts as far as we're aware, which is fine because pen send receive returns a unsigned Or does it return a Signed word. I believe from memory it is it is returning a word from zero to 32767 So is it this calibration that's wrong It'd be nice if we had print f's in this program because then we could just dump what Dana-Cal thinks the vector should be so that then we can then make sure it's getting to the BIOS intact. Let me have a look at that Document Which is this so C index is a signed long The actual coordinates themselves are signed Int that is short on this platform. This is the the 8-bit psoc The other question of course is did I transcribe this code incorrectly? Don't think so. Are we doing the reverse mapping incorrectly? So all these should be promoted to Longs as far as I'm aware This code here screen calibration is a Long signed longs Leave their signed longs signed longs So this vector looks incredibly dodgy to me These numbers do not like do not look like sensible numbers of any description So either they are making it To the BIOS incorrectly or we are incorrectly calculating them Okay, then let's try this in our name. See if we can get some tracing out that bills But we haven't gotten to run this and nothing appears to no one's great surprise What happens if I? Run this from here Dana-Cal click click click Excellent we get numbers so that should be percent D That should be a percent L for a long Console and Because of course our name doesn't have the touchscreen X BIOS calls. Nothing happens. Excellent So now I need to deploy this onto the Dana So now let's try running it from the console and we get a completely blank screen with no information Fantastic that's helpful In fact is crashed whoopee So I'm guessing that isn't gonna work The numbers law looks still all still look wrong, so I would expect the X divisor to be negative because the touchscreen has Low numbers on the right and high numbers on the left. I would wait. Hang on. Is that allowed? Looking at the reverse mapping code Yes, it is so C1 would have to be negative Which it's not Yeah, I think these I think these calibration numbers are garbage. I Wonder if I can Persuade this to write to the bias so the data has actually shown up on the screen, but then the system dies it all goes away Because we can see that this trap has been executed. Otherwise, we wouldn't get this So where else can I put the data where we can put it to a file? Is there a sink? Try to see what happens Actually, no, I bet there isn't I think that will do fine Okay, so it runs. Well, it can be compiled so I'll deploy it and see what happens Okay, oh it crashes privilege violation That 198 FE is indeed in the kernel One nine Eight F is in the gem dispatcher If I'm running it from the VDI that shouldn't actually be being called But luckily the system survives and we have our cal dot text Which is empty so Assuming something to do with the trap has killed it. What happens if we don't do that? So we should just be able to run it again, but that's rebooting it's spotted that I changed the Card you can see it reinitialize the Card driver and that's a good crash. So we restart it The cal dot text is still empty. I do not think that It stood IOs working particularly well in this binary to be honest Though I couldn't tell you why Well apart from the fact that it's probably using Mint specific calls that don't exist on plain toss it doesn't seem to like printf. I Wonder is this not I mean We're not declaring very much data on the stack that shouldn't be a problem. I don't think anything could be Corrupting it we do have the right number of values seven longs zero to six Well, we can take it off the stack actually put that back We can take this off the stack like that now if we Dump it we can see that We need to rebuild the Version for disassembly so here it's doing the computation and after each value it's doing a right to Absolute address Here it's doing the f open here. It's doing the printf. So it'll be reading out of That address that will be Here Yeah, it's It's relaxed this Computation into an ad which is correct though. It's interesting that Aranim ran it, but the real hardware didn't Okay, well, let's try this Actually, I will put this back on Okay, so run it and it crashes again to no one's very great surprise It still hasn't written anything although Now I think of it We should be seeing the printf happen to This console Which mirrors the one on the screen? So I've compiled and deployed to this so we should be able to run that again But we did not see anything here and the boards crashed completely So we're clearly corrupting memory somewhere now. We could be Could we be doing it? here I Mean these will be addresses to Addresses of these stack variables that should be uncontroversial. So You see we're using vq mouse to do exactly the same thing these are slightly long These are these are getting the addresses of things on the stack using the frame pointer. So here We are wait trap 14 WLL this is generated no code do Why has it done that? WLL okay, it's marked as volatile So it should be generating the that instruction Regardless of Alright, it's down here. Okay. That's a bit of a That's actually a little bit annoying because had that been a problem. It would have been easily fixable But we are pushing three values onto the stack They're all 32 bit pointers. That looks fine Then we call the trap then we retract over the values we pushed onto the stack multiply target by four pull load X Write it to The TX array Do the same for why you made nothing controversial there So unless passing parameters through X bios doesn't do what I thought it did we can Do a little bit of verification here? so Let's deploy this and see what happens. So here we can see the three parameters X Y and state are in Are close to each other state is first followed by X and Y Which is exactly what we'd expect for three values on the stack So the boards crashed Here is the pointer to the calibration vector Which again looks reasonably fine So let's try taking out both traps and seeing if this still crashes It does indeed still crash So that's a completely ordinary program. That is as far as I can tell not doing anything particularly dodgy so So let's just start commenting stuff out until it works Luckily toss is reasonably robust for a non-memory protector system. So we don't need to reboot it every time Okay, so that worked. So is something wrong with this computation? What could possibly be wrong? It's just put it's just maths Well, let's start putting that back in So that's worked It does appear to be the case it doesn't like this computation So I think I want to compare this Carefully so C index is assigned long array. Here's a sign long array zero Tx Tx zero minus Tx two times T y1 T y2 minus Tx one Tx two Times to a zero T y2 sx zero sx two Yeah, I'm just going to skip past this bit because it's going to take me forever Here it looks okay to me So let's just try examining some of the code So there are the printfs and here is the first Line of the computation So these are longs It's it's calling an external function to do the multiplication Again all longs, which is stashed in a three It hasn't actually done the multiplication yet. That's T y one Subtract T y2 From T y1. Yeah, that's done this bit here Push let's do says the other subtract then it does the multiplication retract over the parameters do stuff with the result So maybe it just doesn't like the multiplication Maybe I'm using the wrong So there are several different calling conventions for the Atari ST Maybe my toolchain just doesn't work properly because it's not set up correctly But it is working on It is working on Aranim Which I should be able to demonstrate for you and here we have numbers They still look pretty wretched actually However given that This trap is producing garbage Let's just actually do Okay, you can see it's a It's writing the text and immediately clearing the screen sadly And I don't think doing it from the cons the console will help But I can just see small integers Yeah, you can see the last set here followed by the result I'm confused and I'm out of time So I am going to call it here and go and see if I can figure out if there's anything wrong with the toolchain The only thing I can think of is these multiplications Weird weird Anyway, I hope you enjoyed this video. Let me know what you think in the comments and hopefully we'll see what Happens next time