Well, good morning. It's great to be back after two years. I can't believe it's been two years, by the way. But I want to thank the Institute of International and European Affairs for giving me a chance to share my views on the challenges and on the dynamics of Turkish air relations and especially in the wake of the Irish presidency, which we are very hopeful about. Of course, Turkey and Ireland are at the opposite ends of our continent, but our people through history have learned to respect each other. At times, we have been on solidarity. At times, like in places like Gallipoli, we have proved to each other that we have been very brave fighters. But overall, this relationship is a relationship of mutual friendship, respect, and cooperation. National poet of Ireland, James Clarence Mangan, who's also known for his admiration for Turkey and Turkish people, wrote in one of his poems, La ilahe illallah, here we meet, we three at length, the Bosporus, the Bosporus. We felt full of health and heart upon the foamy Bosporus. Although he had never been to Bosporus, he could feel what it represents. Today, Bosporus is more meaningful than it ever was. And I'm grateful for the chance to share with you the greetings of the Bosporus, of the people of Bosporus, of my great constituency, Istanbul, with you today. Of course, as Bosporus is becoming more and more important, by the way, just heard that Russian Navy ships are passing through Bosporus to go down to Mediterranean right now to evacuate their citizens from Syria, which shows how important Bosporus still is. When you consider history, geography, and what's happening, Bosporus is still the most eastern part of the West and most western part of the East, so Mangan was right. There, you really feel that everything coming together. And Turkey today is the most southern part of the North and the most northern part of the South. And my city, Istanbul, is the most European city of Asia and the most Asian city of Europe. And I think that's the most important contribution to the challenges that Europe is facing today. Turkey, when asked, has the ability, the luxury, the great honor to check all of the above when it comes to being European, Asian, from the Balkan region, from the Black Sea region, a Mediterranean country, a Caspian region country. And that is what Europe was all about. It's coexisting in peace and harmony. At times, I even joke with my French colleague. As you know, the French are known to be most nervous about Turkey's membership to EU. And I would say, Pierre, what's your problem with us? You can digest to live with the Brits and not with us?  But we're hoping that the Irish presidency would bring the founding principles of the European Union back into action. The reason this union received a Nobel Peace Prize is not because of the way it has been dealing with the economic crisis. It's not because it has brought solutions to the global problems. But the reason this institution of the European Union received a Nobel Peace Prize is because it has ensured sustainable peace on this continent. It is, in fact, the greatest peace project of the history of mankind, because it has ensured sustainable peace on this continent. Although it's the greatest peace project of the history of mankind, it is still a continental project. When Turkey joins the EU, we will transform it to become a global project. It will be a global peace project rather than a continental peace project. Unfortunately, the process of Turkish e-relations are going slower than it should be. We have not opened any chapters during the last five presidencies. And to be honest, that has created a vacuum in the Turkish public opinion about what the EU stands for. Right now, we have opened 13 of the 33 chapters. There are 20 more chapters to be opened, but 17 of them are politically blocked. So we cannot open them, even though we have fulfilled most of their opening benchmarks. But the three chapters that we could open are the chapters that every country left to the very end in their negotiation process because of the economic hardships that bring to the candidate country's economy. Therefore, we are a testelmate. And we need Irish creativity to overcome this difficulty. Hopefully, we'll get it. Now, we are witnessing some changes in the French attitude with President Hollande taking over. We're grateful to the French voters for sending Sarkozy back to fishing.  And it should be because Turkey is in a country who's trying to become a member. And the process is called accession. But believe it or not, this is the first time that word has been used in any EU document for the last five years. Because that gentleman, who is now enjoying fishing, was blocking even the usage of that word. We're hoping that this new French attitude, which can be summarized as common sense, will be more evident. And the five chapters that were blocked by Mr. Sarkozy will no longer be blocked. Or the six chapters blocked by the Greek Cypriot administration, in addition to the eight chapters that have already been blocked because of Cyprus problem by the EU council, will no longer be blocked after their elections. So the Irish presidency would be really a historical turning point for Turkish EU relations. One way or another, this relationship will have to find a meaning or find itself a new route. Of course, the Turkish-Irish relationship is still full of untapped potential. There are great opportunities for us to cooperate in international organizations vis-a-vis our bilateral trade, economy, science, culture, technology, and tourism. And we were discussing with Ambassador Cengizer if the fact that there are no political problems between Turkey and Ireland. Is this something to celebrate, or should we try to find ways to use that as an opportunity to re-vibrate, re-energize this potential, this huge potential that is untapped? Of course, that would also have its effect on the Turkish-Irish relations. Yes, the EU is going to an economic hardship. But in a meeting organized by the World Economic Forum, I couldn't help myself and told my colleagues from other EU countries, come on, cheer up, guys. This is not that bad. I mean, I remember 15 years ago in my country we had 8,000% interest rates among banks overnight. Today, we are the fastest growing economy in Europe. Things can change. It takes fiscal discipline, it takes being resolute, it takes political will, and it takes public support. But if you can really bring that confidence and stability together, it really works. Just like we overcame this difficulty, Europe will overcome this difficulty as well. But despite all the problems, per capita prosperity is still the highest in Europe compared to the rest of the world. And when we say per capita prosperity, it's not only income. Per capita prosperity, as far as I understand, includes human rights, freedom of speech, food safety standards, hygiene standards, hopes for a future, the toys that kids play with, the baby food that is manufactured in a country, all that combined. We are still in the most civilized part of the world. And looking at so many challenges all around the globe, I don't think the challenges that are threatening Europe are that problematic. And we can really come over them with common sense. And common sense includes Turkey and Europe being much closer. Today, median age in Turkey is 29, whereas it is 44 in the European Union. So we do have a very dynamic young population. Our growth rate for the last five years has been on average of 8%. We are the fastest growing economy in Europe today, the third fastest growing economy in the world. According to OECD, Turkey will continue to be the fastest growing economy in Europe till at least 2020. By 2050, Turkey will be the second largest economy in Europe. But it's more than economy. What really runs the economy is industry and energy. 75% of energy resources that Europe needs today are either to the south, north, or east of Turkey. So unless someone creates, invents, a new technology of wireless transfer of energy resources, Europe is dependent on Turkey's cooperation in the energy game. However, in our EU negotiations, we still have not opened the chapter on energy only because the Greek separatists feel like blocking them. I don't understand what they have to gain with it. I don't understand how come the 26 others are looking the other way. That's one of the irresponsible blockages on this process that we hope to lift during the Irish presidency. For example, most of the criticism that Turkey gets today vis-à-vis human rights, detention periods, freedom of journalism, and so forth, are issues that need to be dealt with within the contents of chapters 23 and 24. According to a year-old EU council decision, those two chapters are prerequisite, meaning a country cannot open any other chapters in the negotiation process unless they can open those two chapters. However, when it comes to Turkey, a country that has already opened 13 chapters, we cannot open those two chapters because the Greek separatists are blocking them. They have voted to make those two chapters prerequisites for all other countries. But when it comes to Turkey, it's a double standard. And that's something that's really hard to understand. So the commission is constantly telling us, in all these documents that we read together, to do our homework. But what is missing is they don't tell us what our homework is.  And that's really a very complicated situation even I have a hard time understanding. However, we do understand that we have a responsibility. Being situated where we are, we are not only an economic solution because within three hours of flying from Istanbul, one can reach 1.5 billion consumers who are willing and able to use European products and services. We're not only a workforce solution with our young population. And I happen to be one of the youngest ministers in the Turkish government. But 70% of my nation is younger than I am. 60% of the population is under the age of 34. So that gives you a concept of how dynamic Turkey is. Energy-wise, we are very crucial. But the most important contribution of Turkey, as I said, would be turning this continental project into a global one. And I'll give you an example. You see, there are many Muslim leaders today who can go to Egypt or Syria or Tunisia or Libya and pray with the local people and show some solidarity. There are many Western leaders who can go to the very same countries and talk about merits of secular democracy, as many have tried, including Cameron and Sarkozy and so forth. However, there are not too many leaders who can do both. But when my prime minister, Recep Tayyip Erdogan, goes to Egypt two o'clock in the morning, more than 20,000 young Egyptians, go to the airport to greet him. And after attending a Friday prayer in Libya, he can come out of the mosque and speak to a crowd of more than 30,000 people. And he can, which he has, told them, don't be afraid of secular democracy.  I just prayed with you guys. But I'm running a secular democracy where we have the fastest growing economy in Europe. Being secular does not mean abandoning your own values or religion. Quite the contrary, being secular ensures one to practice his religion of choice as much as he wants to practice that religion. And that is a very strong message. That shows how important Turkey is, how important messages of the Bosporus that Mangan wrote about are. Because we blend the combined values of the East and West, North and South. And I think that's what's needed so much these days. And I'm hoping that the Irish presidency will help others understand this important need to deal with the challenges. Of course, this is not only one-sided benefit game. Yes, we have a lot to offer to Europe. But we are also gaining a lot from this process as well. My country is much more democratic today, prosperous today, more transparent, and has much more self-confidence than it did before starting the EU negotiation process. In a country where people were afraid to admit they were Kurds 15 years ago, now we have 24 hours of Kurdish broadcasting on state television. Inmates in prisons can talk to their visiting mothers in their mother tongue. Politicians can campaign in the language, in the ethnic language of their choice. After a gap of 88 years, the Orthodox citizens of Turkey have started using one of their historical monasteries called Sumela to practice their religion. The Armenian community has started using their historical Akhtamar church after a gap of 112 years. At the time when some European leaders were trying to deport their own citizens of Roma origin, Turkish government announced new housing and career projects for our own people of Roma origin. For the first time since the foundation of the republic, since the founder Atatürk himself, we have seen a president of the country who visited the place of worship of the Alawite community. These are important developments that would be very, very difficult for us to do on our own. So as far as I'm concerned, the EU is like a dietitian. It has a great prescription, which helps countries become more fit, more dynamic, more healthy. And when I try to explain to my people about the relationship that we have with this dietitian, I try to convince them that the fact that the dietitian is overweight these days has a few clogged arteries and happens to be quite moody doesn't make the prescription bad. The prescription is still the best around. And those EU member states who have been within the framework of their own prescription, which is the Aki, are doing fine. But those who cheated a little bit are now trying to put themselves in shape. And they will, because no crisis lasts forever. So this is the mood that we have in approaching the Irish presidency. We're hoping that our historical friends, a nation that has always been in solidarity with us in good times and bad times, will be on our side again. And I will be talking to my dear colleague, Miss Creighton, later today, about preparing both Europe and Turkey for this great rendezvous, the Irish presidency, which would hopefully be full of good news for the next six months. Thank you for listening to me. I look forward to your questions. Thank you.


