Jump to content
TheMole

Mess updates thread

Recommended Posts

I would like to see some sort of compromise to get the keyboard working correctly.

 

If I use the 'natural' keyboard, the function keys work correctly, but the control key doesn't work. I often do a ctrl-w to write a sector with Disk Utilities and have to switch keyboard type just to do this particular job.

 

If I use the 'emulated' keyboard, the control key works, but the function keys don't. I have to press 'alt' and the corresponding number for the function key I want.

 

There should be a keyboard setting in MESS in which both the function and control keys work at the same time.

 

I know that keyboard usage on MAME/MESS may be somewhat unintuitive at first sight, but there is some reason behind the things you observed. It is, however, not so easy to find a "compromise" due to the emulation concept of MAME/MESS.

 

By "Function keys" I suppose you refer to the F-keys on the PC keyboard.

 

Emulated keyboard

 

The emulated keyboard is a set of digital switches which report 0 or 1, according to being released or pressed. In MESS, they are queried just as realized in the real machine, which means as a matrix of switches, arranged in lines and columns. The column is selected by the emulated 9901, and the respective switch status is then sampled on the input line of the emulated 9901.

 

On the TI console, we have key combinations like FCTN-S or CTRL-W. The actual detection of this combination is done by the key scanning routine inside the console, which is also used in MESS unchanged. So you get two presses, one for the FCTN key, and one for S. This is known as arrow left, but MESS has no idea of that, as this is not its business.

 

So we need a PC key that maps to the FCTN key (and a PC key that maps to the CTRL key, respectively) so that you get your two-key combination again.

 

The bad thing about that is that the PC keyboard layout (in particular, localized keyboards) do not match the TI layout. Suppose I want to type an open parenthesis "(". The key scan routine in the TI console expects two keys to be pressed, namely "Shift" and "9". Unfortunately, on my QWERTZ keyboard, this would be the closing parenthesis. On the other hand, everything is good when I want to type "!" as Shift-1 because there is a match. Essentially, when I use my QWERTZ keyboard and I want to type CALL SAY("#NICE TRY"), I actually have to type

 

 

CALL SAZ)þ§NICE TRZþ=

 

(and you don't hear me complaining? ;) No, I well understand that this is not really desirable)

 

We could try some workarounds for this situation in order to still keep the idea of a matrix arrangement of switches without this effect, but not on a multi-system emulator like MAME/MESS which must fit thousands of other systems. The keyboard routine is deep inside the core of MAME.

 

Natural keyboard

 

Since there obviously were some people that could not get used to the emulated keyboards, the "natural mode" was conceived. The idea here is what may have come in mind when reading the above explanation.

 

Instead of turning the keyboard into a set of switches, we take the keycode from the keyboard driver and simulate a set of switches that has been pressed. For example, when Shift-a is pressed, the keycode is 0x41, and the natural mode maps this to "Shift" (as the value comes from the interval of shifted keys) and "a", which means that obviously two switches are actuated.

 

Let's have a short look at the keyboard definition in the ti99_4x.c driver. I can explain it better with some code:

 

 

PORT_START("COL2")  // col 2
  PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_C)     PORT_CHAR('c') PORT_CHAR('C') PORT_CHAR('`')
  PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_E)     PORT_CHAR('e') PORT_CHAR('E') PORT_CHAR(UCHAR_MAMEKEY(UP))
  PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_D)     PORT_CHAR('d') PORT_CHAR('D') PORT_CHAR(UCHAR_MAMEKEY(RIGHT))
  PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("3 # ERASE") PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#') PORT_CHAR(UCHAR_MAMEKEY(F3))
  PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("8 * REDO")  PORT_CODE(KEYCODE_ PORT_CHAR('8') PORT_CHAR('*') PORT_CHAR(UCHAR_MAMEKEY(F8))
  PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_I)     PORT_CHAR('i') PORT_CHAR('I') PORT_CHAR('?')
  PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_K)     PORT_CHAR('k') PORT_CHAR('K')
  PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<')

 

This is the group of keys activated when COL2 is selected, which means column 2 in the keyboard matrix. The PORT_BIT describes the bit (line) that is set when the key is pressed. Also, we have negative logic.

 

The first line says that when the scancode for "c" is received (in emulated mode), this bit is set (to 0, negative logic).

 

The next parameters are used for the natural mode.

 

PORT_CHAR('c'): When a "c" is received from the keyboard driver, we activate this line, but no modifier key

