Page 1 of 2

My kernel is done

Posted: Fri Aug 22, 2003 1:28 am
by Tux
(Save it and rename it to .img)

I cannot take all the credit even if I rewrote all the drivers. I gave credit where credit is due. The main core was done by me :)

Prees up/down to begin.
It has some "layer glitches", but I wrote this in the night so forgive me ???

I'll release the source at the rite time :)

This was a way for me to blow off steam and help me sleep. Tell me what you think :)

[attachment deleted by admin]

Re:My kernel is done

Posted: Fri Aug 22, 2003 1:31 am
by Tux
BTW, not tested on real hardware :/
So I'll like debug info.
Actually I am killing the project so no need for debugging.
I am thinking to send it to Elec. Gam. Monthly so they convince everyone that the pc IS a console system :)

Re:My kernel is done

Posted: Fri Aug 22, 2003 1:35 am
by Tux
I'll also ask people not to tell what is in the kernel.
Make it a surprise.

Re:My kernel is done

Posted: Fri Aug 22, 2003 2:43 am
by Pype.Clicker
fun, but totally useless on Bochs due to "internal keyboard buffer full" ...

maybe you should consider reprogram the "keymatic rate" so that you only receive interrupts on key stroke and key release (and not repeating keyboard strokes every N ms (like keyboards usually do) ...

btw, how did you switch video mode ? while in realmode or using V86 ?

Re:My kernel is done

Posted: Fri Aug 22, 2003 3:04 am
by Pype.Clicker
also surprising to see the CPU time at 100% during the whole demo. You should consider including a "hlt" instruction when the system is iddle (i.e. has no event to react to) ... And if you're waiting for an I/O condition that you must poll and you know that is about to occur in N ms, just go for deep sleep for (say) N-Q ms and then actively poll during the last Q ms :)

Re:My kernel is done

Posted: Fri Aug 22, 2003 8:01 am
by TheChuckster
Your demo didn't work on my computer.

In Bochs the BIOS reported errors and in VMWare I got a blank screen, redownloaded, and it paniced completely. Are you sure it isn't corrupt? Also, I've been using it as a floppy image. Am I running it correctly?

Re:My kernel is done

Posted: Fri Aug 22, 2003 10:00 am
by Schol-R-LEA
OK, I got it to work with Bochs 2.0.2 (under Windows XP), albeit rather slowly; I haven't tried it on live hardware yet. The keyboard buffer issue is definitely a problem, if not quite a showstopper; fixing it would definitely improve the responsiveness. Still, this isn't bad at all.

Ahh, does that bring back memories, though. ;D

Re:My kernel is done

Posted: Fri Aug 22, 2003 11:24 am
by Tux
I am gonna go crazy if you say slowly X-)

I ran it on actual hardware, it went toooooo fast.
I forgot to mention that I tried to use the pcs internal speaker, but no avail. I was hoping to get some beeps out of it. Before I include the source, I wannah say that the drawing is done in a stack sort of manner:

A padel.

[1]
[2]
[3]

When you press up, the bottom box is deleted, and added to the top:

[3]
[1]
[2]

This is where the layer glitch happens, box 1 is not redrawn till it is moved, so when the ball bounces, it corrupts the box one graphic. Anyway, here is the source:

[attachment deleted by admin]

Re:My kernel is done

Posted: Fri Aug 22, 2003 11:33 am
by Therx
Haven't looked into the source fully but I was just wondering why most of the functions are in header files?

I know this simplifies linking but I can't help but feel it is 'wrong'. Headers were for prototypes and definitions, and the Source Files were for Functions.

Just wondering

Pete

Re:My kernel is done

Posted: Fri Aug 22, 2003 11:50 am
by Tux
I don't know how else to put it. The .h file is equal to a .inc file in asm. The compiler replaces the #include with the file. So:

#include "donothing.h"

void main()
{
donothing();
}

Gets compiled to:

void donothing()
{
}

void main()
{
donothing();
}