Hey, this is Brett, and this 2021 Jeep Renegade Trailhawk is stock number 24T58B. I am here at Summit Automotive in Phonelac, Wisconsin, your new and used Jeep and Jeep Renegade headquarters. This 2021 Jeep Renegade has the 1.3-liter turbocharged four-cylinder engine, puts out 177 horsepower, 210-foot pounds of torque, and it is paired with the nine-speed automatic transmission. This one is a four-wheel drive, and it has been fully safety and inspected by our service shop, has a fresh oil and filter change, all the fluids have been checked and topped off, and it has four brand new tires, and this Jeep is 100% ready to go. A couple of neat things about this one, it does come with the tow package, and it comes with the leather seats and the nice touchscreen radio. I'm going to go all the way around in this video inside, underneath, start it up, take a look under the hood, show you all the options, and just give you the most accurate representation that I can of the vehicle. Granite Crystal Metallics of color, got the black roof there. I shoot all my videos in 4K. If you like the videos, subscribe to the YouTube channel, click the bell notifications, get updates on the videos I do each and every day, as well as having access to one of the largest catalogs of vehicle walk-arounds on YouTube and state current on our ever-changing and vast inventory here at Summit Automotive. This one comes with these 17-inch painted and polished aluminum wheels. They are in fantastic condition. It has Lofen G-Fit AS tires. These tires are brand new. They still have the knobs on them. We put those on in our safety inspection. The frame and underbody is extremely clean on this renegade. This is a one-owner clean title history, clean car facts from right here in Wisconsin. Front fender is in excellent shape, it has insinidense or dings on there. Headlight lenses are nice and clear, and you get the Jeep logo on there as well, and you get factory fog lights down there, and you get the red tow hooks with the trail hop package front bumpers in excellent condition. I didn't see any dents or dings in there, and you get these seven-slotted grille. Black hood decal. I didn't see any dents or dings on the hood, neither. Passengers side front fender is in excellent condition, and the passenger side front wheel no major scuffs or scrapes on there, very nice condition. As you go down this side of this 2021 Jeep renegade, take note of how clean the body is, how reflective and mirror-like that paint is. Take these HD videos so if you are far away or even if you're close by and you just cannot make the trip down, but you're still interested in purchasing the vehicle, you can see the vehicle, hear the vehicle, and have confidence in what you're looking at before you even get here. So when you do get here, there's absolutely no surprises, and you can make a smart and informed buying decision from wherever you're at. With this video helps you do that, let your salesmen know that you saw the video, it was helpful in that breadth-sending. Back wheel is in excellent shape as well, brand new tires back here too. And the underbody, from what you can see, is in excellent shape, absolutely no corrosion under there. Looks really good. This one does have the capitalist fuel fill, which is a really nice feature, never get gas on your hands again, and there is a little spider there. He says, chow baby. Very real imperfection I saw in the entire vehicle. There is one scratch on the side there, and that's really the only thing that I saw. Coming around to the back, the rear bumper is in nice shape. You get the towing package with the receiver hitch and four pin wiring. The rear gate is in excellent condition as well. It is a manual raised gate, as are all the renegades. Back storage area is very nice and clean. You get a factory spare tire back here, and jack tools. Those seats do fold down for extra storage. The other thing is, you get the sun shade here, which also keeps your valuables out of sight, out of mind.  So we have found big foot. It shuts nice and solidly. Coming around to the driver's side, just as clean as that passenger side. Didn't see any major dents or dings on this side, and for full disclosure, his back wheels just as nice as the rest. And the driver's side doors are in fantastic condition. You get the blind spot monitoring on here, built in directional signals, entering the go system. Just have to key fob in your pocket, put your hand in there, and it will automatically unlock. The back seats are in fantastic condition, no rips, no tears back here. It does have the latch child safety system for any child car seats you may have. You also get all weather formats back here, 115 volt, 150 watt plug-in USB as well. These seats, like I said, do fold down, and if the headrests are down, they go down pretty nice and flat.  Child safety locks on the back doors, and the inside and bottoms of the doors all look really good.  This is not pleather. This is real leather. No rips, no tears on those seats, power driver seat with lumbar, factory all-weather formats up here as well. Auto headlamps, power windows, locks, and mirrors. You can see these speakers are in the shape of carabiners. And we'll hop inside, check out the miles, radio, and everything that this Jeep has to offer on the interior. You can see this one has 26,681 miles, you can get the 7-inch LCD display, digital speedometer on there as well, and instrument cluster is very nice and clean. Comes with the heated leather wrap steering wheel. Blue controls on the right, Bluetooth and information center controls on the left. You do get audio controls on the back of the steering wheel as well. This one comes with the 8.4C radio, AM-FM, and Sirius XM radio capabilities, as well as Bluetooth, auxiliary, and USB hookups.  Sorry, I didn't mean to turn it off on you. Now you get your dual climate controls right there, and you can control it up there, or you can control it down there, which is pretty nice. And then you get all your different apps on here. This one does have projection manager, where you can project your cell phone to the screen via Android Auto or Apple CarPlay. We did a demo on Android Auto with an 8.4 if you want to check that out. Then this one does have the factory navigation system. There is Highway 41, so you can see that is working nicely. And then once again, just all the apps right here kind of went fast on that. Anyways, that's also where your backup camera shows up, and you can see that is working nicely as well. Like I said before, down here you have more tactile valentune and climate controls. You also have your lane departure warning. This is really what your trailhawk package is all about right here. You get the auto snow, sand, mud, and then the rock feature is part of the trailhawk package.  That's it turned out there. Turn those on. 9-speed automatic transmission, AUG is in a USB hookup, as well as a 12-volt PowerPoint. You get your start-stop capabilities. You can turn those off, electronic parking brake, and your stability control. There's your keyless entry with the remote start. And the passenger side floor mat and seat are in excellent condition as well. No rips, no tears. The headliner is in great shape as well. You get assistant SOS buttons and an auto dimming mirror, another little Jeep Easter egg right there. Let's start it up and take a look under the hood. Starts right up. No check engine lights or anything like that. I would personally like to thank you for checking out the video today, and hopefully from this HD video, you've been able to verify the quality, condition, options, and of course, cleanliness of this vehicle all the way around inside and out. All the lights are working very nicely. And once again, under the hood, we have the 1.3-liter turbocharged four-cylinder engine, engine base very clean. Runs very smooth, 177 horsepower, 210 foot-pounds of torque. And once again, this Jeep has been fully safety inspected as a fresh, early filter change on the foods. Check-in top-ups, 100% ready to go, there is the emissions sticker. And I would highly recommend this renegade from a quality and conditions standpoint. I think it's in fantastic shape. And to see more pictures of this Jeep or one of our other 550 new and used cars, trucks, SUVs, minivans, Wranglers, half-tons, quarter-tons, one-tons, renegades, compasses, grand Cherokee's, grand Cherokee L's, wagon-ears, grand wagon-ears. You name it, we got it. Go to the website right there, summitauto.com. Full pictures and descriptions of every single vehicle all at summitauto.com. And if you want to check out more HD videos, you can go to youtube.com. Summit Auto, click the bell notifications, get updates on the videos I do each and every day, as well as have access to one of the largest catalogs of vehicle walk-arounds on YouTube. And stay current on our ever-changing and vast inventory here at Summit Auto. In fact, in a second, you will see a link to subscribe to my YouTube channel on the upper left. A link to all the renegade videos I've ever done in the upper right. A link to this vehicle on our website on the lower left. And a link to one of our latest YouTube videos on the lower right. Click those. Check us out. We'll be with this Ultra Clean 2021 Jeep Renegade Trailhawk in Granite Crystal Mentale. Thank you so much for checking out the video. Remember to like, subscribe, and share on the YouTube channel. I really appreciate it. Thank you so much.


