Re: [Freedos-user] Zmiy - a snake-like game for 8086 (like Nibbles)
Hi Eric/Rugxulo, Thanks for your input! I did read a long time ago the power.txt that Mike wrote, but had forgotten it since. After looking again, I saw the note about INT28h. After a few tests, I see that it's actually the best way, since it works on DOSBox, DOSemu, and VirtualBox making them all running cool (ie. not at 100% cpu). So I added it to Zmiy, and made the default energy-saving method. I still haven't figured out any simple way of performing time polling with sub-55ms precision, so I will probably leave it as is (that's not a very big deal anyway). I'm suprised though, that there is well-known microsecond-grade sleep function provided by the BIOS (int15h AH=86h), but no sibling function to just retrieve a timer with such precision. The 'reprogramming the PIT' subject is interesting, but I fear I won't have enough time to really figure all the implications to do it right. About VGA: Yes indeed, Zmiy requires a VGA display for 80x50. On EGA, it will initialize the screen into 80x43, which will make the game hardly playable. I am thinking about converting Zmiy to 80x43 instead, then adding some VGA-detection routing to force it into 80x43. Will probably do this in some future release. cheers, Mateusz On 07/31/2013 12:13 AM, Rugxulo wrote: Hi, On Mon, Jul 29, 2013 at 2:36 PM, Mateusz Viste mate...@viste-family.net wrote: I had a few minutes of free time lately and felt the inexplicable need to write a Nibbles clone I called it 'Zmiy'. It's written in C89, compiled with Turbo C, and, as usual, released under GNU GPL 3 http://sourceforge.net/projects/zmiy Good to know. Boring LONG tech stuff below // you might want to ignore this - During the development, I encountered an interesting problem: timing. It's probably obvious stuff to most people here, but I actually never really played with game-oriented timing in DOS. I implemented inside zmyi 3 different timing mechanisms (configurable via command line). I've not written a lot of low-level code, so my understanding of such things is limited to what I can glean from online forums (i.e. not much). What is the full list of environments you're trying to run under? Just everything you can get your hands on? :-) Apparently: native DOS, VirtualBox, DOSEMU, DOSBox, NTVDM The first (best so far) is checking the time in a loop (at 18,2Hz), and performing an int15h AX=5305h at every iteration to notify APM about available CPU. The second is about calling the BIOS function int15h AH=86h. The third one is about using the Turbo C 'delay' function (supposed to provide a millisecond-grade sleep). So you want sufficiently smooth speed but also power savings (not hog cpu)? I was also wondering about issuing HLT instructions, but it doesn't look like a nice solution to me, since it would require to add some asm into my C project, and it wouldn't work on many platforms (Windows...), and I feel it's not the application's job to issue HLT, this should be taken care of by APM, or the BIOS, or whatever.. But not the application. DOSBox has adjustable cycles (and core and frameskip). DOSEMU, I'm not sure exactly what it's called, but it has some hogging threshold setting in some tool somewhere. Other environments may let you cap your cpu use too (e.g. VirtualBox: System Processor, Execution Cap or perhaps Windows: Task Manager, Set Priority). But usually I just leave things as default (since lacking much reason to delve further). Any suggestion about some neat (and simple, if possible) usleep()-like mechanism that I could use? My int15h AH=86h method is sleeping very nicely (with high resolution), but it makes the keyboard laggy, so I wonder if it's the best path.. I've read a bit about reprogramming the PIT, but it sounds a bit scary, and probably not allowed by Windows anyway (I'd like to keep zmyi 8086-compatible, but still playable on other platforms). I consider Windows almost a lost cause. XP at least somewhat works (barely), but outside of that (Vista, 7, 8) it's probably not (IMHO!) worth even trying. int 15h, 86h is limited under modern NT-based Windows, IIRC, something about not updating as frequently as you'd want. You'd have to check DJGPP libc sources, I forget the details: http://www.delorie.com/bin/cvsweb.cgi/djgpp/src/libc/pc_hw/timer/uclock.c?rev=1.5 As for just not wasting cycles, you may? wish to try the equivalent of __dpmi_yield, which is basically just calling int 2Fh, 1680h. N.B. You must call this via int 31h, 300h in order to work properly under WinXP. And of course check to make sure the vector of int 2Fh isn't zero first (before testing for DPMI before actually calling this). Not supported by every DPMI environment but helpful to those that do. (I think even mTCP uses this nowadays, see POWER.TXT.) https://code.google.com/p/mtcp/ And here's some more obligatory links:
Re: [Freedos-user] Zmiy - a snake-like game for 8086 (like Nibbles)
I still haven't figured out any simple way of performing time polling with sub-55ms precision, so I will probably leave it as is (that's not a very big deal anyway). There actually is a way to do this, but you have to combine BIOS data with I/O data directly from the PIT. A little cumbersome, but possible. I'm suprised though, that there is well-known microsecond-grade sleep function provided by the BIOS (int15h AH=86h), Actually, it's not microsecond-grade, only millisecond grade (read the notes in RBIL). I actually think your best option is either INT 15.83, or trapping INT 70h and having it increment/decrement your own internal counter. The 'reprogramming the PIT' subject is interesting, but I fear I won't have enough time to really figure all the implications to do it right. I personally wouldn't recommend reprogramming the PIT -- that would be my last possible choice that I would use only if nothing else worked. You can run into obscure and erratic compatibility problems (especially with TSR's and device drivers) if you reprogram the PIT. -- Get your SQL database under version control now! Version control is standard for application code, but databases havent caught up. So what steps can you take to put your SQL databases under version control? Why should you start doing it? Read more to find out. http://pubads.g.doubleclick.net/gampad/clk?id=49501711iu=/4140/ostg.clktrk ___ Freedos-user mailing list Freedos-user@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/freedos-user
Re: [Freedos-user] Zmiy - a snake-like game for 8086 (like Nibbles)
Hi, On Mon, Jul 29, 2013 at 3:02 PM, Eric Auer e.a...@jpberlin.de wrote: I had a few minutes of free time lately and felt the inexplicable need to write a Nibbles clone I think the last time I wrote a Snake clone in 2.5 dimensions in Borland, in Pascal, I updated the code to use 40:6c aka 18.2 Hz timer ticks at some point. FYI, here's a link: http://ericauer.cosmodata.virtuaserver.com.br/soft/specials/snake_vr_2007.zip -- Get your SQL database under version control now! Version control is standard for application code, but databases havent caught up. So what steps can you take to put your SQL databases under version control? Why should you start doing it? Read more to find out. http://pubads.g.doubleclick.net/gampad/clk?id=49501711iu=/4140/ostg.clktrk ___ Freedos-user mailing list Freedos-user@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/freedos-user
[Freedos-user] Zmiy - a snake-like game for 8086 (like Nibbles)
Hi all, I had a few minutes of free time lately and felt the inexplicable need to write a Nibbles clone (remember this game that was shipped with QBasic ages ago?). I called it 'Zmiy'. It's written in C89, compiled with Turbo C, and, as usual, released under GNU GPL 3 (yes Rugxulo, I *am* aware that the license file is twice as big as the whole source code) ;-) Here it is - I hope it will provide some 5-minutes fun to other oldish-oriented geeks like me. http://sourceforge.net/projects/zmiy Boring LONG tech stuff below // you might want to ignore this - During the development, I encountered an interesting problem: timing. It's probably obvious stuff to most people here, but I actually never really played with game-oriented timing in DOS. I implemented inside zmyi 3 different timing mechanisms (configurable via command line). The first (best so far) is checking the time in a loop (at 18,2Hz), and performing an int15h AX=5305h at every iteration to notify APM about available CPU. This works very well on a real machine, as well as on VirtualBox (with and without FDAPM). The CPU usage is very low. Surprisingly, under both DOSEmu and DOSBox the CPU usage is very high. I guess they don't support the APM v1.0 interface... The second is about calling the BIOS function int15h AH=86h. This works okay on a real machine, but makes keyboard controls under DOSemy laggy, and don't work at all with DOSBox. DOSBox keeps crying this: Illegal read from 5820585e, CS:IP f000:11c4 The third one is about using the Turbo C 'delay' function (supposed to provide a millisecond-grade sleep). I don't know what is behind this, but it makes CPU usage very high. It works fine under DOSBox (apart form the burning CPU), but not under DOSemu (don't sleep at all, which makes it impossible to play, unless your name is Barry Allen). I was also wondering about issuing HLT instructions, but it doesn't look like a nice solution to me, since it would require to add some asm into my C project, and it wouldn't work on many platforms (Windows...), and I feel it's not the application's job to issue HLT, this should be taken care of by APM, or the BIOS, or whatever.. But not the application. Anybody had such problems too? Is there a 'silver bullet' for such timekeeping gaming needs under DOS *and* keeping 8086 compatibility? Another issue I had (still have, in fact) is the timer resolution. The resolution of my APM-aware sleeping routines is of ~55ms (18,2Hz). This makes the game not as smooth as I'd like. Any suggestion about some neat (and simple, if possible) usleep()-like mechanism that I could use? My int15h AH=86h method is sleeping very nicely (with high resolution), but it makes the keyboard laggy, so I wonder if it's the best path.. I've read a bit about reprogramming the PIT, but it sounds a bit scary, and probably not allowed by Windows anyway (I'd like to keep zmyi 8086-compatible, but still playable on other platforms). BTW, if you test Zmiy on DOSBox, you will notice that the palette is wrong. I have no idea why - seems that DOSBox initializes a different palette on 80x50 than what a real PC do. Mateusz -- Get your SQL database under version control now! Version control is standard for application code, but databases havent caught up. So what steps can you take to put your SQL databases under version control? Why should you start doing it? Read more to find out. http://pubads.g.doubleclick.net/gampad/clk?id=49501711iu=/4140/ostg.clktrk ___ Freedos-user mailing list Freedos-user@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/freedos-user
Re: [Freedos-user] Zmiy - a snake-like game for 8086 (like Nibbles)
Hi :-) I had a few minutes of free time lately and felt the inexplicable need to write a Nibbles clone (remember this game that was shipped with Hehe :-D The first (best so far) is checking the time in a loop (at 18,2Hz), and performing an int15h AX=5305h at every iteration to notify APM about available CPU. This works very well on a real machine, as well as on VirtualBox (with and without FDAPM). The CPU usage is very low. I guess the recommended way is to notify DOS and let that do the rest. Not sure if DOSEMU implements this function. I remember that some VM, possibly DOSBOX, did not emulate HLT, because they were just happy to let DOS stuff run faster by making HLT a NOP :-p It is quite possible that DOSEMU does not do much with APM BIOS, but there is an API to check exactly that ;-) Surprisingly, under both DOSEmu and DOSBox the CPU usage is very high. I guess they don't support the APM v1.0 interface... The second is about calling the BIOS function int15h AH=86h. This works okay on a real machine, but makes keyboard controls under DOSemy laggy, This can be because int 15.86 can try to be smart: Use 18.2 Hz ticks for longer delays and do busy-waiting in a tight loop otherwise. It is possible that some BIOSes use CMOS 32kHz ticks or other fancy and energy-friendly waiting methods for shorter delays, but you simply do not really know. and don't work at all with DOSBox. DOSBox keeps crying this: Illegal read from 5820585e, CS:IP f000:11c4 Weird. Ask their forum? The third one is about using the Turbo C 'delay' function (supposed to provide a millisecond-grade sleep). I don't know what is behind this, Typical Borland IDE compilers come with runtime libraries which implement this as tight loops calibrated when your app starts. Well-known Error 200 for those where you get an overflow for fast CPU. Otherwise just CPU cycle waste. but it makes CPU usage very high. It works fine under DOSBox (apart form the burning CPU), but not under DOSemu (don't sleep at all, which makes it impossible to play, unless your name is Barry Allen). Barry Allen? I think the last time I wrote a Snake clone in 2.5 dimensions in Borland, in Pascal, I updated the code to use 40:6c aka 18.2 Hz timer ticks at some point. I was also wondering about issuing HLT instructions, but it doesn't look like a nice solution to me, since it would require to add some asm into my C project, and it wouldn't work on many platforms (Windows...), and I feel it's not the application's job to issue HLT, this should be taken care of by APM, or the BIOS, or whatever.. But not the application. In DOS, it was fine to HLT, but you can also tell DOS that you are idle, then FDAPM will either HLT or call the APM BIOS function, depending on what is available then :-) Another issue I had (still have, in fact) is the timer resolution. The resolution of my APM-aware sleeping routines is of ~55ms (18,2Hz). This makes the game not as smooth as I'd like. You can change frequency to anything faster, as long as you put your own int 8 handler which takes care that the original handler is only called as often as intended. Otherwise, lots of DOS and BIOS things would suddenly go faster. Programming the frequency of the timer is easy: Same hardware interface as what you use for different frequency PC speaker beeps :-) Regarding PIT programming, you normally just write hex 20 to the PIT port for IRQ ack when you are done, UNLESS you call the original int 8 handler, in which case that will do it for you. You want to avoid sending too many ACK but as you notice, most handlers do not actually take efforts to do SPECIFIC ACK such as am done with IRQ 0 aka int 8 but just send done with IRQ. Cheers, Eric -- Get your SQL database under version control now! Version control is standard for application code, but databases havent caught up. So what steps can you take to put your SQL databases under version control? Why should you start doing it? Read more to find out. http://pubads.g.doubleclick.net/gampad/clk?id=49501711iu=/4140/ostg.clktrk ___ Freedos-user mailing list Freedos-user@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/freedos-user