PORT_CHAR('C'): When a "C" is received from the keyboard driver, we activate this line, and also the Shift key.

PORT_CHAR('`'): When the backtick is received from the keyboard driver, we activate this line, and also the FCTN line.

 

For "Cursor left" we can query for UCHAR_MAMEKEY(LEFT).

 

 

PORT_START("COL1")  // col 1
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_S)   PORT_CHAR('s') PORT_CHAR('S') PORT_CHAR(UCHAR_MAMEKEY(LEFT))
...

 

Hence, this bit is set to 0, when "s" comes from the keyboard driver (no shift), "S" (with Shift), and Cursor Left (with FCTN).

 

Still with me?

 

Some observations:

  • As we take the key code from the keyboard driver, the driver has a chance to deliver the key according to the locale. No need to type CALL KEZ anymore, because when I type Y, I can be sure that the proper lines are activated.
  • Since we interact with the keyboard driver and have to iterate through all key definitions each time, the natural keyboard feels sluggish. The emulated keyboard is much more responsive. For that reason I accomodated myself to the emulated mode and feel much happier. :)
  • The natural keyboard mode can only work when the keyboard driver recognizes the keystroke. This entails delivering some keycode (probably from the unicode character set) that corresponds to the key combination.

 

The last point is a big problem that you already found. We have some key combinations in TI programs like CTRL-W. However, when you press those keys on the PC keyboard, they do not map to a single keycode that can be delivered by the keyboard driver, but only to raw separated scancodes from the keyboard. In other words, we cannot find a suitable PORT_CHAR to be added to the line. Without a recognized keycode, we cannot specify which lines to activate.

 

Summary

 

MAME/MESS delivers two keyboard modes which have their pros and cons. Your desire to have a simple access to the "natural" keys (like F1 or Cursor left) and the TI-specific keys like CTRL-W at the same time sounds reasonable, but I don't see how this could be solved inside MAME/MESS without a thorough redesign of the whole core keyboard routine, with the additional constraint that it must be useful for the thousand other drivers.

 

@schmitzi: I know that you like to argue from the view of the "common customer" who does not care about my technical problems and probably long stopped following my explanations ... but at that point I feel like only being able to shrug and say, love it or leave it. :)

  • Like 2

Share this post


Link to post
Share on other sites

You are right, this should be documented better. The source code was written before I knew where the samples should be kept.

 

Not at all -- I think you're doing a commendable job in documenting TI-related MESS features on Ninerpedia!

 

Just out of curiosity: Is there a chance to add another sound sample when the drive starts up? I've described this as "ploink" before, but I think "thunnnk" would actually be more accurate (at least for the drives I once owned). I loved this sound when I was playing Zork I and I finally entered a room I hadn't been to before.

 

Share this post


Link to post
Share on other sites

Just out of curiosity: Is there a chance to add another sound sample when the drive starts up? I've described this as "ploink" before, but I think "thunnnk" would actually be more accurate (at least for the drives I once owned). I loved this sound when I was playing Zork I and I finally entered a room I hadn't been to before.

 

I thought it was "shlip" when the 3.5" drive starts running after you inserted a disk.

 

Anyway, this is just the first step. If you look into the code you see there are plenty of ways to improve; in particular, to add sounds for 5.25" drives, for special drives like 1541, for different head positions etc.

Share this post


Link to post
Share on other sites

 

I know that keyboard usage on MAME/MESS may be somewhat unintuitive at first sight, but there is some reason behind the things you observed. It is, however, not so easy to find a "compromise" due to the emulation concept of MAME/MESS.

 

By "Function keys" I suppose you refer to the F-keys on the PC keyboard.

 

Emulated keyboard

 

The emulated keyboard is a set of digital switches which report 0 or 1, according to being released or pressed. In MESS, they are queried just as realized in the real machine, which means as a matrix of switches, arranged in lines and columns. The column is selected by the emulated 9901, and the respective switch status is then sampled on the input line of the emulated 9901.

 

On the TI console, we have key combinations like FCTN-S or CTRL-W. The actual detection of this combination is done by the key scanning routine inside the console, which is also used in MESS unchanged. So you get two presses, one for the FCTN key, and one for S. This is known as arrow left, but MESS has no idea of that, as this is not its business.

 

So we need a PC key that maps to the FCTN key (and a PC key that maps to the CTRL key, respectively) so that you get your two-key combination again.

 

