 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. Okay, moment of truth time, try this and see what happens. And the answer is nothing. And as a result our application runs sort of. So that's interesting. Well it's not crashing. Do you think it worked? Of course it didn't work. But it did fail an interesting way. And what do you know? It works. Cool. And login. Yikes. That's a unicode character. That's what it is. So we need to fix. Delete cursor keys and utf8. Right, now the keyboard stuff should happen here under extended keys. No wait. First we're going to edit this. So these are all, we need to provide special keys for all these values. Special values for all these keys even. So just allocating things numerically, okay. And the delete key here needs to generate a 8. So under here we then need to test for our special keys. So that's going to be things like, so this is a, what was that? That should be an up. So this would be, we want to print, we want to type a string and our multi byte type routine is in here. Type back hl. I actually, I think we can simplify the code and make it a lot smaller. Let me just take a look at the VT102 documentation. Okay, transmitted characters. This shows all the characters that get transmitted as you might expect in octal. Yay. These are the special keys. So here we've got the cursor keys, backspace, delete, etc. And here is the sequences they emit. So all these keys, these are control keys, numeric keypad keys. We don't have a numeric keypad, luckily. Where is that it? Oh yeah, there aren't any function keys. I mean, there are keys that have functions, but there aren't any F keys. So I'm not going to find specifications there. I think I need console codes. It doesn't say. Really? Curse of motion, cursor position. You know, cursor keys send S O prefix rather than S left square bracket. Great. Doesn't say. Luckily, we have a better authority here because we can just type them and see what comes out. So pressing up produces escape left square bracket A. So that tells us that function keys generate quite complicated values. How about the nav cluster? Insert, home, page up, delete, and page down. Okay. What seems to be happening is function keys, that is F keys, and the nav cluster produce escape square bracket, then a decimal value followed by a tilde. The cursor keys produce a single letter. Okay, we can work with this. So here is our table. We generate it with this. So let's add another function. This is going to be a cursor key. Oh, one thing I do want to try. Let's try shift and up. Ah, lowercase. Yep. We can work with that. Shift and function key. Bigger numbers. Where do the numbers go up to? $24 sign. So F8, F9, F10. Right. Luckily, we don't have to worry about F11 and F12 because our terminal, our brother machine doesn't have that many function keys. I'm not sure now I think of it. Well, we can do. So my thought was that if we omitted the top, the key with the top bit set, then we can detect that and easily turn this back into the relevant string. So like if this is ABCD, then it must be this mode. But now we have so many function keys. I just wonder if we need special treatment for this. I'm trying to pack all the information that we need into seven bits so that it will fit in our key table. I think we can do it. So let's see. Left bit must be one. Then we can have two bits for the type of key that gives us five bits for the key number. This allows us to have up to four different types of key with encodings like this. However, we can be cleverer with the layout so we can do function and more function so that and then this is cursor and shifted cursor. That way we know that if bit six, this one is a zero, then the rest of this can be treated as a six bit constant. So for a cursor key, we want to set these two modes. So that is going to be top bit set to indicate that this is a special key followed by four zero to indicate that it's a normal cursor key. The shifted version is going to be all these three bits set to indicate that this is a shifted cursor key. Okay, I'm going to put that as C key. However, if it's an F key, then it's just OX80 and the key. The bottom bit shows up from the key number. Right, this gives us up to 63 function keys. But for the time being, we're just going to do C key. Okay, let me just try and get the order of these. So up is an A. I don't believe I can fit in A into five bits. Can I? I can go up to... No, I can't. So I'm going to have to be clever. So zero is the offset from A. C key zero is up. 1F is down. That's C key one. Left is D, which of course is going to be C key three. And that means that right is three, two rather. Okay. Right, function keys. These are like actual function keys. These are going to be sets 11, 12, 13, 14, 15. Hang on, we need to do shifted. It does need to be like that. So 11, 12, 13, 14, 15, 15, 17. So we're up to F6. F6 is 17. 18, 19, 20. Okay, and now the shifted versions. 1, 2, 3, 4, 5, 6, 7, 8, 9, 10. 23, 24, 25, 26, 28. Wouldn't 28 be there for F6? F6 is 17. Shift F6 is 29. That's weird. That is right. I was expecting the gap to be in the same place. 29, 31, 32, 33. Let me just double check that, I think. Starting from F1. 23, 24, 25, 26, 28, 29, 31, 32, 33. Hmm. Normal ones. 11, 12, 13, 14, 15, 17, 18, 19, 20. So this block down here is the row of keys on the left. We're using the top left one for escape because there isn't one. There isn't an escape key on the keyboard and it's kind of important. So let's just treat these as F10, 11, and 12, I think. So we have 10, 11, 12. Shifted, 10, 11, 12. So that will be 21, 23, 24. The shifted values are going to be 34 and 23 or with 2.0 and 24 or with 2.0. This is the top bit of the type code. This is this bit there. 1, 2, 4, 8, 2.0. Okay. This is the nav cluster but I have forgotten what order these appear in anyway. So in rows, we've got insert, home, page up, delete, and page down. I assume that I would have done this in that order. So these are also function keys. So we've got 2, 7, 5, 3, 8, 6. Shifted, not doing what I thought it would. Yeah, shift page up and page down are being eaten by RxVT. Shift insert is producing T because RxVT is inserting the thing off the clipboard. But I'm going to guess shift delete, shift end. I'm going to guess that they're producing the same values as the unshifted ones but with a dollar sign at the end. So okay. And so we go back to keyboard here. Now this point, we know that we're doing, we have some kind of extended key. So our key is in A, stash it in C because we are going to, no, that does not preserve C. Okay. Stash on the stack. We are now going to type an escape followed by an open square bracket. Now we need to decide what kind of key we've got. So if it's a cursor key, does the Z80 have a test instruction? It does not. Okay. So we want to mask off the top four bits, the top two bits rather. Yeah, we want to mask off the type. So that's 0x60 and with B. And I now want to, we're going to use a lookup table for this because there's only four entries. And we've got lots of code space. In fact, I wanted to use lookup tables for everything else as well. And I'll change that later. Shift right, logical. Isn't there a, I thought there was a single byte instruction. There's rotate, contents of bit seven copies of the carry flag, contents of bit seven, a copy to the carry flag and bit zero. Okay. Right. So what this has done is we've shunted our two type bits to here. So effect, we now have the type code, the value here, multiplied by two. Handle table. So handle function, more function cursor and shifted cursor. Although now I think of it. So we've got one, two, three, four, five, six, seven, eight, nine, 10, 11 bytes. If we were to just do this with a comparison chain, we would have two bytes for the comparison and two bytes for a JR jump to skip over the positive. So there are four options. Therefore, we only need three comparisons. So it's in fact cheaper not to do it like this. So okay. Although we probably will need a jump out of these things. But anyway, okay, cursor keys. We've done the 27 square bracket. So we now just need to pull the bottom few bits and type it. So shifted cursor keys, the same but with a low case a function keys, function keys, type a number. We want to call this. This is in the wrong routine, the wrong file. This is, actually we do want to call into that. So tty type a, tty type string, tty type, type D for decimal I think. And we're going to have to do something about these leading zeros. So type that out in decimal. We then want to type a tilde and exit. So again, more function keys is the same code except we're returning a dollar sign rather than a tilde. And let's get rid of our key table. Okay. There was something else I wanted to do. I can't remember what it was. Oh yeah, UTF-8. Now we did test UTF-8. So if the top bit is set, it's a UTF-8 sequence, which is this. So we do kind of know it works actually. So set UTF-8 trailer. We copy the number of bytes in here. Set UTF-8 trailer mode, which is here. I know what's going on. We are never switching out of UTF-8 mode. So this wants to go into set state waiting. Okay. Let's try this. Right. And we're still in the man page. Of course, we can reboot the terminals as often as we like. The Raspberry Pi keeps running. It's the thing that remembers where we are. Okay. So cat to dev null. It's exactly what we were doing on the PC. Up, UTF-down. And it's not right. Well, delete works, which is nice. Command D works, which is nice. Delete's not right here. Oh, is that trying to do a beep? That's not right. That's broken. I think that that is when it's trying to do beep. And I should probably fix that. Okay. Let's try that man page again. Ha, no hang. And here that Z should have double quotes around it. Curly quotes. No, it shouldn't. I don't know where that Z is coming from, but that's happening when printing a Unicode character. And we haven't done that bit, so I would expect that not to be right. Okay. Far at VI again. Left. No, no, no. Not working. Let's try a function key. They all produce A's. That does produce an escape, which is right. These ones. All A's. A's everywhere. Right. There's clearly something wrong. Which I figured out while I was moving the floppy disk over. And it's, huh, no, actually I didn't. I thought we were passing this the character in in the wrong register. I thought we were putting it in C. But no, that's right. Is our keyboard table looking correct? I think it is. Or is it? So this is scan code 01234. And it's producing a 95. What is scan code for? Here it is. Okay. That does, that is looking plausible. So I reckon the problem might be here. So compare against OX80 and against OX80. It's thinking that the high bit set keys are, wait a minute, is, yeah. This is a relic of my, the previous way I was thinking of doing code. So that was always jumping into the more function key setting. Skipping this bit, which is supposed to print the prologue. So it was always, right. And then this was failing because the value in A wasn't set up. Well, the value in A contained the actual key. And this was none of these were ever it. So it was always skipping down to here and adding A on to the value in B, which we hadn't set up yet. Okay, try that. Okay. So cat to dev null, cat to dev null, apparently dev full or others as it's otherwise known full is full. Who would have thought? Up. Looks good. They all look right. Function keys. 031, 031, 1. Well, those are the wrong values. Yeah. So how about this one down here at the bottom? We know should have a is a more function key when shift pressed. Yep, that did it. That was the return key, not the shift key. Yep. We're clearly getting the wrong number from somewhere. And so I'll need to fix that. I'll also take the opportunity to go and find a better decimal print routine. Actually, I don't think it's that hard. We want print.z80. So all we're doing is wait a minute. This decimal print routine will suppress zeros. Where's our, wait a minute, where's our, oh, yeah, because of course I've got print routines and I've got type routines. So BT102. Okay. Well, the print routines version both works in HL and has got some code to do it. So that's straightforward. We're just going to copy that. So it reset d to indicate that if the value is a zero, it might be, it could be suppressed. Here, if if we get this far, make sure that d is not zero because we don't want to suppress the last one. Right, the comparison. What earth does this code work? It's repeatedly subtracting the value from C. So, right, B is the value to print. Yeah, it loops around here, adding on this value each time round and counting with B. If an overflow happened, we exit the loop and then we put back the value we just took off. So, we actually want this to go into B, that's the going to be here. Did we get a zero? If we did get a zero then, how do we avoid suppressing, ah, there's some special code at the end for doing zeros. This is quite bad code. I think I may have written it. Yeah, so if you've got a zero, we go down here, we test the top bit of d to see whether it's negative. If we are suppressing zeros and it was a zero, immediately return. If we're not suppressing zeros, print is anyway. Okay, now we were also getting, no, we fixed that bug. Right, let's try this. All right, so we're still in our cat there for null. So, let's try the function keys. 4D, those numbers don't look right. I think our routine is borked. And they are still all the same. I thought we fixed that one. No, we didn't fix that one. It's 1030, I'm getting pretty tired. Function keys, cursor keys still work. And we still need to fix these values being wrong. Yeah, we've put ld instead of and. No, we haven't. We've forgotten to and in the key itself, which is in b, because we want to pull out the actual number from the key code. Let me take another look at that at this thing here. We can shorten this code slightly by using e instead of c, because we then get to combine both constants. Okay, anyway, let's try this. So, what's going to do? All right, function keys. 4D, that all seems very wrong. For start, that's not decimal and the terminals hung. It's 1030 and I'm actually getting pretty tired. Must be in shifted cursor key. Pull key number. Hang on, these ones we want. So, it was more function key that made it hang. Let's actually do some splitting this up, I think. Let's put some white space in for readability. So, pull the key number, type it out in decimal, type a tilde and stop. Pull the key number, type it out in decimal, type a dollar sign and stop. So, I think something's wrong here. The value we're typing is in a, which is correct. So, we do our loop, b contains our loop counter. Well, b contains the character to type. Put it into a. Is it a zero? If so, follow this code. Otherwise, don't suppress zeros anymore and print it. And the ret takes us back up here to do the next digit. I think that should work. But I know what the problem is. A is being used to hold the value being printed. So, we do this, we overwrite it. So, that's annoying. Because we have to save it somewhere and put it back again after all of this. But because we've got two returns here and here and the branch happens after saving, then it's not always, the code flow is tricky. So, I think we want to do, I think this is the cleanest. It would be possible to get rid of this pop and this push and put an additional pop in here. Nah, be too hard. Because we would have to do the pop between deciding to do the return and returning. And as we are exploiting a single instruction here, I think that should fix it. So, DevNull function keys. 01. Well, the numbers are all the same. At least they're numbers. And they're also wrong numbers. That's producing, wait a minute. This is not consistent with the numbers. I think it's occasionally, yeah, look, you see, sometimes it produces an 01. Sometimes it produces a, yeah, there. So, it's missing characters somehow. Oh, and now it hangs. Well, it's improving. And of course, we are storing our zero flag state in D. And our keyboard type here is going to corrupt it. All right, function keys. 11, 12, 13, and it wedges. And we're still getting the leading zeros. You can really tell I'm getting tired. Pop AF doesn't just pop A, it pops the flags as well. Which is why this value from the comparison is always being ignored. So, lose that. So, we are actually going to jump into here with the value pushed onto the stack. So, this then has to be jump back to here if not zero to allow us to restore stack and red. So, we press the function key and we get a value. 18, 19, 20. Now we shift them. 33, yep. Yes, and these ones. Yeah, so we even get the ones with the dollar signs at the bottom and now cluster and shift those. Yep. And these ones shift those. Yep. And we haven't had a hang. Interesting. The keyboard is handling auto repeat for us. And it appears that the function keys don't auto repeat. What's about these ones? Page up. Page down. Page down auto repeats. Page up does not. I actually think that from looking at the layout, this is supposed to be page up. Yeah, and that does auto repeat. The first cursor keys auto repeat. Yes, this is very much a bespoke keyboard for a word processor. Okay. Well, let's fire up nano. Yeah, that's not right. But the cursor key should work now. Except that. Yeah, control L now redraws the screen. Except that something is not right with the, yeah, those eight interesting. I think those are supposed to be attribute changes. There's something's wrong there. Did I just write a file? Save modified buffer? No. But it does actually seem to be working more or less. Well, the cursor keys don't seem to want to work in vi. And we still get control G there. But this is loads of progress. It is better than our old vt 52. Certainly less snow. I'm going to have to do something about that. I have a few potential plans. It depends exactly what's causing them. I have a worst case and the best case. But it's late. I'm tired and I have like a billion short snippets of video to edit together. So I'm going to call it here for this session. We're going to start work again on this next time. Things remaining to do are snow, fix the state machine issues, character attributes, and see if we can bump the board rate up. So until next time.