Do you get a sink in feeling that your friend doesn't even really like you that much? Do you wonder whether they love you at all or are you just a tool to them? Well, the truth hurts, but you have to face it. In this video, I will share with you 7 signs people are using you. 1. They don't contact you unless they want something. If your friend is using you, the most noticeable sign is that they don't contact you unless they particularly need something. It may not be obvious at first what they need, since they may be self-aware enough to conceal their intentions. For example, maybe your friend calls to hang out with you. They spend a few hours with you, and sometime during the encounter, they mention a problem that they have. Maybe their car broke down. Maybe they need to cut the grasses in the lawn, or maybe they are short on laundry money. An expert user won't ask you for anything up front. They will build some rapport and then mention the problem. Before you know it, you might be offering to give them a ride to work, to fell their tree with your chainsaw, or let them use your washer and dryer. Obviously, there is nothing wrong with doing favors for your friends. That's part of friendship. The problem begins when your friend wants something from you almost every time they see you. 2. They leave you in your darkest times. That something suddenly derail your life and you need some support? Sometimes it's not even about money or resources. On occasion, we may just need someone to talk to when our world is crashing down. When something tragic happens, does your friend show up for you? Or do you hear nothing but crickets chirping? Can you rely on your friend during your darkest time? Or do you have them around when things are great and blossoming?  That would drive anyone away. But if you are a reasonably positive person who is having an emergency, you should be able to expect a real friend to sympathize. Except there is a strong reason for their absence. If your friend doesn't show up to cheer you up in bad times, then they're probably using you. 3. You hang out on the specific conditions. Sometimes the fact that your friend is using you can be disguised by circumstances. For example, maybe you only ever meet each other when you're going out to your favorite night club. In this situation, if they were using you for your social status because you're popular and it makes them look good to be seen with you, it may be hard to tell.  In this case, they are only after you because of the little money you have. Switch things up a bit, see if your buddy will be willing to hang out alone, or do something totally different from what you usually do. Invite them over to your tiny low-life house or tell them to meet you up in a public place. Unless it's an activity that your friend hates, they should be happy to spend time with you but in your wretched home and in public if they actually like you. 4. They blackmail you if you don't do what they want. Good friends understand boundaries. They will not force you into doing what you don't want. Crappy friends who only want to use you for resources might be angry if you don't give in to their requests. Often, they may even try to manipulate you by guilt-tripping or saying things like, I thought you were my friend. When you tell them no, watch out for this controlling behavior. Real friends respect your free will and they will like you even if you have something besides your friendship to give. Someone who is using you does not care about the limits they might be crossing with their boundaries. As long as it is what makes them happy, they will use any means to get it from you. They play the victim and make you feel like you are using and oppressing them. Users are so quick to turn the tables and paint you bad to them. 5. They know and use all your buttons. The seatful friends start out as someone who was interested in getting to know you and will present themselves as being concerned with your overall well-being. They ask certain questions especially about your past. These individuals will listen to the silliest thing you want to say. Humans in general actually like to be listened to. We get naturally drawn to individuals who want to hear what we have to say and even more drawn when we spill gibberish and the person still pays attention to us. However, that is until the opportunity to get over a new appears. When this happens, don't be surprised when they use your insecurities or other sensitive information against you. Emotional manipulators have a good awareness of your emotions and will quickly use them against you. Real friends are aware of your weaknesses, but will in no condition use it against you. An old saying goes thus, love is giving someone the right to hurt you, but trusting that they will never do such. This is what it feels like to be friends with someone. But for users, they fire at you with the variable that you entrusted them with. They push all buttons. 6. They always want to be in charge Your friends' unwillingness to set aside their own point of view for a moment to see yours is a common pattern of behavior in someone who is looking to double-cross you. These people usually have a compulsive need to remain in their ways, even if a logical way of why things should be done differently is presented. Even if they are best at it, a good friend ought to step aside and allow you to grow as well. One of the reasons why users do not want you in charge is because they want to be the only ones recognized. As a matter of fact, even when you are the one who completed a task, a user can go as far as taking the accolades. Oftentimes, you will be punished for not complying with your friend's wishes. He or she may give you the silent treatment. 7. They will never compromise for your sake Ideally, friendship should be about give and take in everything, including the logistics of when you get together. Reciprocation and compromise are words that are closely related to friendship. The act of reciprocating your kind gestures and being able to allow things done your way at times means that someone wants to be your friend. They can do this in several different ways, but they respect your decisions and can see reasons to bind to them as well. You just have to make sure you're doing it right. A successful compromise will leave you and your friend feeling like your voice is heard and your opinion is valued. And while you may have to make some sacrifices, you can still reach an outcome that makes you happy. Wanting a friend to make compromises does not mean that you place high expectations on them. It just means that you, alongside your friend, have an open mind to reach and accept the best possible solution. Users will never accept your opinion. Even with the facts, they think they know better and will never let go of their opinions. Well, we can actually say that they know better. After all, they're the ones with ulterior motives for having you as a friend. So, they fear that any suggestion by you might just ruin their well- orchestrated plans. It hurts to realize that someone you considered close is using you and that they don't actually want to be a real friend. In situations like this, it's easy to look away from the truth at first, ignoring the signs no matter how visible they may be. But then again, until you face the situation, take a deep look at your friend's behavior and talk about it.