And from there it does other compiler stuff.
(Actually the compiler checks the #ifdefs first to see if there is anything to include inside the #ifs)

Re:My kernel is done

Posted: Fri Aug 22, 2003 12:20 pm
by Curufir
lol, good fun, glad to see I'm not the only one that remembers the classics ;D.

I have to agree with the others though, header files are intended to be used for glue, not code. In theory AFAIK their use should be limited to definitions of variables/functions/structures contained in a .c/.cpp file (Ie Header files are used to export an object file's API). The way it is now you have to recompile every file to create the final executable, if you use header files correctly then you only have to recompile the altered source files and relink object files. It's not anything to worry about in this instance, but in a larger project you will probably find yourself not wanting to recompile the whole thing every time you change one file.

The other thing I've gotta mention is the fact that this image is over 16k big, even without the bootsector. Is this due to using C++? I find it difficult to believe that even with the required kernel setup part that it should be this big. I'm not trying to disparage your skill or code, I'm just wondering how much bloat the C++ paradigm brings with it automatically because it's made me curious.

Re:My kernel is done

Posted: Fri Aug 22, 2003 12:50 pm
by Schol-R-LEA
Taking at look at the code... well, I've got to say it's not how I would have done it, but then again, it would have taken me a good deal longer to do it and I don't know how well it would have come out.

I have to agree with Therx that it would be better to link in the library code rather than having it all inline. If you separate your functions into their own .cpp source files (leaving only the global variables and the function prototypes in the headers), compile each of them with the same options you used for kernel.cpp, and add the resulting object files to the linker after kernel.o, you should be able to link the whole program together. I must admit that I am not all that familiar with working with ld(1), but as far as I can tell, this should work correctly, even using binaries compiled as -ffreestanding. I would be interested in any corrections on this point, however.

I would probably have broken the overall algorithm in main() into a lot more separate functions; the function call overhead should be negligible (and if it really bothered you, you could inline the functions), while the greater decomposition of the algorithm would make the code a lot easier to read. Also, there seems to be a fair amount of repetition in the code; separating repeated operations into their own functions should reduce the overall code size. This would also help reduce the number of semi-global variables used in main(), which agani would help with debugging.

While I haven't looked too closely at it, I suspect that many if not most of the extended conditional statements (the several long "[tt]if()...else if()...[/tt]" chains) could be replaced by lookup tables, which should be both more compact and faster.

A lot of people are going to give you grief over the heavy use of [tt]goto[/tt], and I can't say I disagree with them. While I'm inclined to give you the benefit of the doubt on the issue (program flow in games sometimes does require that kind of thing), I'd definitely suggest seeing if they could be eliminated or replaced with, say, function calls - yet another reason to break the program down into smaller functions.

in the keyboard polling routine (which should definitely be a separate function, IMAO), you use several succesive calls to Keyboard.getchar(); not only is this wasteful, as you are polling the same device repeatedly, it also presents a problem in that the state of the keyboard may have change between the two function calls. It would be better to trap the keyboard state in a temporary variable, which would not only avoid the problem but also make the individual comparisons faster.
HTH. C&CW.

Re:My kernel is done

Posted: Fri Aug 22, 2003 1:13 pm
by Tux
Since I am working on a nanocore, we are using include .h and breaking standards :)

I see the reason for .h files (Check out the FS2 sourcoude, takes 1 hour to compile), but when working on a small project, you tend to drift away from standards. All I have to say is, enjoy :)

Re:My kernel is done

Posted: Fri Aug 22, 2003 1:19 pm
by Tux
Hmmm, just for fun I may rewrite it in text mode. I am gonna try to make a tutorial for it too. Xsism is on vacation still, school is almost close, and this is good for math.

Re:My kernel is done

Posted: Fri Aug 22, 2003 1:42 pm
by Schol-R-LEA
OK, here's a specific example of something in your code that could broken down into a separate function, the code for drawing the paddles. RIght now, it consists of two successive nested for() loops, to draw the initial state of the paddles, plus similar loops throughout the code to redraw them when they are changed. The whole thing could be simplfied as a single function of arity three:

Code: Select all

enum {BLACK = 0, WHITE = 223} COLOR;
int const p1_col = 10;
int const p2_col = 304;


void draw_paddle(int hpos, int vpos, COLOR c) 
{
  int const width = 6;
  int const height = 22;

   for(int dy=0;dy<height;dy++)
   {
     for(int dx=0;dx<width;dx++)
     {
       video.putpixel(hpos+dx,vpos+dy, c);
     }
   }
}
Which could then be called like so:

Code: Select all

draw_paddle(p1_col, p1[0], WHITE);
draw_paddle(p2_col, p2[0], WHITE);
To move the paddle, you'd simply do something like:

Code: Select all

draw_paddle(p1_col, p1[0], BLACK); // erase paddle
p1[0] -= 2;  // move paddle
draw_paddle(p1_col, p1[0], WHITE);
Note that this code has not been not tested; it is simply a demonstration of how it could be simplified. There are several sections of the code where this should be possible; how you would decompose it would be up to you. Note that this may require some changes in the program flow, but if done carefully, the changes should improve overall program behavior.

Admittedly, I'm something of a fanatic on this point: if four or more lines of code are used twice in a program, I often try to make a function out of them. Similarly, I loathe having any magic numbers (def. 1) in code, and invariably put them into named constants, even if they are only used once. You probably don't want to go to quite such lengths, but you really would be better off decomposing the problem further than you have and givng names to the more commonly used constants.