 So I was going to try and get the pen working this session as being the last major component But I think on the whole that getting the screen contrast fixed is higher priority If you can't see what's happening on the screen, there's no point even trying So as you can tell by this rather grainy thumbnail I have taken the back off the machine and hooked up the logic analyzer to the various LCD control pins I have managed to trace them to a chip on the LCD board that is underneath this But I haven't been able to figure out what chip it is yet and therefore what the data sheet is So until then I don't know the command set so rather than try to figure it out from Decompiling the Where did I put it here we go Decompiling the palm os rom what I'm going to try instead is Running the palm os rom and changing the contrast setting and seeing what happens with the Controller chip so we should be able to snoop on the conversation between palm os and the controller So this is hopefully what it's doing. It is running palm os right now If I peer under here It's not to be running palm os the preset button. Oh Yeah, for some reason it won't reset if the logic analyzers plugged in so let's try that Go and now we have the palm Logo on the screen so if I plug that in and hit the run button We see that nothing is happening because pretty obviously it's not talking to the device however If I find the contrast buttons Okay, sorry about that that turned out to be more complicated And I thought and I managed to avoid recording it for some reason So it turns out that if you plug the logic analyzer in and then I try to adjust the contrast Which I shall do The screen turns off however, I suspect what's happening is there a pull-up or pull-down resistors which are Less strong than the ones in the logic analyzer So the logic analyzer is disturbing the voltage signals and everything is going haywire Now we do however get a set of commands. This should be it changing the contrast and We see a pulse train You've got a start and stop control bits and our clock bits But what we don't see is Any variation in the signal like this is always the same so I wonder if This is because I have wired up one of the pins incorrectly Or it's just not being picked up So that's peculiar so I'm going to pause it and Take this thing back to the workbench and double-check the wiring. I think but of course If it's wired up correctly Then the logic analyzer is pulling these the data signal low which means that What to be honest high which means that nothing will show up here and Zeroes or logic ones or whatever are showing up on the Controller device and that's why the screen is being turned off So I can't actually analyze this Using this logic analyzer That's fabulous Yeah, whoopee Okay, so we can't control the screen but if I were to Hook up the analyzer again Throw the switch so that it boots into bootstrap mode and And then run my code We should be able to compare what we're getting to see whether I'm actually doing this properly Okay, so If I get ready to execute I hit the run button I press return we get a signal and what do we see so this is Pretty much the same pattern There's a month. I've got I'm sending two bytes next to each other with a very short delay that's possibly wrong We do see in the init code this is the init byte it should be sending Hex seven zero and this is the actual contrast byte We should be able to see this happening here However, there should be a pause between the two So if I go over to here Position of the windows So in display in it here. It's doing the thing Here it's writing out to the seven zero byte here we send the termination bit and Then there's a couple of delay traps. This one is for e2o Which is 20,000 20 milliseconds So that's worth doing However, I would still like to see the data bytes being produced I think I'm not going to get anything with the logic analyzer So I'm going to have to go offline and hook this up to my actual scope Which would hopefully do a better job of capturing the signals Unfortunately, I can't do that live. So I'll just have to take screenshots instead. So Be back then Well, I did manage to get a oscilloscope trace which you should be able to see on the screen now and this is exactly what I would expect from Parmos sending a seven zero hex byte All clock and data signals are exactly the way I expect the signals are Active high, etc. etc. So I Think I'm doing the right thing here However, while I was getting this capture the machine stopped booting into parmos. It just resets continually So I think some of its internal storage that does have a battery here is now corrupt so I'll just try executing with that delay in and see what comes out So luckily emutos still runs on it and it is indeed still the very dark screen So I Am very puzzled It's a shame. I didn't get a trace of parmos changing the Contrast itself you can see that the pins I sold it on having fact come off because everything is just far too small and Having to work on the thing while it's upside down isn't great for pressing keys the other thing I could do is to solder some actual wires on and route them out through the Quote debug port unquote. I Do also have a built-in command for adjusting the contrast it just sends a byte to this so Let's see if I can get the thing the right way up. Shall I? I'll try sending various bytes and nothing's happened So I I'm wondering if I I know I've double-checked this lots and lots of times But have I actually am I actually not sending the byte correctly? Well, now we know what a decent signal supposed to look like these off Gaps might be a bit short But this is their code and I am copying it almost exactly Anyway, so Set data to zero command to one wait so of the three bits we've got Four oh and pf data Which is the data We've got four oh and pk data which I believe to be the command bit this one No, sorry, that's the clock bit That's d2 in this trace This is command She's here command to zero clock to zero right we are here we now do the Data itself we set the bit Well, we set or clear the bit Then we Then we clock Shift right by one and go again. Okay. Now. What's this code doing pf data that is One oh one one that is Unsetting that's doing this that's doing this Then we do lots of this Then we undo that bit Then we undo that bit. Okay. That's is the same code. All right d1 becomes our Oh heaven's sake Okay, I know what's going on this and is backwards so This is I'm used to instruction sets where the destination is the first register but on this destination is the last register So what this is doing is adding the two together and instead of sticking the result in d1 where it will be ignored it puts it in d0 which is our data and It all goes pear shaped Okay Get rid of that It means we discard all bits, but the first that's why we can turn it on or off, but no more than that Okay, here it goes. In fact, I had made an additional mistake there In that just changing this to an and was with the destination d1 was in fact clobbering the bit number as well so I just changed this to be a B test and a bit index and a subq and a bg and it all works fine And we can change the contrast to our heart's content and appears to the hundred is a decent value and With luck, this is showing up on the screen in a reasonable fashion Who knows? Okay, so I'll just Check this in We do at least now know what the various I will just make sure that comment is up to date Clock is 40 pk data So pk 40 lc contrast clock This is Start stop bit This is data bit. Okay so I am Wondering whether to call this short now. Oh, yes, we this is our new Contrast code which got hacked into the CLI which we don't want to keep there and So I think we want to check in BIOS only so I think Well, we could get started in the pen but That is going to be a little bit complex turns out the pen is also connected to the second SPI device and Not only that but the battery controller is connected to the second SPI device and I found quite a lot of code Referring to SPI contour to in here They all use different ship selects and different settings so This is the scan this is the code that talks to the keyboard Can we get back to here? Kidra has a few UI bugs so this is the code that talks to the battery controller and I'm a little bit Confused by it because it does not appear to be setting the chip select before it sends the data instead it Well, I assume that this line here is Doing is adjusting the chip select and this happens after it triggers the The read-write transaction But this does definitely look like a chip select so you can see it turning it back off here by raising it Anyway, that is a value for PG data. Have I put that in? Yes, I have The pen Where'd I put it? Also, what's interesting is it all seems to be copies of the same code Don't think that's it. I did find the pen code This is the keyboard controller code The pen device is hooked up by its own Let me start that again the pen touch screen controller is can is also connected where SPI I did find the Chip and the date sheets, which is a big Improvement So it could be this I Don't know what BB get XY is but this is very similar code to the Keyboard controller. Let me just They come at 8249 not Okay So this is calling this code Yeah, this is almost identical to the Battery controller code. So in fact we can look at this and see FB of PG data is also That same bit Maybe this is not the Pen controller. What's this function called? Here we go pen get raw pen So I think this is the one we want See there is a awful lot of this So what's I wrong about? That thing being the battery Where's this called from so this is called from Talk to battery controller, which I thought was doing battery controller things This is being called from Hardware wake and prove filtered burr brown read This is doing. Yeah, this is called from lots of battery related things So you can see that this is clearing 101 one that is clearing the bit with value for that's bit to Here it is setting it. This is doing ascend and receive to the Device is also twiddling This thing in pin Port E See I thought this was the battery So get raw pen here is calling proof BB get XY which Twiddles port F and it calls this Yes, and this touches port G so I Think now I come to think of it That this is not to do with the battery or the pen this is Something else related to talking to the Hang on I put that in the Now that's port G Yeah, I think I mean I think I mean writing these things in the wrong place so I think this has got something to do with the the SPI interface to Both the pen and the battery Chips this is probably routed to both things which means that the pen chip select is most likely this So that's port F. So this could be pen chip select So now if I go to talk to battery battery so battery send receive is So let's call this battery and pen send receive You see this is called from there However, if you go finding it's definitely the battery Proof battery command alkaline detect read that calls this thing. It's called get raw pen Well, maybe the path. Maybe the battery code is talking to the touchscreen. I don't know why it would want to but What's this that is Yet another copy of lmol. What's this that's next to it? does generic stuff with the battery so hardware charger on just sets a clears a bit even and so that is 111 xbf 101 one that is bit six of J low charger enable turns the charger off Right this should be talking to the battery controller. I mean, I don't think there's any other way you can do it. What's this? this Doesn't have a name. Where does this come from? Is this actually a child subroutine of? Yes, it is. This is not a function. I put this in the wrong place. I should be able to Pressing delete I delete this. Yeah, there we go So down here. This should be the end of the function. I remember going through this previously It's gigantic is here. Okay, and it's not decompiling because a 0 a 5 9 Not you see this is calling a Generic function that's doing something to either the pen or the battery these system calls are annoying because gidra doesn't know how to turn them into Branches subroutine calls So it ruins the ability to generate decent code as far as gidra is concerned It just pushes some stuff onto the stack does a trap with no parameters and then pop stuff back off the stack again So it just tends to just kind of vanish in the Decompiled version Okay Hardware battery master read all of this So what port is it touching? Well, this pins seems interesting D is 1 1 0 1 so that's this one hardware charge off Yeah, that just sets that bit This is doing something with port D Looking at bits seven of port D See, this is not initialized as a GPIO So it's an interrupt line So I don't know what reading data here does I Understanding the battery charger is not actually the priority here what I want to do is to try and figure out which is the Chip select line for the battery So that I can identify what the chip select line is for the pen Then we should be able to just talk to the pen controller. So this It's just definitely talking to the pen Like this is not my name this name came from the Where did that name come from? Is that in the wrong place? Do I have two of these in me? Yes, I do So this is the one at 9a and this is the other one. So this is Not the one I want this is the pen code Right So what's this doing? It's IPR interrupt pending register this Why is this checking for a? pen Checking for an interrupt. So it's checking for this bit RTC Yeah, real-time clock Level four interrupt event from the real-time clock is pending. I why is the pen code touching that? exit if There is no real-time clock bit pending That makes no sense Well, this is not touching any bits any ports other than IPR that I can see so it's going straight into here. This is Setting what I think to be the pen chip select and then it's calling this that is Reading and writing the pen and this takes a Single parameter on the stack if I remember correctly Here you see it's pushing a word onto the stack. So this is turning interrupts off This is calling this to do the work Right. This is again a separate copy of the thing. I've already been through for the For the battery This looks like it's generated by a complete different compiler the code style is quite different We don't have the symbol names after each subroutine So what it's doing is it's putting The addresses of the SPI-2 device into a zero and a one so This is Byte star that's a register in a zero Byte star To and I believe it's inlined it in this code here is a bite star This is a bite star. No, it's not these are Word stars so here you can see it doing stuff to the pen We set up the SPI for a transaction we Clear this bit whatever it does We wait for the transaction to complete apparently twice. Oh Yes, there's a third parameter This one which is on the stack and this is Stack plus Word so it's always two bytes long So wait for bit seven waits for the transaction to complete Then it Right, that's not wait for bit seven. This is wait for bit seven and this is a word star this is a So what this is doing if this bit is Set rather if it's not set Send it out and wait for transaction to complete otherwise Do more complicated things. That's a delay Yeah that's complex and I don't really follow what's going on, but it's not called wait for bit seven this is Do pen thing so that do pen thing is calling wait for bit seven Read write pen is This is a maze of code But you can see that this is not doing any chip select stuff but this is Here So I think that the basics of it is This is the pen chip select Then it Uses the SPI interface to talk to the pen Then it Unders the SPI interface so I think that's basically all we need to talk to it now what we don't have is Any information about how this chip works. I mean we've got the datasheet, but it's Complicated to say the least so Actually getting anything out of it is going to be exciting So as far as I can tell You send it a command byte You send it a command byte and then you read back in number of bits saying Telling it which telling it the value of the channel you asked for and I assume that there are multiple channels per Four x and y I know it can run in more than one mode and I don't know how this is Hooked together Wow Okay So we've got read write pen here Which I believe takes a single parameter, which is probably the opcode to send to the Device So that's being pushed onto the stack therefore this parameter is Going to be at four Param one. Yeah, so let's call this opcode however, yes, this is the Extra parameter. I don't think this parameter is set up correctly Yeah, he is wrong. They should start at four This is This is due to a compiler having abstracted something out So wait for a do-pen thing here is Referring to values in its call as stack frame which is Not complicated at all so Okay, so if we tell this that there's a dummy value Let's go here. It's a D word It's a stack for so this is a Dummy value at eight nine a BC D e doesn't make any sense see D okay, there's these does need to be Another one so this is going to be at C size of two CD in the next one is a e so this code But that's not working at all Okay, anyway This value here. I believe to be the Yeah, what is that doing? That's a word at address at offset four And it is being referred to Okay, I can't actually tell what's happening there. I Think the thing to do is to try poking the Pen controller and see what happens now this is More fraught than you might think because of course we've got this code in the For doing the keyboard stuff Which is called ST send receive from an interrupt handler So we're going to have to make sure the interrupt to turned off around our Talking to the pen to the touch screen controller in order to make sure that the interrupt doesn't come along and Reprogram SPI to why we're working on it. So this is done by Reading SR and then putting the value back again and I'm sure that The BIOS has got code for doing this. Here we go. All right So that's word Set SR So this is going to send And receive a byte However, it's still set up to send it to the ST micro controller. So we think that our pen Chip select is on f1. So let's follow up the stack chain Do pen things called from read write pen. I'm going to want to come back here BB XY Here we Okay, so this is PFP Ewan Is the pull-up register or the pull-down register that is X FD 1101 that's pin to this one here It is clearing it so it disables the pull up resistor it then Raises the chip select line Soon is a chip select line Okay, and now we go into here the appropriate configuration for the pet the pen device is 2247 and we also want to Do this thing with PG Now let's take a look at that touchscreen controller See what things might be wired up to where's the pin out here, so Serial data Input chip select is low, but we've raised this whatever it is. Oh Wait a minute. This hasn't set the data. This has just set the Select line oring it turns it into a GPIO. What is that? bit nothing particularly interesting Wait a minute IRQ 5 That's a pen interrupt. That's what that is so what this is doing is By setting this to a GPIO because of course this thing we think of as the here is Here we stop it being an interrupt and therefore We know that no pen interrupts can be showing up this means that if the Pen controller tries to get our attention By Asserting pin 11 pen IRQ while we're talking to the The controller then bad things don't happen But we still don't have Chip select unless it's this This is the only thing I can think of for it to be okay, well Let's stash this in here Because we're not going to care about interrupts just yet so in our pen send receive Wait PE that's the Look at this one So I think that this is the one we particularly care about So B is 101 one and that's on port G so One oh one one pen and battery maybe therefore BG data and equals not pen chip select Should lower this pin chip select on the Touch screen controller and we can now send it commands right now the bottom bit the bottom nibble of the SPI con to is the number of bits to transfer minus one So clearly this is an 8-bit command and this is a 7-bit command So if we look at this our commands are all this says 8 bits wide and They always start with a set bit and the response we get back is 8 to 12 Bit depending on whether we're in high or low resolution mode So what is do pen thing being called with? Oh, yeah, what does this mean if command? 1 0 well that's this bit here But then this code is actually doing all kinds of weird stuff with the com with the command byte So it looks like if a 0 here is not set then we only send 7 bits. It's kind of weird Anyway, let's follow the stack chain up so that we're sending two commands which is 9 0 and D 8 and This is passing in two parameters. I think read write pen takes a Oh, no, no read write pen returns a 8-bit value Okay, so 9 0 is Set 0 0 0 0 0 0 1 No, it's not Set 0 0 1 0 0 0 D 8 is 1 1 0 1 1 0 0 0 the single-ended differential reference select bit Is the one that depends on the hardware and it looks like that's always 0 Okay, well, so that's the wrong code We do want to say data equals SPI data 2 So I believe We need to initialize these F3 1 and the other one was PFPU and 4 to a Okay, so that builds So I think that we may have enough here to actually get something out of the pen controller so let's just do this and Yeah, we do have the serial console enabled So I have no idea what we're going to get out of this, okay, so let's execute and Nothing don't think that's actually told it to start sending and receiving to be honest as it's hung here Read write pen Do pen thing 2 2 4 7 1 0 That's sys clock by 8 Not quite slow as it can go 2 1 0 so it's on but not exchanging for 0 1 0 0 So interrupt request enabled That I've been here before the SD code right that actually tells it to enable interrupts if 47 Well 7 is the bit count so 4 is 0 0 1 0 IRQ EN. I don't think that makes an awful lot of sense. I don't know why we would want be wanting to generate SPI interrupts at this point So that's actually not told it to do anything, but we have Written a value to the FIFO which is a zero Right, so then get to do pen thing and this is where we actually Tell it to do stuff So in this case, it's a 2 3 4 7 so 2 is the same data rate 3 is enable and exchange 4 is as here and 7 is the bit count So this will be 247 2347 Right, so my earlier worries about the The chipset line being inserted before a transfer happens are void because it was in fact not starting a transfer Okay, let's try this Okay, so run it We get a lot of the same bite Now I did go look for Linux drivers for doing this and there is one And it's huge Like really huge 1500 lines and it appears to use lots of stuff involving You know voltages and resistances so This could be tough But we are still not talking to the The chip so what we receive is a Here's to be a 1 0 Although now we come to think of it. I think I'm doing this wrong again. So we clock out our command But the response hasn't come in yet so So what's this doing 2 2 4 0? 2 2 is Enable no exchange for but the bit count of 0 is One bit and I need to change the type of this how you can't use volatile Yeah, right because it the de-compliation is missed bits Because it assumes if you write twice in succession to one of these pointers then nothing happens so and this is This is an incorrect de-compliation. I think so that this writes zero to the To SPI data It's right to zero to the transmit buffer Then this doesn't do anything But then we do this this as a send and receive of a single bit then we fiddle with this bit Which I thought was the battery and then we do a send and receive of 16 bits So I think what that's doing is trying to read all Possible bits of the response Of which there could be up to 12 and Then it says zero fills until you run out of clocks and then for the result SPI data to left shift by three bits Okay, so Let's change this code so pen send and receive we are sending a Bite and we are reading back a word so let's try That do we need to wait There's a wait here. It's an 8249. It is waiting a little The actual amount being waited appears to be coming from This structure here, whatever it is It's loading the value at this register into the register that used to contain SPI content to The Decomplation has alighted all of that because the value has been sent to a trap and It doesn't know how to decompile those so let's put a 1000 in Actually, it looks like it can happen more or less immediately. Ah We have to wait for the busy bit to reset, but I don't know what the busy bit is and it doesn't seem to be Any code here for doing stuff with the busy bit. I don't see any loops Okay, let's just try that. I'll try it like that then. Okay, and let's run it Zero great Also, that needs to be Four so either any data is in the top two bits or this isn't working so this code does seem to be Setting SPI content to a different value. So maybe we need to do that Also, that should be an F not a zero so two to four F So that was actually trying to read one bite. Oh one bit Okay, now what do we get? Well, it looks like a number. Oh That does indeed look like a number as my stylus Okay, down here in the corner. It's falling off the Yeah, that right down the bottom it falls off the the touch screen the number goes like that Now I expect there to be three channels For X Y and Z So let's do Well, nine zero is clearly Channel X so where do I put the touchscreen data sheets? so zero zero zero no that zero zero one is X Driver one so the next one we want is Well, well the other command this was setting was D8 Here so I'm going to guess that one is why but D8 is D is One one oh one one one one oh one. Yeah, okay. So that is the other The other channel this one I Think this touchscreen isn't is far is connected sideways to be honest. So let's just do 90 The eight is for eight bit mode. So let's just go for that's used 12 bits throughout And we will measure Z as well. So that's going to be F zero like so Okay, so let's see what this does write numbers so X is moving Why yep, you've got X and Y Z appears to not be connected to anything I still don't know how to how to detect Whether the pen is pressed or not other than through the interrupt. It's possible. That's all we need That is a pen interrupt shows up and we fetch the X and Y and do the conversion and post the result to the input system. So this is connected to Oh, I gave it an invalid channel so Z is actually 101. Oh, which is a And in fact, let's do the fourth one as well just which is one one one oh or E Okay, let's execute this Right numbers Right Z and Q are not doing anything. It would be nice if we could detect Pen up pen down from this Maybe we can So if the if the pen interrupt is configured to be a GPIO then we can actually see the value PF data is 42d 429 now even if this works There are still things to do which is to Convert the values we're getting into a nice X Y And send it to the Atari operating system and this seems to happen via I keyboard so what we're actually going to be doing is pushing a sequence of bytes to Keyboard Vec here Actually converting the touchscreen resistance voltage things into X Y is actually quite complicated involves calibrating the screen This is why a resistive touch screens always start up with you know touch these targets to calibrate the screen So we may need to write a program to do that We could use a Atari TOS development kit and actually produce a program which we run However I'd kind of like to bake it into the ROM so that you don't need to deploy more moving parts Hmm Anyway, let's execute this and see what we get right BB Presto That works nicely Right, we now have a successful interface to the touchscreen We do need to do all the front end of it But I need to go figure out how to do that so I Am going to leave it here The other thing we can do is hook it up to an interrupt line which looks reasonably straightforward for this It is IRQ 5 Yeah, you can see that X has got the lowest value down on the right-hand side of the screen and the highest value up on the left Well, why does appear to be roughly the right way around? I? Don't really like that dead zone of the At the bottom and I also don't know the appropriate way to map these because I bet it ain't linear Yes good Well, that was much less horrifying. I thought it was going to be We may be spamming random bytes the battery charger so that if we put a battery in it, it will explode now, of course this direction is Only 160 pixels so that we don't need 12-bit resolution Which is why the? the palm osc code was using a D8 here because that sets the touchscreen controller to 8-bit resolution which is faster So we might as well do that as well But I think we're going to leave that until next time that is a decent piece of work And I think it is actually almost done at least for the first stage We just now need to hook up some UI things awesome Okay, then I hope you enjoyed this video Please let me know what you think in the comments