Skyhigh 20 Coding chapter
From C64 Diskmag Wiki
Coding chapter Hmm.... It strikes me as very odd that when Skyhigh is a magazine produced by one of the ruling demogroups, Camelot, which has some of the best coders on the C64 in it, that the coding chapter for the mag is going to be hosted by someone who does not really class as a coder. Yup, I bet when you saw that there was a coding chapter in this issue, you thought that Raz, Glasnost, Slammer etc would be hosting it. But, sadly, the duty has fallen to your fool of the hour, Shuze. Coding chapters in magazines are truly bizarre, it must be said. They are also the easiest in the world to do if you are feeling lazy. After all, I don't think I could count as high as I would need to, just to count the amount of magazines which have listed all the Kernal routines. The same applies for the mags which have listed illegal opcodes. The word "boring" immediately springs to mind. So, this is going to be a different chapter. What I am planning to do is start on a project, and I will tell you all, in theory, how to do all the important bits of the coding. I will also be slipping in tips here and there, to help you speed up your code, and so on. But I won't list any fucking illegal opcodes.... OK, the best thing I think we should work towards is this: HOW TO CODE A MAGAZINE OUTFIT HOW TO CODE A MAGAZINE OUTFIT It seems a better and better idea every second to get Raz to do this.... Anway, lets decide on a few parameters for our magazine's outfit. Imagine we have a real cunt of an editor who wants a load of totally unreasonble things done with the outfit (that's you, NTI! 8-): 1) A proportional displayer/upscroller 2) An IRQ loader 3) A scrolling menu 4) A logo above the text display And some other stuff. So, lets begin shall we, with a proportional displayer for our unreasonable editor. --------------------------------------------- As I said, I am not going to give you any code yet, but am instead just going to give you a lot of help on how you can code your own. If I can persuade either Biz Kid or Cupid to do some logo's and fonts for me, and Metal to do some music, I guess I will actually do all the code, and link it as an extra. OK, part one is a proportional displayer. These things are actually a standard on PC software these days, due to the extra speed of such computers. But, they are still perfectly reasonable on the C64, as you obviously have seen, from this mag! The general idea is that each letter only fills the space that it needs, instead of the typical C64 way, where each character fills 8 bits across, and 8 bytes down. So, each character takes up 64 bits, even though it may only be like the letter "i", and really fill 1 bit across. The idea of a proportional font is that it only takes up that one bit (or 2, as it will have a blank bit on the right, so all the letters are not stuck onto each other). OK, so now you know the idea, this is how it is done. There are two ways in which you can show your font on the screen. The first way is to use a bitmap screen, which is NOT the method that this outfit uses, but is the best method for a normal displayer. That is what we will use. The second method is the one that this magazine, and The Relax use, to allow an upscroller. That involves splitting the screen into horizontal bars, with a raster split. In each of those bars, you display a NORMAL block of text, with 40 chars across, and 6 chars down. Then, on each of the raster splits, you change the charset. The idea is to have, for example, in the top block, the chars numbered 0 to 239. That is 6 rows and 40 columns of chars, all of which are different. If you know anything about the way a font is defined, the data is held in the exact same way as a bitmap screen, so what you do is that you treat the charset data the same as how you would treat a bitmap screen. So, if bar one has the charset stored at $2000 to $2800, you would say "OK, so the first 6 row's bitmap screen is at $2000 to $2800. The second 6 row's is stored at $2800-$3000, and so on...." But, because you are only using 240 of the characters in the $800 bytes of screen store, instead of 256, the screen for each bar is really only stored at $800 - ($10*$8), as you are not using 16 chars worth of data, which is the same as 16*8 (16 chars*8 bytes), which is, in hex, $10*$8. So, you have to be careful of that. Anyway, that is neither here nor there, as we are using the first far simpler method of a plain old bitmap screen. We will use the second method when we get onto doing a proportional upscroller. Eek. OK, so now we move onto the theory of proportional fonts. The very first thing you need is a charset, and a list of lengths. The charset is in the usual format and attatched to them are the lengths, which are $100 (256) bytes long. Each byte in the lenghts is in the corresponding position to the screen code of the letter in question. So, if you store the lengths at position $4000 to $4100, the length at position $4001 is the length for the letter "a". And $4002 is "b", $4003 is "c" and so on. This makes life very easy, as if you want to get the length of the letter "a", you will already have the screen code somewhere, probably in the A register. So, just move it to the X register, and do: LDA $4000,X To get the length for the letter "a". Clever, eh? As a note, the easiest way to get the lengths is to use a small programme called "Proportional Convert" coded by Fuben/Oxyron. It will give you the lengths that you need. You can actuall put some code in your proportional routine to work out the length for you, but all it does is slow the whole lot down. OK, so we have our data, and our lengths. Now, onto the hard stuff. Imagine we are at the start of the top line, so since we are storing our bitmap at $2000, we are at that position. What we do is get the character we want to display from the memory (remember, we have already coded our text editor (ha!)). Lets say it is the letter "a". We know we are at the start of the line, so what we do is to get the data, and we want to store it at the right position. So, what we do is to get the position from 0 to 7 of where the last letter ended. Since we are at the start of the line, it is 0. So, we do not have to move the data over any. We then just pick up the charset data, and store it in th bitmap screen, at $2000-$2007. The best way to store it is with an ORA command. OK, then we check the length of the character. We know the oldlength was 0, and the length of the letter "a" is 7 (as we got the before). So, 0+7 is 7, so we know that it fitted into the space. If it had been greater that 8, then we would know the letter had not fitted. Anyway, lets move on. Store the 7 somewhere, as we need that for the next letter, we'll store it at $FB. So, increment the counter of the letter we are getting next. The next letter we get is the letter "b". So, get the value in $FB. Oops, it is 7. OK, so what we do now is this. We just store the letter as normal, but in the loop where we pick it up from the data and place it on the screen, we LSR the data $FB times. So, what we are doing is moving all the data 7 positions to the right. That then means that the data at positions $2000 to $2007 is the whole letter "a", and only one pixel of the letter "b". So, add $FB and the length of the letter "b", which we find to be 7 also. So, 7+7=14. Oops, bigger than 8, so we know that the letter has not fully fitted into the space $2000 to $2007. So, we store the value 14 at $FC for future reference. Then, we don't get another letter, we move onto a new loop we have not met yet. OK, this loop again gets the data we want, but it is a little different. Instead of getting the value in $FB, and LSRing is, we want to ASL the data, as now we are dealing with the RIGHT side of the letter. Confusing? OK, but how do we know how many we want to ASL it. This is the numbers bit.... OK, since we fitted in 1 column of the letter "b", it means that column 1 has been printed. So, we want to move it over 1 bit to the left. So, we get the value in $FB, and subtract it from $8, as then we get 1. And that is right, as if the value in $FB had been 5, and we had fitted in 3 columns of the letter, we would want to move the letter 3 bits left, which is 8-5. So, what you then do is to get $FB, and subtract it from 8 (remember to set the carry or the maths will bug here and there....) and then in your loop where you display the letter, ASL each byte 8-$FB times. Simple?!?!?!?!? So, now what you have to remember to do is to get the length of the letter "b", and subtract 8-$FB from it, to get the length that you want to be stored in $FB next time. Then, from this loop, what you do is add 8 to the place where you are storing the data, so that it is then stored at $2008-$200F, and so on. And then you continue in a loop. Obviously, if you are doing that on the IRQ, you want to keep a count of the amount of letters you are doing, and find out how many letters you can do in each frame. Using that method, I have got mine to display rougly 20 letters per frame, which is about as fast as you need. OK, so I will summarise the whole thing in a simple algorithm: 1) Get character 2) Get $FB 3) Get data and store it in the position, LSRing the data $FB times 4) Add the letter length to $FB, and store it at $FC 5) If $FC>8 then goto 10 6) Store $FC at $FB 7) Increment the letter-getting routine 8) Goto 1 9) ; 10) Store 8-$FB at $FD 11) Get the data and store it in the right position, ASLing it $FD times 12) Store charlength-$FD at $FB 13) Add 8 to the position where the data is being stored in the bitmap screen 14) Increment the letter getting routine 15) Goto 1 And that is it, except that you need a few more routines to code a mag outfit. The main ones are routines to check if the letter you have got is a marker for the end of a line or page. For that, just check if the letter you have gotten is equal to a $00 byte, and if so, then store 0 at $FB, and change the position that the text is being stored at. It is easier to store somewhere the position in memory of the start of the line you are on (so, store the bytes $00 and $20 somewhere) and then if you rech a $00 byte, add 320 to those bytes, by the usual hi/lo byte method (i.e. add 160 to the $00 byte, and if the carry is set, increment the $20 byte, then do that again, to add 320). Then, store that value at the loop that displays the text. Then, you need an end of page routine, which is easy, as all you do is check, when you hit an $00 byte, if adding 320 will take you past the end of your page, and if so, then you set an end flag, and wait for the spacebar to be pressed, or the joystick, or something like that. Going backwards through the text is a little more difficult, as then you then have to scan backwards through a certain amount of $00 bytes. But, if you have an end marker at the end of a page, like Raz does in this outfit, it is a lot easier. And that is it. Next time, we will go over the theory of a proportional upscroller and I will hopefully code one to show you how it is done. Sadly, there will be no code on this issue from me, as I have already gone 3 days over my deadline from Biz Kid, so I do not have time to do more! But, hopefully we can squeeze Fuben/Oxyron's proportional converter on this issue for you. Ok then, that is it. I particularly need your comments on this chapter so that I can try and make it more reader friendly, so either get in touch, or write a reaction on a sheet. Thanks a lot. Shuze/AFL'70 (I really would have included the proportional con- verter from my cool buddy Fuben, but Shuze forgot to include it on his disk, and I can't find my own ver- sion!! So I guess you will have to wait for the next issue to get it - right Paul!! -bk!)