a nice new brother WP1 word processor. I could connect the Raspberry Pi up to the UART like so. Okay, that's interesting. You can see that I'm successfully interacting with the Raspberry Pi sort of, and I seem to have mostly made it work. There are some problems. Linux is really keen on sending and see escape sequences. I am actually going to take the time to write a whole new terminal emulator. I am going to cut this video short here because the next one is going to be long and is going to be me writing Z80 code on my desktop. Let's write a VT102 terminal emulator, or at least most of one. So what you're looking at here is a hacked up version of Pterm. I've taken away all the code that I previously had and replaced it with a simple test routine that just prints a 16 bit value to the console and some code that actually does it. Now we can compile this and then we can run it in the CPM emulator and that gives a nice way to actually test things to make sure it works. This is eventually going to turn into a standalone program for the brother that doesn't use CPM, but I also want to be able to reuse the VT102 state machine for CPM-ish. So we're going to start with this for now. So this routine just uses the CPM entry point for writing to the console. So there's nothing really of interest here. This is the code to turn a value into hex using the digital adjust instruction on the Z80. So what's our emulator actually going to look like? Well, we're actually going to try and do this properly, which means it's going to be a gigantic state machine. Each time a character arrives, it's going to process that one character and store its state ready for the next character. This is annoying to write, but is the best way of doing it. Now the CPM-ish TTY state machine, the user interface for it is pretty straightforward. We have a, where is it? Somewhere here, we have the instruction, the routine that actually does it. Here we go, TTY put C, which is the thing that actually does the work. Now, our state, we could just use a single byte for them, but I think it's going to be simpler to use the address of the handler routine. So we're going to do, I'll try to remember the syntax of the, here we go, it's DW, DW zero. This is going to be the routine of the handler. So this is just going to be, and that, so does that compile? It does, and this actually won't do anything yet. And I'm just going to take a quick look at the hex to make sure that it did what I expected. Yeah, I'm just making sure that dseg, meaning place what's here in the data segment, is actually doing the right thing rather than just emitting it inline. Actually, is it doing that correctly? So LDHL89AB call put hex 16, ret 00, it is not doing it correctly. Okay, yeah, that's actually probably because I have got this set to absolute mode rather than relocatable. That's fine, I'll fix that later. We want to define states, so we're going to use a macro to do that. And we have state macro to the macro syntax. I have some macros to steal here somewhere. Common, that's interesting. I have some macros for the hd64180 extended instructions. So did I put them in there? Yes, no, they're here. z180.lib, there it is. Okay, so this will define a new state. A state consists of a label and a routine to set to the current state. So that will be hopefully this, gel comma, hopefully that's not going to work. Okay, so that should be the core of our state machine. So let's define a state and it does not like that. What I'm trying to do here is glue together the macro parameter with this string in order to produce a constant label. I'm using ZMAC, which is a kinder old fashioned, but rather good, z80 assembler. So check the documentation. Macro call expands to text to the macro body. Parameter pkvk, fantastic, doesn't say. I'm going to go look this up. It's the dollar sign. According to the documentation, dollar signs are ignored and identifies everywhere. So that should do it. And to double check, let's just take a look at the listing. So our def state waiting here gets expanded to the correct code. So what this does, it allows us to do call set state waiting to change the current state. And when we call TTY put C, it just dispatches to the state handler, which in this case does nothing. So C for character. Okay. The other state start with waiting means that we actually have no pending state. The terminal is idle waiting for something to show up. This is going to be where the bulk of our code's going to be. This is going to take care of printing normal characters. Now, the first thing we're going to do is handle UTF-8 parsing. We are going to cheat. We are only going to support printing UTF-8 characters because trying to handle them inside escape sequences is a lot of work and pointless anyway, because they don't really make sense there. So what we need to do here is to check to see whether the top bit is set, which indicates it's a UTF-8 multibike character, or unset, which means it's simple ASCII. UTF-8 is a way of encoding Unicode. A Unicode code point can have up to, I believe, 31 bits, yeah. And UTF-8 encodes this with a fairly efficient variable length encoding. You can see the different number of bytes for different values here. It has the nice property that you can tell how many bytes a sequence will have just from the first byte of sequence. So we are going to, we are going to look up the Z80 instruction set because I always need help with this. We want to look at the top bit of the character, which is, of course, like this. If it is zero, then we know this is a normal ASCII character. Otherwise, it's UTF-8. And if it's UTF-8, we want to look at the top byte and then track how many bytes there are going to be for use in our state machine and initialize things like our UTF-8 accumulator. So we are also going to cheat. We are going to parse 32-bit UTF-8 code points, sorry, Unicode code points, where we're actually only gonna care about the bottom 16 bits because Astral Plane Unicode is rarely used and I don't think our terminal is going to care about them at all. So I don't want to do this the other way around. Yeah, let's do this the other way around. So we want to know how many bits there are in the, we want to know how many bytes there are in the sequence. So we want to test one of these prefixes. Or can we do that efficiently I think, let's stash a copy of the character in A and we want to rotate. It's a bit zero, rotate, right, shift, right. Is there a logical shift, right? Oh yes, of course there is this one. Shift, right, logical. Contents a bit zero, copy to the carry flag and zero is put into bit seven. So shift, right, logical A. We can then now compare A against this sequence in binary. I'm trying to remember whether Zmax supports binary constants. I think it doesn't. So we're gonna have to do this in hex. So that is going to be seven, E, okay. Then we shift it right again. This is of course three E. Shift, right, again, this is gonna be one E. Actually, we don't wanna do it like this. We want to invert all these. A label starting with a dot is local. It only has validity between normal labels. So it's really useful for labels that don't really need a formal name. Six, I believe. And there is no one zero. So if we get this, it means we've come across one of these where we didn't expect one, which is invalid. So to handle these, we are just going to just strip off the high bit and treat it as if it was ASCII, like so. Okay, so here we want to prepare for actually handling UTF-8. So the first thing we wanna do is reset our state machine. Well, reset the UTF-8 parser. So I'm trying to think of the quickest way to actually set this to zero. Actually, we only need to initialize UTF-8 chart because we're about to initialize this, which we do here. So we're gonna say that this is a six-byte sequence. So we set the remaining characters to five because we've already got the first character. And we want to initialize the UTF-8 chart with the bits of the character that are in the top byte, which is still safely in C. So to do that, we are going to do ANSI and stash this in A, in the low byte of UTF-8 chart. And then this gets copied here. I wonder, can we make this better? There's quite a lot of duplicated code here. Oh yeah, and I also forgot to put our RETs in. Yes, I think we can. So we're just going to set the, we're just gonna set A and B to be the values we're interested in. Four, three, two, and F, one zero, one F rather. And I also remembered that I need to do this to give us some syntax highlighting. Okay, so here we call pass UTF-8 leader, that sets the A and B. We have to change this. So let's just do that. So if A is zero, that means we are invalid. Otherwise, store the A to the number of pending UTF-8 bytes. B is our mask, so this gives us our value. Put that in L, set H to zero, write our 16-bit value as the character and jump to set state UTF-8 trailer. So this is our code path for if we got an invalid value. So we are going to mask off, we're going to turn it into a rather broken seven-bit ASCII value and jump to the routine that actually does that. All right, so we need a state for, you see this won't build, we need a state for UTF-8 trailer. When a character is processed, when we're in this state, we're actually reading one of these. So we need to shift the UTF-8 char left by six bytes and or in the value in C. Now I'm just trying to think of the best way to do this. Shifting left by six is of course the same as shifting left by eight and then right by two. But if we actually did it that way, then I think we would lose the top two bits. Yeah, these two bits would be shifted off the left into the third byte and then back two. So I think we're going to have to do it the crude way. So we want to load our UTF-8 char. Shift left by six and the easiest way to do that is to just add it to itself six times like so. We now want to or in C, which is our character into the low. So like so, write it back and now we want to get the address of the variable that's got our number of UTF bytes remaining in it. Decrement it and let me just find deck HL, not this one, this one and yes, Z flag is defined as effected as defined. So if it's not Z, just exit and we will stay in the same state that we were in before. Otherwise, we have finished, we have read a complete UTF-8 character. So we are going to jump to a routine to do it. So what are we going to do for this? Well, for the time being, we are just going to print it, print the value we got and then switch back to the waiting state. Okay, so we have some code and if you look at the listing, we can see that we have a reasonable amount of code. Here's our shift left by six. Add HL, HL is actually cheap. It's a single byte and a quite a fast byte too. Z80 code is annoyingly slow. That is 2929, add HL, HL. See, this is 11 clock cycles. That's way faster than trying to shift it piecemeal using the shift instructions, particularly as we would have to use some of the extended shift instructions. These, which are both, which are two bytes and like eight cycles per byte. Also the other add instructions here are two bytes and 15 cycles. Yes, and here, if we'll print ASCII, we are going to call put hex eight jrset state waiting. So put hex eight, yes, that prints the thing in A. Okay, so let us print this and see how that parses the emulator. We got a five five, that is exactly what we would expect to see.  We want, this isn't going to be a valid one, but it is at least going to be simple. We're going to do a two byte value. So that's going to be CO, meaning this prefix, but with all zeros for these Xs here, which is technically not allowed. And then we're going to do our five five in the second byte. Is that going to work? Yeah, that's a D five. So we run this, we get a D five, that's wrong. Yeah, that's because we forgot to mask off the top two bits here. So we're going to want to change this slightly. We're going to want to put, so that will mask the character with three F, which would give us the bottom six bits. Then we're going to or it in with the low value of the shifted, you see a shifted code point, and then put that back into L. One five, that is wrong. A is that wrong. So five five is 0101, 0101, which will not fit in our low byte. So this is just me with bad data. So the top one wants to be there, so we're going to have to put it there. So that should be like so. Five five, excellent. We should probably test the others that don't really fancy trying to put more test cases together. So, okay, let's try at least the three bit version. So that's going to be picking up a random value, which is E one, eight one, eight one. So we get one zero four one, which is 001, 001, 001, 001. So this is the six bit sequence from this byte. This is the six bit sequence from this byte, and these are the bits from here. And I can probably see one, three, seven O C ones. 0111, 00, 00, 1100, 001. So that gives us the six bit sequence from the last byte, which is n in a one. The six bit sequence from this byte, which ends in a three. And the sequence from this byte, which ends in a seven. Good, I think that works. So let me just do some, just divide things up a little. All right, this should give us the, we should now have a working state machine for UTF-8. How big is our program so far? 200 bytes. Wow, that's quite big. All right, so now we start with the more interesting stuff, which is the actual VT-102 state machine anyway. Luckily, this is documented reasonably well. We can look in the Linux console man page, which has a decent summary of the various instructions, the various control sequences. These are defined in various groups. So we have the simple instructions, which are one byte. We have instructions beginning with an esk, which are two bytes. These are fairly esoteric and mostly private, but the main ones are these. The CSI sequences. These are an escape followed by an open square bracket followed by some numeric parameters specified in decimal, followed by a byte indicating what it is that's actually happening. Annoyingly, you can have as many numeric parameters as you like, or at least I haven't been able to find any documented limit to the number of numeric parameters. The only instruction that seems to use more than two is M here, which sets character attributes. But yeah, here's an example of instruction that turns the LEDs on and off. We're just gonna ignore this one because we don't have any. Here are the parameters to the M command. These numbers all do particular things and you can turn multiple of these on and off at once. So we are going to need to define some states. So the first thing I think is to, here under print ascii, we want to test for the simple commands. So that's fairly straightforward. There's not a lot that can go wrong here. Ignore beep, I think. So do backspace, compare with, let me see, are these all in order? 10, no, they're not. Okay, 27, set, state, escape. If it's not any of these, then it's a printable character. In fact, so we compare with 32, which is space. Anything with a value less than this is not printable. So the way compare works is it subtracts. It will compute A minus 32. So if A is less than 32, then that will overflow and the carry will be set. If it is 32 or above, it will not overflow. So if the carry is set, then do nothing. So at this point, actually we're not, this is called from elsewhere, so we might not be in the waiting state. So at this point, we know it's a printable character, so we print it. So none of these are defined. So do backspace, do tab, do line feed, do return. In fact, ret is wrong here, because this is, we actually wanted to set state, waiting for all of them. Okay, so how are we going to handle these? Well, we have two variables to specify where the cursor is. Backspace just goes back one. So does LD set flags? I don't think it does. LD, we want the opposite of that. Here it is. Does not set flags. You know, I want to use a ret there, because it would make life cheaper. So let's just call set state waiting here, which will enforce that we are in the waiting state. This then allows us to do ret z there, ret there, and all of these can be a ret, which is one byte rather than potentially three for a long call. So this allows us to do this. So if the cursor X, if cursor X is zero, then just return and do nothing. Is there a easier way to do this? No, that won't work. So decrement it, wait, why am I do loading? Why am I doing that? Cursor X, come away. Update cursor is going to be a routine that will update the hardware when the cursor changes. And in fact, that can be a tab advances to the next tab stop. And traditionally tabs are on eight character boundaries. This one actually wants to know how big the screen is. So we're going to define some values. So to do this, so this will advance to the next eight character boundary. We now want to compare it against the last character. So again, this is going to do eight minus W. So if A is less than W, carry will be set. So do nothing if carry is clear. Otherwise, update, right. Oh, there's several of these. Okay, we're going to have to do more of them. 10, 11, 12. So each of these compares is two bytes. We can actually optimize this somewhat. It's a little annoying. So what we do is we would subtract eight from here. Z is set, but now we want to compare against nines. All we need to do is do deck A. And then we can keep going. Here we need to subtract another value. And I think in the interests of, let me see. So I believe that what you do here is subtract 27 by 13. And then here it would be 32 minus 27. Okay, TTY update cursor is going to be a stub for now. So we have to make that a long call because there's now too much code in between the definition of the label and the JR statement for a two-byte jump. Okay, so our code is now bigger. Here's our print ASCII routine. So you can see the one-byte comparisons. On the 8080 and children, these conditional returns are very convenient for dense code and tend to encourage refactoring into subroutines. Of course, calling a subroutine is always the full three bytes. Anyway, right, do line feed. This moves the cursor down unless we are on the last line. At which point the cursor does not move but the screen scrolls instead and the last line is blank. So get the Y value. Are we on the last line? If so, scroll. Otherwise, simply move the cursor down once. You know, I could have sworn that, hmm.  The actual implementation, the thing that actually draws onto video memory, this is just a state machine, has to know how to do this. So let me just look to see how the, this is my ADM3 state machine. Forms a new line and then a carriage return. Carriage return is, let's just do carriage return. This just sets the cursor X to zero. And let's just rename this to match the old code. New line is special. So let's add this. New line is a routine that will do a line feed and then a carriage return. Oh yes, it does also need to be a home, but we'll do that later. Okay, here is our cursor down. Scroll here, right. What scroll does is it temporarily stores the old Y position, sets it to zero and deletes that line. So that's as good a way to do it as any. So get the address of the cursor Y variable, load it, sets it to zero, deletes that line and puts it back again.  So let me see. In fact, we can combine a bunch of these line feeds together because there's three of them that prevents us from doing multiple comparisons, but I won't just yet. So the way that traditionally you do state machines is by ending each routine with a jump to the new state. But these are other conflicts from the fact that we want to use RETs where possible. So this is three bytes, which you kind of don't want to do. Anyway, let's just do, let's just do some debugging. So that prints an equals sign. This loads the cursor position into HL and that prints it. And that prints a D to delete line. So up here, we are actually going to do a new line. And let's see what happens when we run it. So the high byte is Y. So that has in fact moved from location zero to location from row zero to row one. Okay. Let's put us in row 23. That's the last row, 22. That's the second last row of the screen. So we've gone down one and if moved the cursor, that's what the equals means. We've gone down one again and it's scrolled. It's deleted the line at zero. There we go, D zero. So I think that worked. So what do we got here? Escape sequences. So we are actually going to do a whole set of more comparisons. Is it SD, in which case it is an ordinary line feed? So, and again, we know that we're going to end up, we're probably going to end up in state weightings. We're going to call that there. So a return here will consume the character we just got without doing anything. SK is new line. SK set tab stop at current column. Oh wow, I didn't realize that this thing had programmable tab stops. Let's just ignore that one for now. The terminal capabilities are way more than most programs use and we're going to need a custom term info file for this anyway so we can tell it not to do that. But, SKM reverse line feed. So I'm going to have to implement this one. So, this is essentially the, excuse me, let's do this the right way around. So, this is essentially the same code as for line feed, but in reverse. So we want to compare again zero if we're already on line zero, scroll down. Otherwise, decrement A and update the cursor. There's a lot of these, which we could probably abbreviate. One of these is three bytes. Okay, scroll down. Again, this is similar except we're going to use insert line rather than delete line. Push AF, save old Y. HL, zero, TTY, insert line, pop AF, cursor Y, HL. There is a ZMAC mode, which will automatically expand JRs to JPs on demand, which isn't documented, so don't worry about it for the time being, I'm just going to change all this stuff. Okay, so let's put ourselves on line one. We want a escape followed by a reverse line feed is an M. So what does this do? Right, it's moved us to line zero. Try it again, but on line zero. And we have inserted line zero. Good. That works. Okay, to deck private identification. This is used to, it causes the terminal to type back on the keyboard a sequence identifying it. So, how do we do this? This is in line, so we're going to do, so TTY type back HL is going to be the primitive that types back into the keyboard, whatever is pointed out by HL. So, to do this, we load the, we load the value, can we do that? Yes, we can do that. I want to compare it again, zero. Okay, so that's 27 by, that's a Z. Deck ID, what does this do? It did print the right thing. I'm not sure where that closed, closed square bracket came from, came from there. Okay, we have to use less to see what the emulator produced, because if I do this, then of course that escape sequence is interpreted by the, this terminal emulator here and it will be eaten. Okay, so man page, save and restore state. So, we don't, there's going to be more state coming. So, we don't know how much there is to save and restore. This is in fact not terribly difficult. So, let's just do, right now, open square bracket is a tricky one because this is going to start the, switch the state where we're reading the most complex commands. So, this is going to be set state CSI. CSI is what these things are called, command sequence introducer. We probably want to implement these just to make them go away because we won't implement them. Yes, let's do that. So, set state gobble one, means gobble one, bite and discard it. Set state one, okay. So, dev state gobble one, discard one, discard and go into waiting. Right, we haven't done that one. Once this is all over, it's worth shunting the code around to put things that call each other, frequently next to each other to reduce the overall code size. Okay, right, CSI. CSI is, oh, here we go. At most N part, 16 parameters. Wow, these are decimal numbers separated by semicolons. And the sequence of parameters may be perceived by a single question mark. This indicates that this is a special private sequence. Now, I believe, here's one here. I believe that the question mark doesn't actually do anything semantically. Or does it? Yes, it does. So, question mark 3H is not the same as no question mark 3H. Well, that's a pain. Okay, let's do some parameters. So, we have 16 slots for parameters. We have a single byte that counts the number. And we have a flags byte, which is where a question mark's going to live. There may be more we want to add later. When we enter CSI mode, you want to reset all these. So, we would really want to put this code in setStateCSI, but our macro makes it harder. So, we're actually going to do initStateCSI, which falls through into setStateCSI. And this is going to want to initialize all these values to zero. Now, we can do this relatively straightforwardly using LDIR, which is capable of resetting memory. See, transfers a byte of data from HL to DE. So, we're going to put this initStateCSI, start CSI state, end CSI state minus start CSI state minus one, like so. LDIR is basically memCopy. It copies from HL to DE. I always get this mixed up. From HL to DE, that's correct. So, we write a zero to where HL is. So, this means that LDIR will copy this zero to the one at DE. Then it will advance them both, so that HL is now pointing at the old DE and it will do it BC times. So, this will reset all our parameters to zero, which is a reasonably dense bit of code. Okay. We're now in the CSI state, where we actually have to parse this stuff. So, we're going to stay in this state until we receive a command byte. So, we want to see whether it's a, if it's a question mark, then set the question mark bit. If it's a digit, then we want to add it to the current parameter. To test to see if it's a digit, then we are going to exploit a feature of the ASCII character set, which is that all digits are in this range. Hmm. It's not quite as easy as this. Semicolon is actually special. So, let's just do that one first. So, to do this, we load the parameter count field. We compare it with the highest possible value it can have. Again, this is doing a minus value. Oh, no, we don't want, we just want to, yeah. If it's zero, that is, we are already on the last parameter. Don't do anything. This means that more than 16 parameters will just all overwrite the last one. That's as good as any count. Okay. So, detect a digit. Actually, at this point, we know that anything lower than a zero is invalid. So, just ignore that. I think if this happens, we just want to cancel and we just give up trying to process this escape sequence. Okay. So, we're now going to compare against nine plus one. That's going to have to be a P, I'm sure. Yes, it is. So, at this point, we know that the character has to be zero or up. So, by comparing against nine plus one, we know that if carry is set, this means it must be one of these. So, no carry continue. So, here we want to add this digit on to our current parameter. So, the first thing is we need to get the address of the specific parameter we are dealing with unless there's an easier way to do this. So, I think we want a current parameter value. Actually, no, no, let's not do that. What we are going to do is to add a helper routine, which is provided by the system called addahl. This adds the 8-bit zero extended value in A to the value in HL. This is a standard tool in the Z80 world. I also say Z80 addahl, which is this. So, having this ret nc here means that it's so much shorter to call out to a routine than it is to do it in line, even though there's only actual three instructions that do work. So, all this does is it adds A to the lower byte of HL, and if it carries increments H. If you actually had to do this in line, this would be a two byte jump. So, as it is, this is one, two, three, four, five bytes. Every time it's used, it's three bytes for the call. If you did it in line, it would have to be one, two, three, four, five bytes. Wait a minute, yes. So, you save two bytes by calling that each time you call it. So, what we're going to do is, in fact, param count is the wrong word. It wants to be current param, because the number of parameters is actually one plus that. This is pointing at the last parameter being written to. So, we fetch the current parameter. We shift it left by one by multiplying it by two. We get the address of the parameter block. We add the two together. This gives us the address of the current parameter in HL. And then, we want to load it in order to do work on it. So, now we have the value of the parameter in HL and its addresses in DE. Because we are adding on decimal digits, we need to multiply the current parameter by 10 and then add on the value, the digit we just received. So, to multiply by 10, we want to multiply by eight and add two. Hang on, let me do this again. So, x times 10 equals x times eight plus x times two. So, we have the parameter in HL, remember. So, we double it and stash a copy of the doubled value in BC. We double it again and again. And add on the parameter times two that we initially first thought of. The syntax is wrong like so. We now want to add on the digit which used to be saved in C until we trashed it here. So, our digit is in A. I'm sorry, our digit is in C. So, we put it into A. We subtract zero from it. This gives us the decimal value of the digit and we call add AHL. Now, we want to store it back again. Now, we've incremented HL here and that then got copied DE. So, DE is actually pointing to address plus one. That's fine. We swap things around so that the address is in HL and the parameter is in DE. Save the high byte, decrement HL again and save the low byte. And we're done. Okay, then the last byte, a combination of the last byte and the question mark flag tells it what it's actually going to do. So, the first thing we do is reset the state because we're not in state CSI anymore. Once we finish our processing, we're going to be in state waiting. So, we do this so we can do red. We then want to test the command flags bit to know whether we are private or not. If we're not there, if we're not private, then sorry, if it's not there, then it's private. Okay. So, I think at this point we want to do some testing. So, we want to print the parameters. Now, or at least print some of them. There's no point doing them all. Now, it would be, actually, you're now just going to simplify things slightly with a put C. A, D, C, C, 6, J, P, E, 5. Again, this is all debugging code. Now, we could do a loop here, but this is debugging code and that sounds like work. So, let's just do this. So, that just prints the first four parameters in hex. Okay. So, escape. Question mark. Open angle bracket. A1. A semicolon. A1. And then a 2. Or rather, A2. A semicolon. And a Q. Right. Now, what does this do when we run it? Because I forgot to call putparams. Right. Well, this is garbage. Lovely. Now, I have remembered to put brackets around this. So, it is loading the value at the parameter rather than the address of the parameter. Has it been reset correctly? Well, to do that, we call putparams here. Right. Those are all zeros. So, that means that this code is wrong. Well, we can call putparams here. So, we'll get the parameters after every byte. That 3.1 looks very much like the digit 1, to be honest. Okay. Well, we're going to have to figure out what's going on here. And to do this, we're going to use the debugger. So, the first thing we want to do is to figure out where CSI lives. State CSI. Here we are. Set state CSI is at address 1D0. So, we start up the emulator with debugger. We do trace 1. Actually, I don't want to put parameters there because that will produce lots of spammy tracing. So, trace on go. So, that has run the entire program tracing out the every instruction. Actually, let's put that through less. And that does not do... Okay. So, it needs to be... Yeah. It needs to be interactive. So, I'll do it with script. Script logs everything. So, run the debugger. Trace 1.go.exit. It's now generated a file called typescript containing the trace of what happened. So, here is where it called set state CSI. You can see here it is taking the address of CSI and stashing it in the variable. So, a bit further down. Here we go. 1D7 LDA A comma C. So, on entry, C is 3.1. That is our digit. So, compare with question mark. It's not a question mark. The jump is taken. Compare with semicolon. It's not a semicolon. The jump is taken. Compare with 3.0. That's a zero digit. JPC. The jump is not taken. Compare with 3A. The jump is not taken. Okay. We now think correctly that what we've got is a digit. We are here. Load the current parameter into A. It's a zero. Double it. Still a zero. Load the address of the parameters to HL. Add them. And HL doesn't change. 2F7. We load DE. The value we get is a zero, which is what we expect. HL has been incremented by one. Swap them. Wait a minute. Okay. Swap them. HL now contains the parameter value, which is a zero. Here's all our arithmetic. Here's what's wrong. Put our character into B, which is the high byte. Wait a minute. That should be an H. You can see here that the 3.1 is ending up in the upper byte of our parameter accumulator, which is all wrong. Okay. Let's try that. Okay. That seems not so correct, to be honest. It means it's different. Does the script take a single command? Nope. Okay. We're going to have to do this manually. Oh, wait a minute. Wait a minute. I did forget to put the minus D in. There we go. But this does seem to now spin forever. Right. It's jumping into nowhere. D7. Wait a minute. That's my program gone. That does not seem like valid code to me. Oh, I managed to overwrite it with the TypeScript. Okay. There we go. That's better. This one. Go. Okay. 1D7. Here is the top of our routine. So if we go down, we can see. So we're here. Push BC there. Push BC here. You can see it contains our digit. So we've multiplied HL by 10. Pop BC load A, C sub 30. This gives us 01, which is the right value. And now we add it to HL, which is here. And this is wrong. We are writing back our parameter in the wrong order. Okay. This looks like the right numbers. So we have written a 1 into the first parameter, which is this one. Then we write a 1, 2 into the second parameter. 12 is C in hex. So that's correct. The third parameter is empty and Q is then ignored. So now we just need to pause and execute the actual commands. So these are more complex than the other commands. So I'm just thinking how to do this. For most commands, the first parameter, Act as account. So that this command here seems to insert spaces. The number is the number of spaces to insert. This one moves the cursor up. Again, the number is the number of movements to make. But if the parameter is empty or zero, it moves once. So how are we going to do this? Like this, I believe. So copy our character into C, which should still be there. Compare with... So this will then load the parameter. We are then going to load the address of a routine to do it and call a routine that is actually going to repeatedly call this that many times. Hang on, we don't need to do that. We know that the parameter is always going to be in parameter zero. So do CSI, repeat it as zero. So we are going to make an unjustified assumption that there are going to be fewer than 256 motions, because that's the only real thing that makes sense. Or... No, actually, we're not going to do that. I mean, something like ICH does need to be repeated, but something like CUU here, like Move Cursor Up, would be done in a single pass. So this is going to want to be... Load the number of blank characters into B. Save that on the stack because it's probably going to be about to be corrupted. Call the routine to print it and print it that many times. So where does print ASCII get its value from? It's in C. We probably don't want to call print ASCII because it's going to go through this stuff. So let's just do... Let's add a routine here. Print Printable. So Move Up, Move Cursor Up. So the interesting thing about these cursor motions, which isn't actually mentioned here, is that if it hits the edge of the screen, it doesn't scroll. So load the current cursor position into A. Subtract by the parameter, ignoring the top byte. No carry means it worked. Otherwise, A becomes zero and then update the cursor. CUD is cursor down, so it's the same code but different. Okay, so this is value minus screen height. That's 23. So any value that is less carry will be set. Any value which is greater, which is equal to or greater carry will not be set. Okay, let's do some testing. Okay, so cursor down. Now this is not actually going to do anything. It's moved the cursor nowhere, so it's still at 00. That is because these both default to... That's the wrong piece of code. These both default to zero. Just thinking how to do this. Yeah, this code can be cleaned up a lot, actually. Okay, so we put the parameter into A. If it is zero, we increment it. But we now want to do a reverse subtract. Because we want to subtract the parameter. Does this thing support negate? I think we can do a negate with... There we go, neg. So what does this do? Right, we're now on line one, which is correct. So if we, say, put a nine in, we should end up on line nine. We are A1. We are now on line one. Excellent. So now let's move up by nine. We should end up... We should see a motion to line one and then back to line zero again. That's not right. So I don't think this has done what I wanted. However... However... We should just be able to check to see if the resulting value is negative. Or rather, minus. It's... Yeah, there isn't a JR for this. So it's always the two byte version. I wonder... Yes, I think the carry flag is inverted here. We'll do some careful testing. Okay, that looks good. Line one, line zero. Should still be line zero. Yep. Yeah, I think that works. So let's try and do 99 downs. That should put us in the last line. Yep, that worked. Good. So forwards and backwards are very similar. They just work in... ...wards... ...backwards. We're using the x-coordinate rather than the y-coordinate. So we just duplicate all of this. I mean, literally, we just duplicate it. That wants to be... So forwards... ...backwards... No, wait. These are the wrong way around. Curse the backwards... ...and curse forwards. Forward... ...backwards. For f should be line 79... ...column 79. What's next then? CNL, move down the number of rows and go to column 1. That should be relatively easy to do. All we're going to do is... ...like this. So we literally just set x to 1 and then do a down. Move up the number of rows does coup and G move cursor to indicated column in current row wait wait we are indexing by zero so that what this calls column one our code is column zero so CSI char move to indicated column in current row do CSI jar so if this is a zero no hang on hang on we wish to convert this to the same numbering scheme that we're using and so if they don't provide a parameter or provide a zero treat that as column one by this terminology so we test for zero if it's not zero we decrement a then we compare with the screen width if it is a minus 79 78 is a carry 79 is not a carry okay now I am not sure whether this is correct actually because if you're comparing if you're doing a minus 24 and a equals 24 then the carry won't be set but zero will be set after doing the comparison no that's fine because if we're at screen width minus one then carry is not set so it will think that it's out of bounds and it will execute this but it won't actually change the value so it's actually it's logically incorrect but won't make a difference but this is the better code so that was char G so this should put us into column 79 it has this should put us into column 79 it right yes that is correct this is what the terminals one base numbering system thinks is the right hand column so this 79 is one less than that and that is correct so this should give us a zero which it does this should also give us a zero which it does and should this which it does good right ED raised display these erasers chunks of the screen but which chunk depends on the parameter and the default is cursor to end of display that's a zero then so we actually going to want to load this if it's a zero if it's a one if it's a two in fact if it's anything other than a two let's just do this just erase everything and this our terminal won't have any scroll back in fact the video chip we're using supports all kinds of really cool things it's got 8k of video memory you can have multiple windows you can have multiple banks you can pan around you can do smooth scrolling by pixel by pixel which well vertically which is really cool it seems to have been designed for doing exactly this kind of thing but actually using it all is more work than I'm willing to do raise from start to cursor raise from cursor to end arrays all now thinking about how these are going to be implemented in the back end the current ADM 3a implementation as that the arrays primitives are clear to EOS which is effectively cursor to end clear to end of screen and clear to end of line clear to EOL and you can tell the ADM 3 state machine to emulate these by printing spaces if you try to clear the entire screen it will try to use it will home and do clear to EOS if you have clear to EOL and no clear to EOS then you get the emulated clear to EOS but it uses clear to EOL to clear each line which is way faster than trying to print lots of spaces but if you don't have clear to EOL it will emulate that as well that's with this code here for the time being I think I am what am I doing clear to EOL is important for text editors because it happens quite a lot when you're editing a single line of text I think let's just have a clear line and then implement these in terms of that so to clear the entire screen we are going to load XY into cursor X save it restore it again later okay so this will clear X clear Y and leave HL pointing at Y we now have our loop we load Y increment Y load it compare it with screen height if it's not that loop so this should erase the entire screen but leave the cursor position unchanged so that was a 2 so here it is clearing the screen one line at a time now these are going to be similar I think we want to help a routine actually so we're going to write a routine where you give it the range of lines to arrays and it will do it so D becomes the first line E is the last line E is actually at this point one plus the last line but we want it to be inclusive so let's just decrement E so that should be an increment of E so now this code becomes DE is going to be the high byte goes into D which is 0 the low byte goes into E which is screen height minus one and fall through does this do the same thing no it doesn't because we need to save DE as well there we go and we also want to know we are going to have E being the line after the one we want to erase that is it's exclusive because this allows us to do you can be compare E ret Z so if the if we ask it to erase a null range then it does nothing because that will make this easier so start to cursor well the cursors online cursor why of course so this will erase all the screen except for the line the cursor is on and likewise here this will erase all lines all lines after the cursor except the one the cursor is on so if you look at the man page erase from start to cursor so if we put the cursor online 5 say then we can see that it has erased 0 1 2 3 and 4 but not 5 which is what we want because let's look at look at those console codes again because the next one is the is a similar command for erasing the line so we've got from cursor to end of line start a line to cursor and erase whole line so this means that from do ed start to cursor we erase everything above the cursor and then call do ed do yell start to cursor which handles dealing with the current line and likewise here we do cursor to end do yell cursor to end so compare with K yell raise line so if it says 0 it's cursor to end of line it's 1 start of line to cursor otherwise erase the whole line I'll fix this later JP versus JR is a pain okay so so we're going to start with raise current line which is do yell all line that's all that's needed the TTY back end knows which line we're on and it will do the rest from cursor to end so save the cursor and restore it again now does this actually erase the cursor the erase where the cursor is itself I think not I think but I think I'm actually going to have to go look up more detailed documentation on these in a moment so are we on the first row if we are give up no no I got to do this differently so X goes into L so let's stack that stash that in E so we set the cursor to zero no we don't we want to put this in B for reasons push BC LD C to space actually we can do that here push BC call print printable this will advance the cursor on by one and loop DJNZ decrements B and jumps if not zero so what this will do is it will home the cursor at the beginning of the line and keep printing spaces until it reaches the cursor position and then stop cursor to end is going to be similar but different print printable is going to increment the cursor so once we reach the end of the line it will the cursor will be screen width and go on hang on is this right yeah B is our count no we can do it better than this you can do it better than this okay so we calculate how many spaces we need to print and then otherwise it's the same code right so let's put let's put us at five comma five and let's do a yellow it starts to cursor so what do we see so it raises line zero to four it then prints five lines of garbage print printable is supposed to print the thing in C but it doesn't let's try that there we go line zero to raises line zero to four and prints five spaces we don't get a cursor motion because we don't call update cursor which we don't want to do here because we haven't like actually moved the cursor but let's just put it in for debugging purposes there we go high byte is y low byte is x it's moves us to zero and then we should be at five afterwards okay that is what we would expect to see a raise to end of screen so it erases these lines and it should then print well 80 minus five characters so let's just put our cursor at 575 here we go five spaces good well that's worked how big is our program now hmm it's growing it's growing this stuff is the fake implementation this is our state data and everything above this is the actual state machine well apart from a little bit of test program at the top so my throat is getting dry and it's dinner time so I think I'm going to break it here I'm going to have to come back again with more because wow there's a lot of this how much more of there it more of it is there well just in terms of the state machine we have these I'm going delete the indicated number of characters this will require either a primitive or not actually implementing it I think I would prefer to go with not implementing it to be honest I'm going to have to look up to see exactly what these means easy easy easy easy easy tab stops let's ignore those not implement them modes we can ignore attributes we will need to implement but that's not actually too complicated status report yeah this is this is I think we have most of what we really care about the mode switches I don't think we need to implement there's a lot of the standard that I don't think I care about and of course once we've done with the state machine you then have to start working the actual implementation that will be fun so I'm going to call a break see you later