The bad thing about that is that the PC keyboard layout (in particular, localized keyboards) do not match the TI layout. Suppose I want to type an open parenthesis "(". The key scan routine in the TI console expects two keys to be pressed, namely "Shift" and "9". Unfortunately, on my QWERTZ keyboard, this would be the closing parenthesis. On the other hand, everything is good when I want to type "!" as Shift-1 because there is a match. Essentially, when I use my QWERTZ keyboard and I want to type CALL SAY("#NICE TRY"), I actually have to type

CALL SAZ)þ§NICE TRZþ=

(and you don't hear me complaining? ;) No, I well understand that this is not really desirable)

 

We could try some workarounds for this situation in order to still keep the idea of a matrix arrangement of switches without this effect, but not on a multi-system emulator like MAME/MESS which must fit thousands of other systems. The keyboard routine is deep inside the core of MAME.

 

Natural keyboard

 

Since there obviously were some people that could not get used to the emulated keyboards, the "natural mode" was conceived. The idea here is what may have come in mind when reading the above explanation.

 

Instead of turning the keyboard into a set of switches, we take the keycode from the keyboard driver and simulate a set of switches that has been pressed. For example, when Shift-a is pressed, the keycode is 0x41, and the natural mode maps this to "Shift" (as the value comes from the interval of shifted keys) and "a", which means that obviously two switches are actuated.

 

Let's have a short look at the keyboard definition in the ti99_4x.c driver. I can explain it better with some code:

PORT_START("COL2")  // col 2
  PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_C)     PORT_CHAR('c') PORT_CHAR('C') PORT_CHAR('`')
  PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_E)     PORT_CHAR('e') PORT_CHAR('E') PORT_CHAR(UCHAR_MAMEKEY(UP))
  PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_D)     PORT_CHAR('d') PORT_CHAR('D') PORT_CHAR(UCHAR_MAMEKEY(RIGHT))
  PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("3 # ERASE") PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#') PORT_CHAR(UCHAR_MAMEKEY(F3))
  PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("8 * REDO")  PORT_CODE(KEYCODE_ PORT_CHAR('8') PORT_CHAR('*') PORT_CHAR(UCHAR_MAMEKEY(F8))
  PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_I)     PORT_CHAR('i') PORT_CHAR('I') PORT_CHAR('?')
  PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_K)     PORT_CHAR('k') PORT_CHAR('K')
  PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<')

This is the group of keys activated when COL2 is selected, which means column 2 in the keyboard matrix. The PORT_BIT describes the bit (line) that is set when the key is pressed. Also, we have negative logic.

 

The first line says that when the scancode for "c" is received (in emulated mode), this bit is set (to 0, negative logic).

 

The next parameters are used for the natural mode.

 

PORT_CHAR('c'): When a "c" is received from the keyboard driver, we activate this line, but no modifier key

PORT_CHAR('C'): When a "C" is received from the keyboard driver, we activate this line, and also the Shift key.

PORT_CHAR('`'): When the backtick is received from the keyboard driver, we activate this line, and also the FCTN line.

 

For "Cursor left" we can query for UCHAR_MAMEKEY(LEFT).

PORT_START("COL1")  // col 1
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_S)   PORT_CHAR('s') PORT_CHAR('S') PORT_CHAR(UCHAR_MAMEKEY(LEFT))
...

Hence, this bit is set to 0, when "s" comes from the keyboard driver (no shift), "S" (with Shift), and Cursor Left (with FCTN).

 

Still with me?

 

Some observations:

  • As we take the key code from the keyboard driver, the driver has a chance to deliver the key according to the locale. No need to type CALL KEZ anymore, because when I type Y, I can be sure that the proper lines are activated.
  • Since we interact with the keyboard driver and have to iterate through all key definitions each time, the natural keyboard feels sluggish. The emulated keyboard is much more responsive. For that reason I accomodated myself to the emulated mode and feel much happier. :)
  • The natural keyboard mode can only work when the keyboard driver recognizes the keystroke. This entails delivering some keycode (probably from the unicode character set) that corresponds to the key combination.

 

The last point is a big problem that you already found. We have some key combinations in TI programs like CTRL-W. However, when you press those keys on the PC keyboard, they do not map to a single keycode that can be delivered by the keyboard driver, but only to raw separated scancodes from the keyboard. In other words, we cannot find a suitable PORT_CHAR to be added to the line. Without a recognized keycode, we cannot specify which lines to activate.

 

