 Just a brief background, what before this presentation is that I actually took part in the internal company hackathon at SP Digital with my colleague Soap. So we built and add a slack client to be precise on a very old platform. So as you know it's Windows 3.1 which it became quite popular on Hacker News. It was number one on Hacker News for a few hours. In the end it got 700 plus points. So I think quite a lot of you found it interesting. I thought it was quite a boring thing but no. So what is Windows 3.1? So I'm really sure Windows 3.1 is older than many of you here. So it is actually a series of 16 bit operating system for Microsoft first release in 1992. But the version that I'm going to show today is variant called Windows for Work Groups. We were released in 1993. So what's so special about this OS? Because this is the first one by Microsoft to have network abilities. I mean let's sing it for a moment. This is the first Windows OS to have network abilities. Like official network abilities. I mean before that people hack things but this is the official one. Okay so I know I asked some of you all to sign up right? Retro Slack but not many of you did. Just go to the Win3.1 channel. Let me switch over to my very ancient laptop. Okay. Wow, a lot of you never see this before right? Okay let me sit down here. Okay. So as you can see right, this is a Windows 3.1 PC. You can take a look here. I'm not faking things. This is not a VM obviously. This is a real PC. Okay so let's go to the Win3.1 channel. Those who ever have already signed up for the Retro Slack workspace. I think only a handful did. Something about 7 or 8 of you. So I know Michael did at least. So Michael can you please post some messages there. To prove that this client works. Win3.1. Just send something there. And try to keep the message short and no pictures. Can you do emojis? Okay can you do emojis work? Okay so Michael just send a message. So now let me reply. Hi Mike. Okay from Win3.1. Okay so I'll just click send. Okay so I think Michael should get that. Ya you got that right. I don't know who else is actually on this Retro Slack. Not, who else? Actually not much right? Actually I posted just now few 1 hour nobody use. Okay. And if Michael send some more stuff. Send emoji. Okay send. Okay this wasn't called jasmine send something. Yes. Okay so yes I got some evidence that this app works. Okay. Ya so let me go back. Okay so the top question I got from people is how does one develop an app like that right? Okay so this is a very complicated diagram. Let me go into detail first. I actually develop the app on my modern Mac. Okay so this one here. And it's running Windows 2000 VM. Okay. Inside it's running a compiler called Visual C++ 1.52. That was the version of Visual C++ release in 1993. Then there's a Samba Shared folder. So far it can be communicated between them. Then the binary right it's actually transported over the network to my actual Windows 3.1 PC. So occasionally it can be tested that way. So let me go into detail. Okay so why this version of Visual C++ right? It is the last compiler for Windows 3.1. Okay so it's a 16-bit compiler. The significance of that is that a 16-bit program can only be officially run on up to a 32-bit version of Windows. You cannot run it on a 64-bit Windows. Although theoretically there are Windows there is a Windows 10 32-bit. But I don't have that. So I use Windows 2000. So why Windows 2000? Because Windows 2000 is the oldest OS that is supported by VirtualBox with full drivers. That means you can copy-paste stuff inside. You can do network share. It's oldest you can go back already. Then Windows 2000 can also communicate with both Mac, Windows 10 and Windows 3.1 over Samba Shared. Windows 3.1 cannot share files with Windows 10 and Mac because the version of Samba it uses is so old. That the modern OS cannot communicate with it. But Windows 2000 is a very good bridge pretty much for them. So now how do I connect this old PC to the internet? So this PC does not have Wi-Fi. I mean, ya. So it doesn't even have ethernet. So I use a Paraport Network Adapter. Y'all may not have seen this. What is this thing? This is the days before USB. And this normally use by printer but it can also be used as a Paraport as a network adapter if you got this one. So let's talk about coding stuff. In modern times today whenever we want to look for resources the first thing we do is Google or we go to Stack Overflow or we go to API documentation or we also can use online code simulators. However, what happens if you don't have any of this? And this was the situation I face. I don't have any of this when it comes to coding Windows 3.1 because Windows 3.1 is older than Google Stack Overflow. Okay? So I did things the old fashioned way. I use a book. This one. This book for real. I actually bought this book. So this book was published in 1992 and someone commented if you're going to program for Windows 3.1 buy this book, you pay for yourself in the metal hours. And I agree with that. So let me pass around this book and it has some sample code and it's given in a good old floppy drive. Floppy disk. So yeah. Just flip-flip. Yeah. That save icon is real. It's not 3D printed. Okay? Okay. So the language that I use is C. We think that C language is still used today in fact. Although not very much. But it is an old version of C. Okay. So it uses a version of C called C89. Okay. So C has undergone many revisions since then like C99, C11, C18. But the compiler was released in 1993. And obviously, the compiler can only support language that's older than itself. Right? So the language older than itself is C89. Okay? So let me go through some of the weird stuff this old version of C has. So the first thing is that you cannot declare new variables in the middle of a scope. Okay. So what this mean is that let's say if you have a function the variables that you want to use in a function have to be all declared at the top. You cannot have a variable declaration as in in the middle. So that's why you see this, for example, this stock of the function. Why so many things here? Because it's all the functions that are used. All the variables that are used. Right? Okay. So they may be pros and cons. You shouldn't see it as a disadvantage. Because some people say that it may actually increase code readability. Because it forces you to put all the variables at the top. Whoever uses this reads this function will know it being used in a function. Okay. The next one is unsaved functions. So there's one particular function called sprintf. So you all may heard of printf. So sprintf basically is a printf but printing to an array. Okay. So for in modern times, right, we are highly encouraged to use sprintf. So sprintf means that you can specify the number of bytes you want to write to a buffer. If you do not write there's a risk of buffer overflow. Because if let's say the formatter string is greater than the size of the buffer, sprintf will overwrite and continue to write on. So you will have problems. The problem is sprintf came out in C99. So I'm forced to use sprintf, the older function and have to be careful not to cause a buffer overflow. Then another one is system computing. So let me first code this on Wikipedia. In the context of an IBM PC compatible and a wind-tail platform, a 16-bit application is any software written for MS-DOS, OS2 or early versions of Microsoft Windows such as Windows 3.1 which originally ran on a 16-bit Intel 88 or 286. So programs containing more than 2 to power 1664K of instructions and data therefore requires special instructions to switch between the 64 kilobyte segments increasing the complexity of programming 16-bit applications. Right. So the key part is here as if it's not hard enough for Wikipedia still need to purposely say it's very difficult. Okay. So why? So let me go in a bit of detail. In modern times, right, this is a more memory that we have for app. A default stack size for a modern program is 8 megabytes. Right. You can increase that but this is the default. The heap size is the how much memory can address which on 32-bit platform I don't want to put the number there. It's very, very huge. Okay. So pointer size 32-bit and 64-bit respectively. So what about 16-bit platform? The stack size of a 16-bit app is only 4 kilobyte. It's 1,000 times like 3 orders of additive less. The heap is divided into 2. It's something called local heap up to 64 kilobyte and something called global heap. 64 kilobyte segments up to 16 megabytes. This means that you can address memory in 64 kilobyte segments and your total amount of memory that your single process can use is 16 megabytes only. 16 megabytes. Nowadays, our app use how much. We don't know. We don't care. And the pointers, right? Nowadays, we think of it as 32-bit or 64-bit pointers. There's something called near and far pointer. Like, still got this kind of thing. Okay. So the difference is that for near pointer, right, is your default size because 16-bit platform means 16-bit pointer when you do a mallock to allocate memory, you get a 16-bit pointer. This part is obvious. The thing is at that time, people already realize that even 64 kilobyte is very little, right? So they want to use more memory. The problem is the pointer size is only 16-bit, right? So to address more memory than that, they use something called far. So you have to address memory very far for you. So they have something called a 16-bit selector. And I will try not go into detail but this is what it means. If you Google about it, right, you will find out that Winner Trip 1's far pointer is based on something called a 286 protected model. Okay. So what this means is that the 16-bit selector is mapped to a 24-bit address. Okay. So to the power 24, you get this 16 megabyte limit. Okay. Ya. So very difficult to access. So how do you allocate memory from this? Because obviously 64 kilobyte is not enough for my app. Memori far away, right? So the answer, actually, it cannot be Googled. It has to be located in the book. Okay. So I'll briefly explain what is all this thing, right? To normally allocate something you just mallock, then when you're done, you're free, right? But to allocate something from a global heap, it's very complicated. You need to specify the size, call these bunch of functions. Then after that, right, you need to ask this about doesn't mean you get this amount. Okay. Then after you're done, remember to free the memory. Right. Well, without the book, I wouldn't have known how to do it. Okay. So network stuff, right? Okay. So making a network crash is very, I would say, complicated. Nowadays, for example, if you use Go, let you just do a post or something, right? You just call to use the HTTP package. Just one line, right? You can do already. This one cannot do one line. So, at the top, right? Uh, you probably recognize what it is. This is a post request structure, right? So, modern languages, you seldom people construct a post request by hand like that. You call the functions and populate with your haters and all the required stuff. This one, I need to manually define. Okay. After that, define a socket with TCP, set the IP address, set all the stuff. Okay. Set the message. Then, then close the socket. Now, everything is done for you automatically. But, this wasn't the case. This post request, this windsock thing, it still exist today. So, every programming language below, under the hood, they probably still do something like that. But, it's all affected away from you. Another thing is no HTTPS. So, this was a very huge challenge for me. So, I decided to cheat. Eh, put a proxy in between. So, this proxy is not something that was off the shelf. I actually had to write a Go program to do it. So, what this Go program does is that, it will actually receive the HTTP request from the Windows 3.1 app. Then you forward it as HTTPS to the Slack server. Then whatever reply that comes back, it will just be relayed back to the app. It's just a transparent middleman. No manipulation at all. Okay. So, why? Because it's, I look at all the libraries but it's very hard to do. I mean, modern days you use OpenSSL, even do something like that. But, who compiles OpenSSL for a 16-bit platform? I don't think it's possible. Maybe it's not impossible, but it probably take many years to do it. Okay. So, I added this line in because people complain. Say I cheat a lot. So, I say, this is the best I can do with my abilities in a reasonable amount of time. I don't spend much time on this app to do the HTTPS stuff. That's not the point. Then, after you get the data, you still have to pass the J-Song. So, this is a typical way to go a very simplified way. So, this is an example J-Song string that I will get from Slack. Okay. So, how do you normally process it? It's like a key value padding where you submit pass the key, you get the value out. Then, this example here is that you're just iterating as very simple if the API is there. But you believe J-Song API exists on Winner 3.1? No, right? Okay. So, I managed to locate a J-Song library that is compatible with C89. Oh, lucky. This is the one and only one I could find. Ya. So, the trouble doesn't end there. Because this guy, when he wrote this C89 library, he recognises the fact that if you have to use his library, your system probably does not have enough memory. Right. So, the way that his library functions is not like that. You see, let's think of what happens behind the scenes here. You call it a martial, right? Basically, what's happening is that the API is constructing a dictionary, right? And then you can do the key value mapping. So, the size of this dictionary is definitely as large as the original J-Song string. Definitely, in fact, it's more that this guy recognises that you cannot double your memory, just like that. So, what he does is that when you call his API a part of J-Song string, you will get an array of tokens. Okay? And each token, he will provide the start and end position of the past key or value. So, let me demonstrate this example here. So, this is the J-Song string that one will get from Slack. So, the token that you want to pass out. Then, you call his API. So, in this example, I'm iterating through. So, when I get the first token, I have a start and then I have an end position, right? So, with the start and the end position, I get the token size. So, what this token returns, right? The start position is basically the index of the array where the key or value starts. Example, so, the value for this okay, right? It's actually 012. Start is 2 and end is 3. So, you can so and so on. So, that's why what is a bit of trouble to use is because you have to manually extract the key or value out based on the start and end position. Then, copy to another array. So, it's not that straightforward, right? So, who's J-Song passing like this is like, difficult. Because it's limited to the total size of the array. For example, max tokens here, right? I limit to 128. So, 128 means that this library will only look for the first 128 keys or values, which is actually not enough. Because, for example, the number of messages that you have in the Slack channel is so great, right? You definitely want to way you can't cover all. So, I need another level of optimization. Because if I stack usage will be so high. And, remember that Windows 3.1 stacks only 4 kilobytes. So, I need another level of optimization, which is, okay. So, this is an example of what I will receive from Slack. So, this is the messages and this is the user ID. So, first, I will actually look for the keyword text, right? So, by using a C function called string, if I locate it, right? Then, I will ask the library to process the next four. No need to process 128. Just from here, onwards, process this four, right? And after that, extract this two out. Then, copy to another data structure. Then, I repeat the process again. So, then continue. So, this will work for me. So, I don't have to now, this is in-thing. Do you think it was in-thing at that time? Ya, so definitely no. So, in the early 1990s, when Windows 3.1 and Visual Studio came out, so definitely test-driven development wasn't an important aspect of programming. So, I tried to find a test framework. So, a test framework exists for C definitely, but does not exist for C89. This is very old version of programming language. And even if, let's say such version will exist, it probably wouldn't work for Visual C++ 1.5.2. So, actually, I have to write my own simple test framework to do the testing. Okay? So, I duplicated the project. And then, these are all the packages. So, what this does is I have individual test file inside each package. And the test file will run the individual test that will test individual functions. And for network, network stuff, something special. I actually had a mock server written in Go to test the Winsock API. So, for the, this networking function to send and receive, send and receive, right? I had a simple program that will just replay whatever that is sent on the TCP connection. For the rest API testing, right? I had a mock-up of a pretend slack server that will reply the API. So, all these are the APIs that I use. Okay, conversations, Q3, users, and the posting the message. So, it fix the reply back. So, to know whether I call the recipe properly. So, if you ask me what a rare musician, how much does it improve from the actual slack app? So, let's look at the official slack app, right? All this add up is about 400 megabytes. Okay, I think it's no surprise to all of you slack app is bloated. Okay, what about the slack app? So, look at this value, virtual box which includes doors, window, trip or what, and my app is 132 meg. You include a proxy is another 9 megabytes. So, the total usage is 141 meg. Ya, so, then one of the this space usage, right? So, this space usage is, you can see, even with the size of the VM, it's still less than a slack app. So, I don't know what slack okay? So, I'm nearing the end of my talk. So, some takeaways that I'd like to talk about. So, the first thing is about writing code for resource constraint systems. I mean, people like ask me, you do a retro computing stuff, right? Ya, how does it relate to your normal work, right? The link is not immediately obvious. Okay, so in my work, I do I do I program for resource constraint systems where there are not enough RAM usage or CPU system. So, it actually is a good practice. When you write for this kind of very slow system, right? You are forced to think of creative ways to solve problems. You cannot just let's use this library, whatever just you don't care about RAM usage. But now I forced to optimize things, right? You see how I do the JSON passing? When the JSON passing will be so difficult. Okay, so, learn about things that happen under a hood. So, I do the socket programming. I've not done that in a long time, so it was very useful. Okay, reading books, right? So, if I wonder what is advantage of reading books compared to like searching on Google, right? Because when you search on Google, right? You are you are quite pigeon-pigeon holding yourself to certain knowledge. But the difference when I come to reading books is that I, when I read, then I found that there's another chapter that interests me that I read further. I know the front and the back, the story behind all these functions and how they relate together. So, I don't get that feel. Then, I understand the pride of yesteryear programmers. Ya, so, I mean that I have some colleagues who were really literally yesteryear, they are like probably double my age. Right? So, they say, those were the days, last time I know Google, I go and read book, I go to the library or whatever. See, now I understand. Don't tell me I don't understand. Okay? So, since we have a bit more time, does anyone have any... Guys, you can ask now. Okay. What are some other skill languages or platform you've developed for? Okay, my retro computing, before this thing, interest was mostly just using. This is the first time I actually developed actually for this. Ya. Ya. How long did you go back? Okay, so this one started as a hackathon. The hackathon app only took less than one day, but there's a difference between something that's written for hackathon and written for open source. Okay, so during the hackathon, obviously there was no test. And this app was actually completely rewritten after the hackathon. So I took it over a span of several months or something, like weekends, that kind of time, free time I just do. Any more? Ya. What's that? Probably a DOS app. Okay, that's all. Okay, so I'm going with came out with a lot of pause.