That's right everybody, Maya and I are reunited once again. And today we're gonna be talking about how Jeffree Star manipulates the drama channels. But if you're just here for the drama, if you're just here for the tea, you're in the wrong place, baby girl, because we are here to teach you about the inner workings of the human mind. And it might help you not get manipulated in the future. What is up everybody? This is Chris from the Rewired Soul where we talk about the problem, but focus on the solution. And if you're new to my channel, my channel's all about mental health. So yeah, I pull different topics from the YouTube community, but I'm not here to just gossip and spill tea and all that. I like to discuss what we can learn from these situations to improve our own mental and emotional wellbeing. And in this video, the specific topic is getting manipulated without even realizing it. All right, so if you're into that stuff, make sure you subscribe and ring that notification bell. And if you're not yet, follow me over on Instagram and Twitter at the Rewired Soul. And as you can see, all you loyal Rewired soldiers, I am back home in Las Vegas after being out of town for a week for the holidays. And thank you all for following me on social media.  All right, so yeah, what inspired this video is obviously there's a lot of stuff going on with people like Rich Luxe and Luscious and somebody just sent me Ashley Kyle's video and everything, but I made a promise to all of you and that promise was I will not turn on this camera and make a video unless I can provide you with some value. So as I was watching Ashley Kyle's video, she said this. I started receiving PR during the Jawbreaker Collection. That was my first PR package. So I always felt so respected by him and I'm just the kind of person where if you respect me, I'm gonna respect you back. And did that create some bias? Yes, it did. I guess it did, yeah, it did. And it shouldn't be that way at all. And that's not acceptable. And at the time, I don't even think I really realized I was doing it until everybody was calling me out for it, calling everybody out for it. I was like, damn, they're right. So again, although I'm using this as context for the situation, I want you guys to realize how this might be happening in your own life or in the world as a whole. All right, because some things I'll circle back to a little bit later after we jump into some of the psychology evolutionary psychology and stuff like that, we're gonna double back and talk about why drug companies send doctors such nice gifts. Why different industries like the tobacco industry or big pharma make such nice campaign contributions. You know what I mean? And also, I come from a background of sales and marketing and I'll discuss some of the other situations I've seen. But anyways, what I want to recommend to all of you, if you find this video interesting, check out this book called Moral Tribes. It's a long book. It was the longest book that I've read in a long time and I was like, oh, this is gonna be boring, but I just could not stop reading it. All right, so like you saw from that clip, something Ashley Kyle mentioned was, you know, she was just on Jeffree Star's PR list and she realized that she wasn't making certain videos about Jeffree Star, right? And this is something that all of us run into, okay?  This is in psychology classes as well as like philosophy classes, all right? So there's a bunch of different versions of the prisoner's dilemma. Like in that book, Moral Tribes, there's actually like a really long chapter on just all the different versions of the prisoner's dilemma. So let me just give you like the most basic version of it. All right? So two dudes go and rob a bank, right? They get caught by the police, okay? They put them both in different interrogation rooms. They go up to one of the dudes called John. They say, hey, John, all right? You're looking at 10 years, but if you rat out your boy Bob, you're only gonna get five years, right? And then they go over to Bob and they're like, yo, Bob, you're looking at 10 years, but if you rat out your boy John, you're only gonna get five years. So this is the prisoner's dilemma, right? Does John betray his partner in crime for a lesser sentence? But John also has to consider that Bob might be getting the same offer and he has to take into consideration what is Bob going to do, right? The prisoner's dilemma. And the best case scenario is that they both don't say squat, all right? So they've recreated this in a bunch of different ways, but eventually they took the prisoner's dilemma and they did it with computers, right? To see which situation was the best. And that's when they came up with the saying, tit for tat, all right? Tit for tat, we all know what that means, right? And that is do what other people are doing. You kind of mirror the other person's behavior. They've also done more experiments with people in a game with like money, right? And it was like pennies or whatever. They put a bunch of people in different places and it's like, how much are you contributing to the pod? And you can take some out too. And what they saw was people mimic other people's behavior. So the more you take the more I'm gonna take. The more you put in, I'm gonna put in, all right? So why do we do this? Why do we do this as human beings? Because of something called reciprocity, all right? So from an evolutionary standpoint, like we are designed to survive and pass along our genes, that's it. Those are our two main priorities. Live long enough to pass on your genes. So what evolutionary psychologists are looking at is like, so how did tribes form? Why did these form? And this is something talked about in moral tribes even more. So there's me versus you, right? Me versus you. But the thing is, we get a lot more done if we work together, okay? Then there becomes us versus them. And that's when you kind of see the tribal aspect, tribe against tribe. So me versus us or me versus you doesn't really work too well, but us versus them, that works a little bit better. And that's when you saw different empires throughout history and everything, whoever had the best cohesion. So that allowed them to survive, have more power and control, pass along those genes. So the reason why we do good things for other people is to promote cooperation, right? Because people back in the day, if they didn't cooperate, boop! They got booted out of the tribe, baby girl, all right? So what does this mean? What does this mean? So when you look at people like, all of the beauty influencers, right?  And you got James Charles and Jacqueline Hill. So let me make this very clear, all right? Especially for the people in the back. I am not assuming anybody's intentions, okay? I am not going to assume anybody's intentions, not Jeffree Star's, not Tati Westbrook's, not James Charles, none of that, okay? You can come to your own conclusion, okay? But what I'm getting at is, like at our most basic level, we are designed for reciprocity, all right? Somebody gives something to us, okay? We feel indebted to do something nice to them. That is how we are wired, okay? So these PR kits that are just sent out to drama channels, it begins this kind of unconscious bias. And as you saw with Ashley Kyle, she didn't even recognize it was happening.  Like how many people, like maybe it's a family member, maybe it's a friend, maybe you've stayed in a relationship so long because of that internal feeling of reciprocity, right? Like maybe your mom lets you live with her for a while, right? I'm using my own example real quick. Like my mom, when I first got sober, she let me live with her, like went free. You know what I mean? I feel indebted to her, okay? Maybe you're in a relationship, maybe a toxic relationship. And this is when some people know that. They know that about human nature and they hold it over your head, right? Maybe you've stayed in an abusive relationship too long because they paid the bills and they did this and they did that. They took care of this, blah, blah, blah.  Or even if they don't shove it in your face, maybe again on that kind of subconscious level, you feel indebted to them, okay? But going back to what I was talking about in the beginning, because I'm not gonna assume the intentions of anybody from Jeffree Star to Tati to James to Jaclyn Hill or anybody, but this is just how we're designed. Now, like the big pharma, for example, a lot of you know that I'm a recovering opioid addict, right? Like I have a big issue with big pharma and their campaign contributions, okay? Because they can't flat out say, Purdue Pharma, the place that's going bankrupt because they're paying billions of dollars for the opioid epidemic. They can't just go up to a senator and say, here's 500 grand, all right? Make sure that you don't let any bill pass that might regulate pharmaceuticals. They can't say that. We call that bribe. But you can make a campaign contribution, right? The NRA, you can make a campaign contribution. Big tobacco, make a campaign contribution because of reciprocity, okay? Like I said, next time you're in your primary care doctor's office, check around their office. See how many notepads or pens they have with names of medications on them. Like if you've been in a doctor's office for a while or if you've worked in a doctor's office, you've seen representatives come and give out swag and things like that. Like part of it is just a visual reminder, all right?  But sometimes it's reciprocity, right? Oh, this representative always brings me pens. And if you work in the office, you know how people be stealing pens, right?  Some people even bring food and bring donuts, they bring coffee, they bring all this stuff. So when I was working for the Addiction Treatment Center, we actually, we were nationwide and we had reps in every major city where, not only where we had treatment centers, but in other parts of the country because we had people coming in from all over the country, going to different facilities. We had facilities from California to Florida, right? But we had reps that would go around to the different hospitals, different therapists, anybody who might give us a referral, right? And these reps would go there, they'd give them swag, they'd buy them food, they'd buy them lunch. Why? Because the next time you get a drug addict in the emergency room, you'll remember to send them our way. You see what I mean? It's reciprocity, okay? So I thought this was the perfect time. I was watching Ashley Kyle's video. I was like, huh, this is a perfect time to discuss this. So again, I highly recommend, like if you want to learn more about this topic and moral tribes is more about morality, I just kind of dove into the prisoner's dilemma and cooperation and everything like that, but that book goes so much further. Starts talking about liberals and conservative views and where they stand on certain things because once you understand that, you start understanding different people's opinions on things and why they view things. Like, do you ever sit back at somebody and say, how could any logical person even think like that? Well, once you start learning about moral psychology and moral philosophy, all that stuff starts to click. You know what I mean?  But like just be mindful. I'll end with you on this, like way back in the day, I was one of the biggest Kanye West fans, all right? One of the biggest Kanye West fans. He had a book that came out. I forgot what it was called. It was this very small book. It was almost like Chicken Soup for the Souls. It was very small. He just had little quotes and everything like that, right? But one of the things that he said was, he never asked anybody to be on a track with him. And this is back in the day, so I don't know if he's changed his philosophy on this. This is like way back like college dropout times, right? But he doesn't ask people to be on a track with him, because then he'll feel like he owes them something, right?   But that's the thing, like something that I've tried to do pretty much since I got sober is become fully self-supporting. So that way I'm not indebted to anybody, right?  You know what I'm saying? So just keep that in mind. So I'm not saying don't take the free PR. Take that free PR, baby girl. But just keep in mind on a subconscious level, you might have that reciprocity going on. You know what I'm saying? I mean, anyways, glad to be back. Make sure you're following me over on Instagram and Twitter at The Reward Soul. And if you liked this video, please give it a thumbs up. If you're new, make sure you subscribe and ring that notification bell. And a big, big thank you to everybody who supports the channel over on Patreon. As well as everybody who supports the channel by buying my books over at TheRewardSoul.com and everybody who gets Reward Soul merch. And by the way, we got hoodies and pullovers and everything like that. So if you're chilly this winter, go check out The Reward Soul Shop. All right, thanks again for watching. I'll see you next time.