Summary

 

MAME/MESS delivers two keyboard modes which have their pros and cons. Your desire to have a simple access to the "natural" keys (like F1 or Cursor left) and the TI-specific keys like CTRL-W at the same time sounds reasonable, but I don't see how this could be solved inside MAME/MESS without a thorough redesign of the whole core keyboard routine, with the additional constraint that it must be useful for the thousand other drivers.

 

@schmitzi: I know that you like to argue from the view of the "common customer" who does not care about my technical problems and probably long stopped following my explanations ... but at that point I feel like only being able to shrug and say, love it or leave it. :)

 

Well, that's a very nice explanation, Michael. But it applies to the emulation of the TI994/A. The keyboard behavior I'm looking for is in the SGCPU emulation, which I use almost exclusively. As you probably know, the real SGCPU keyboard behaves as I described - the function keys work as well as the control key combinations. But under MESS emulation, it doesn't behave that way. So the question is, can MESS be fixed to properly emulate the SGCPU keyboard?

 

Gazoo

Share this post


Link to post
Share on other sites

 

So the question is, can MESS be fixed to properly emulate the SGCPU keyboard?

 

I see. You did not mention SGCPU in your last post, did you?

 

(just getting a memory flashback ... it was summer of 2012 ... I asked for information about the mapping of the SGCPU keyboard ... collected all that information ... put it on a TODO list)

 

Yes, the SGCPU keyboard is not properly emulated. What I need to do is to emulate the keyboard adapter on the SGCPU so that it accepts the PS/2 keyboard input. What is done right now is to pretend that we have a normal keyboard.

Share this post


Link to post
Share on other sites

Concerning the floppy sounds - I guess most of you are using the HFDC emulation with default settings (16ms). Tip: Try the 8ms setting in the OSD menu - I find this much more realistic. Also, the BwG uses 6ms by default.

Share this post


Link to post
Share on other sites

In another thread I mention that my PC is equipped with an EZ135 and SCSI card.

 

Has there been any discussion of using media directly? That is, instead of copying a raw image and converting it to a CHD, could the image be used directly from MAME/MESS?

  • Like 1

Share this post


Link to post
Share on other sites

I guess not. All mass storage is handled in MAME/MESS uniformly by CHD ... even if we had a SCSI card and a EZ135 emulation. You may be able to read the device directly in TIImageTool, create a CHD from it, but there is no way to read the raw contents inside MAME/MESS.

Share this post


Link to post
Share on other sites

Last evening I was chasing a bug in my program that ran fine on MESS, but crashed on real iron. Yes, the issue was uninitialized RAM that happens to be all zero in MESS.

 

Could we get RAM contents randomization at startup? This would even increase the fidelity of the emulation, no?

 

(Classic99 has this feature, but in this particular case the likelihood is 65535/65536 that I was too stupid to use it correctly.)

  • Like 1

Share this post


Link to post
Share on other sites

Another suggestion:

 

It would be really helpful if you could change ROM contents in the debugger as well. Why would the debugger need to adhere to emulated hardware limitations? IMHO the debugger isn't part of the emulation.

  • Like 1

Share this post


Link to post
Share on other sites

It would be really helpful if you could change ROM contents in the debugger as well. Why would the debugger need to adhere to emulated hardware limitations? IMHO the debugger isn't part of the emulation.

 

The debugger uses exactly those memory access functions as the rest of the emulation. It would require me to do a case check - if debugger then allow writing else reject - in every part of the emulation.

  • Like 1

Share this post


Link to post
Share on other sites

Oh, I see. Well, if it's technically not feasible (or requires excessive effort) to edit ROM then that's fine. I was just arguing preemptively against writing to ROM not being "accurate". ;)

Share this post


Link to post
Share on other sites

You see, the problem is that the debugger is a generic component by itself, not TI-specific, so it must get along with those 30000+ drivers from the arcade side and the thousands of MESS drivers. For that reason it acts like the CPU and fetches memory content in the usual way. However, MAME can also show particular memory content from the buffers directly (see CTRL-M, choose the region). Maybe there are more things possible than I know about right now.

Share this post


Link to post
Share on other sites

That ^M window is what I'm actually referring to. And if I may continue to offer feature requests, then adding the VDP registers to that window's drop-down list would be nice as well (if those registers are implemented as memory).

 

