• Please review our updated Terms and Rules here

keyboard input in borland c++ for dos

PgrAm

Experienced Member
Joined
Sep 28, 2011
Messages
276
Location
Toronto, Canada
I'm in the middle of porting a game I wrote for SDL into normal VGA mode dos (which I must say has been very easy so far). I'm using borland C++ 3.0 for my compiler and I'm using a 386 pc with a VGA card. Does borland provide any functions in dos.h or wherever for getting immediate keyboard presses. Something like GetAsyncKeyState() in windows. How would I go about doing this in dos?

I am a competent programmer so if this sort of thing requires interrupts or reading bytes straight from the keyboard I can do that.

thanks.
 
Look at the bioskey( ) call ... you can poll the keyboard in a non-blocking way to see if there is something to read. If it tells you there is a key available then you can read it.


Mike
 
for a game, i would hook int 9h and read scancodes from the keyboard port.

What functional difference is there?

Bioskey will tell you the scan code if the user gives you something that is not ASCII. If you insist on reading scan codes directly from the keyboard, then you lose any remapping that the BIOS might be doing for you. That means the game becomes *very* tied to a specific keyboard layout. That breaks machines like the PCjr, the IBM Convertible, and anything else with a non-standard layout.

If you want to differentiate between the arrow keys of an extended model M and a standard model F in the AT line you can use a newer BIOS call for that. You do not need to take over int 9h, and doing so means that you had better be prepared for the non-standard machines out there. (As well as keyboard utilities and other TSRs that think they know what they are doing too.)
 
What functional difference is there?

The main one is that you get notified when keys are released as well as when they are pressed - for games that is important because you want your character to move continuously as long as the key is held down and then to stop immediately when the key is released.

The other is that you get notified about every key including the shift, ctrl and alt keys which don't generate BIOS codes. You can find out the state of these keys with a BIOS call but if you hook int 9 all the keys work the same.
 
What about machines that don't use IBM compatible keyboard controllers, such as Amstrads?
 
What about machines that don't use IBM compatible keyboard controllers, such as Amstrads?

I think pretty much anything compatible enough to be called a "PC" will have the same low-level keyboard interface presented to software - i.e. interrupt 9 and ports 0x60 and 0x61 (though some of the scancodes are different on some machines). So many games use this method of keyboard input that any machine that didn't support it would have been at a great disadvantage.

I'm not sure which Amstrads you had in mind but the PC1512/PC1640 definitely have IBM compatible low-level keyboard software interfaces - Digger was one of the first games that I played on my PC1512 and that uses interrupt 9 for all its keyboard input.

I don't know of any machines that run DOS and don't have this keyboard software interface, but this being VCF I'm sure someone here will come up with the counterexample!
 
The main one is that you get notified when keys are released as well as when they are pressed - for games that is important because you want your character to move continuously as long as the key is held down and then to stop immediately when the key is released.

The other is that you get notified about every key including the shift, ctrl and alt keys which don't generate BIOS codes. You can find out the state of these keys with a BIOS call but if you hook int 9 all the keys work the same.

Good points, and I had forgotten about them. The code that I write normally doesn't measure or care about keys being held down - it just wants to know what was pressed. So if you need to detect keys being held down, then polling the keyboard using the bioskey calls does not work.

As far as compatibility with other machines - most other machines with non-standard layouts do the remapping *before* the INT09 routine is called. So INT09 is not as big of a compatibility problem as I suggested. (My brain was in the offline state when I wrote that.) For example, the PCjr uses the NMI interrupt to read the keyboard, maps the PCjr specific keys to the standard scan codes, and then invokes INT09.


Mike
 
I'm using int 9 now and it works great. I found info on it in an old book I have and I made an ISR to handle input.

I'll post the game I made on this forum later so anyone can download it.
 
something that a lot of applications do (i.e. EDIT/QBASIC and more) is hook int 9, but then do a PUSHF and far call to the original BIOS handler. when it IRETs, it'll return control to your function where you can then get the new keystroke after scancode conversion through int 16h so you retain that benefit but don't waste any time on polling or use blocking calls.

something like this.

Code:
void far interrupt (*oldhandler)();

void far interrupt myhandler() {
    (*oldhandler)();
    // get keystroke value from BIOS here...
}

then somewhere in the game init code,

Code:
oldhandler = _dos_getvect(9);
_dos_setvect(9, myhandler);

the only annoying thing about doing it this way is that you can't get shift/ctrl/alt key states by using the same BIOS call that gets the other keys.
 
Last edited:
what kind of game is this, btw?

sort of a generic space shooter.

I originally began writing it as a windows SDL game but never finished it. After I got a retro PC I decided it was simple enough to port to dos and I decided to finish development there. I hope to eventually add Adlib sound but I'm no musician so chances are it will be pretty simple tunes. There's a little problem with flicker in my game but immediately after I fix it I will post it, hopefully later today.
 
sounds good! so, something along the lines of galaga? as far as playing music from an adlib, you might want to look into making a MIDI file player engine. it might be more hassle than it's worth, though. the file format looks fairly complicated, but i suppose not too bad. you wouldn't really have to support every little thing it has i guess. i've never tried doing it myself, but here's some info on it:

http://www.sonicspot.com/guide/midifiles.html


that way you could just search the net a bit to find some MIDIs that would fit well in your game, and use them. for sound effects like shooting a laser, explosions, etc. you could just use the PC speaker. ultima 6 does this, and it works nicely. that way if somebody doesn't have a music card, they can still get the sound effects at least.

basic adlib programming itself isn't too complicated, i had to learn how the adlib is controlled via I/O ports to emulate it in fake86 and it was a lot less complicated than i thought it would be.
 
Back
Top