• Please review our updated Terms and Rules here

CP/M MBASIC - INKEY function?

nockieboy

Experienced Member
Joined
May 12, 2017
Messages
261
Location
UK - Kent
Hi everyone,

Does anyone know if there is a way of getting an immediate keypress from the user in MBASIC (~version 4) in CP/M?

I'm aware of (and using) INPUT to get a character, or sequence of characters, from the user - but this requires a Carriage Return before control is handed back to the program. I need a function like INKEY (or INKEY$) to repeatedly scan the keyboard buffer for a keypress, then pass control back to the program to act on that keypress.

Basically I'm testing out the tone generator I've built in my FPGA which handles video output for my DIY Z80 computer. I can scale through the notes easily enough with a for...next loop, but I'd like to play a note based on the key the user is pressing - and this requires something like INKEY which I can't seem to find (or its equivalent) in MBASIC. Does anyone know if such a function exists in MBASIC?

I guess I could (and probably should) switch to BBCBASIC... ;)
 
You should be able to get the function you need with wait and inp();

In my system status port is 80h
rx ready bit is 1
data port is 81h
so:
10 WAIT 128,1
20 A=INP(129)

joe
 
You should be able to get the function you need with wait and inp();

In my system status port is 80h
rx ready bit is 1
data port is 81h
so:
10 WAIT 128,1
20 A=INP(129)

joe

Thanks joe, that's a start. Problem is, reading the status port and then the data port of my PS/2 interface is a bit hit and miss, as the CP/M BIOS is already reading the port for keyboard input anyway - it's like they're fighting with each other for the port's attention. Some key presses are read fine by the BASIC programme, others are completely missed.

I've taken a quick look at writing my program in BBCBASIC as well, but I've hit a block there with the lack of (or I can't find it) an I/O OUT command. I've had a stab at creating a function in assembly to write to the correct I/O port in the BBCBASIC programme, but I can't seem to get it to work - the extensive BBCBASIC online manual doesn't seem to show an example I can make sense of.
 
Thats a little suprising. BIOS should be idle. Is it interrupt driven?
Plan B.... If your BIOS wants to fight, you can use the USR function to get the character using the bios.
You will need to code a small routine that calls the bios input character routine and calls a routine in
BASIC to return the key value. There's a good example documented in the basic manual.

joe
 
Thanks for your help, Joe - I've gone the easy route and just written a CP/M program to do what I wanted in the end. It's just a shame that neither MBASIC or BBCBASIC are able to do what I want, for different reasons.
 
I don't have it off hand, not knowing the details of the interface, but it should be trivial write a simple USR routine to call the BDOS directly and return this status properly. It's only a few line of assembly, you can stuff it in to a string variable and use VARPTR to find it, so you don't even have to come up with someplace for it. I don't know if the BASIC you're using directly support BDOS calls.
 
Hi whartung!

I'm using MBASIC 5.29 (not 4.whatever that I quoted previously!) - I seem to know more about assembly than I do about MBASIC it seems, so it was about half an hour's work to throw a CP/M program together that does everything I need (i.e. basic working keyboard synthesizer to test my FPGA's audio output in a fun way). I'll have to go away and research USR and VARPTR commands - I'm hoping they're easier to pick up than the documentation on including assembly in BBCBASIC...

Thanks! :)
 
Well, that's embarrassing.

Having taken whartung's advice, I've gone to look for information on USR and VARPTR in the MBASIC manual - and found a whole section of the manual dedicated to additional commands for the MBASIC-80 version that I'm using (my system is Z80-based). USR and VARPTR are there.... and so is INKEY$ - the exact function I was after in the first place! :rolleyes:
 
BBC basic also has an INKEY(val) function as I recall where 'val' is the amount of time the computer waits (in 1/100th of a second) before returning the result (being the key pressed or -1 if no key was pressed).
Using the assembler in BBC basic is a little bit tricky as you need to do the two passes yourself by using a loop and an OPT statement. I always found this fascinating in BBC basic.
The nice thing is that on different platforms (being Z80, 6502, x86 or ARM based) it also has the matching assembler.
BBC basic runing (almost) natively on a Pi just screams, let alone doing assembler :)
 
This whole thread had me scratching my head, as I looked over my old MBASC test suite and wondered if I'd gotten the meaning of INKEY$ wrong all those years ago... ;)
 
Back
Top