Personally, I don't see the debugger as a means to debug programs, but more as a general tool for observing the state of the emulated machine when running.

Share this post


Link to post
Share on other sites

That ^M window is what I'm actually referring to. And if I may continue to offer feature requests, then adding the VDP registers to that window's drop-down list would be nice as well (if those registers are implemented as memory).

 

Personally, I don't see the debugger as a means to debug programs, but more as a general tool for observing the state of the emulated machine when running.

 

You can choose to display a memory window for the individual VDP registers and flags, but not for them all together.

Share this post


Link to post
Share on other sites

I found something odd about GROM addressing in MESS 178. This short GPL program

.

main   fmt
       row 4
       col 8
       htex '[email protected]>6000'
       fend

       move 10,[email protected],[email protected]
       move 10,[email protected],[email protected]

       b main

       aorg >7000
t7     text 'TEXT >7000'

       aorg >7800
t8     text 'TEXT >7800'
      
       end

.

should print
.
[email protected]>6000
TEXT >7000
TEXT >7800

.

on screen, and it does do in Classic99 and on real iron (well, my GROM cart). But in MESS the last line is
.
[email protected]>6000
TEXT >7000
TEXT >7000

.

Now my understanding is that real GROMs are 6K and the address counter does wrap around at >17FF, although the Ubergrom doesn't. On the other hand, there are countless cartridges with look-a-like GROMs that are 8K in size and that need to address those bytes.
How does MESS handle GROM addresses above >17FF? Why am I missing the third line? Can I enable 8K addresses in the layout.xml?
The BIN file with the program: gmove.bin
EDIT: Fixed the output.
Edited by ralphb
  • Like 1

Share this post


Link to post
Share on other sites

Use the type "gromemu" in the RPK. The GROMs in MAME are designed to be unable to address more than 6K; anything else is supposed to be a "GROM emulation".

  • Like 1

Share this post


Link to post
Share on other sites

Found this in the source code for MESS 150 (don't ask why I haven't got the latest):

 

 

Each GROM is logically 8 KiB long. Original TI-built GROM are 6 KiB long;

the extra 2kb can be read, and follow the following formula:
GROM[0x1800+offset] = GROM[0x0800+offset] | GROM[0x1000+offset];
(sounds like address decoding is incomplete - we are lucky we don't burn
any silicon when doing so... Needless to say, some hackers simulated 8kb
GRAMs and GROMs with normal RAM/PROM chips and glue logic.)

Share this post


Link to post
Share on other sites

Yes, this is far away in the past, a comment from Raphael Nabet and not applicable anymore since I rewrote the GROMs (now in file src/devices/machine/tmc0430.cpp). As I said, the way to go is to use the "gromemu" type.

 

[bTW, you're certainly free to use any MESS/MAME release, including the old ones, but you're on your own with it.]

Edited by mizapf

Share this post


Link to post
Share on other sites

 

 

Now my understanding is that real GROMs are 6K and the address counter does wrap around at >17FF

 

The address counter does not wrap at >17FF, that's just the last byte of valid data in a 6k GROM. ;)

 

The fact that you see >7800 and not >7000 on hardware should be a giveaway, cause the UberGROM cart does not include an address readback function. The GROM addresses are all being pulled from your console GROMs.

  • Like 1

Share this post


Link to post
Share on other sites

Yes, the wrap occurs for every 2K. This is the way I implemented it:

m_address = ((m_address + 1)&0x1fff) | m_current_ident;

(from tmc0430.cpp, I had to have a look whether I did it right :) )

Edited by mizapf

Share this post


Link to post
Share on other sites

Thanks, Tursi, for the clarification! And also Michael for confirmation. So wrapping is not an issue.

 

And I also discovered the source for my confusion. When looking at PHM3053G.BIN (TI Invaders rpk) from WHTech, the upper 2K are filled with data, and it's not just garbage, as there's "PRESS/ANY/KEY/TO/BEGIN" in there. But now it dawned on me that >1800->1FFF is just a mirror of >0800->0FFF in that BIN. :dunce:

 

Regarding "gromemu", where would that go? In layout.xml, <pcb type="gromemu">?

 

Edit: Bonus questions, are there any known 8K-GROM BINs? I was looking at Congo Bongo, whose GROM 4 has the upper 2K mirrored, but the upper 2K of GROM 3 are unique -- so either they're junk, or valid data ...

Edited by ralphb

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...