[Staff][Alpha] Emerson - TI-83+ Keyboard/Mouse

Here you can find side projects of the staff and great projects which we think should get extra support. (Note that featured projects are not projects by staff members of MaxCoderz)

Moderator: MaxCoderz Staff

User avatar
KermMartian
Calc Wizard
Posts: 549
Joined: Tue 05 Jul, 2005 11:28 pm
Contact:

Post by KermMartian »

Word, can't wait. :)
Image Image Image
User avatar
benryves
Maxcoderz Staff
Posts: 3080
Joined: Thu 16 Dec, 2004 10:06 pm
Location: Croydon, England
Contact:

Post by benryves »

Get it here.
Obviously, there is no keyboard code in there at all, it's just the mouse (I'm still pondering the keyboard).
The Mouse Demo.asm file could be useful, I know it's missing the mouse icon I used so just create a little 8x8 bitmap of a mouse if you want to test it.
Just .include Emerson.asm at the end of your file, but before that you need to specift what you want to use.

Code: Select all

.define Emerson.Mouse ; <- adds mouse routines
.define Emerson.Mouse.InvertY ; <- inverts the Y axis (by default, the origin is in the bottom-left for a mouse)
.define Emerson.Mouse.Intellimouse ; <- enable Intellimouse extensions
I think adding cursor clipping could be useful, rather than having to do it yourself.

I tried modding Solytare to use the external mouse, but the code was... strange, and whilst the game was fully playable I'd get an "ERR:MEMORY" followed by the screen turning off and RAM Clear when exiting. Not good. :P

Emerson.asm is fairly well documented inside, though the readme.htm is clearly missing.
User avatar
KermMartian
Calc Wizard
Posts: 549
Joined: Tue 05 Jul, 2005 11:28 pm
Contact:

Post by KermMartian »

Got it. Now to write an SE for DCS...
Image Image Image
User avatar
benryves
Maxcoderz Staff
Posts: 3080
Joined: Thu 16 Dec, 2004 10:06 pm
Location: Croydon, England
Contact:

Post by benryves »

I fixed a silly bug in the InvertY mode and added clipping.

.define Emerson.Mouse.Clip ; enables clipping
.define Emerson.Mouse.Clip.X 96-8 ; sets X clip
.define Emerson.Mouse.Clip.Y 64-8 ; sets Y clip

Same URL as before.
User avatar
KermMartian
Calc Wizard
Posts: 549
Joined: Tue 05 Jul, 2005 11:28 pm
Contact:

Post by KermMartian »

k, I'll get the update.
Image Image Image
User avatar
benryves
Maxcoderz Staff
Posts: 3080
Joined: Thu 16 Dec, 2004 10:06 pm
Location: Croydon, England
Contact:

Post by benryves »

It's been a while, I know, but I'm fed up with a the library sitting on my hard drive and not being available for people to use, so I'm gradually (I don't have a lot of spare time) trying to get it into shape for a proper release. It's 90% there, just needs a bit of tidying and documentation.

The mouse stuff I'm happy with. All you need to do is call Mouse.Update in your main loop and you have access to Mouse.Position.X, Mouse.Position.Y, Mouse.Position.Z and Mouse.Status.Buttons. Mouse.Intialise will reset the mouse, automatically detect if it's an Intellimouse and so on. All routines return Z on success, NZ on failure. For example, if Mouse.Update returns NZ you could just call Mouse.Initialise after it, effectively making the mouse reinitialise if you lose position information. This would make the mouse entirely hot-pluggable.

The mouse routines will also (optionally) clip the mouse to a bounding rectangle for you, will invert (again, optionally) the Y axis for you (so it points down the screen - when inverted you can use the x,y directly as a cursor coordinate on screen) and so on. It's all good.

The keyboard stuff I'm not happy about at all. The problem is that the keyboard has a lot of different scancodes, some of which are multibyte! This makes life difficult, so the library automatically converts keyboard scancodes into single byte Emerson-specific scancodes. This is all well and good, but for the fact that this conversion relies on some chunky tables and the equate names are UK keyboard specific.

Once that is fixed, there is still the issue of rewriting the scancode->key value conversion, which is pretty ugly (having to take into consideration things like shift, caps lock, num lock, ctrl and so on). Bah.

To make this worse, the keyboard I'm using is horribly cheap and doesn't send back correct acknowledgements (either it doesn't send them back at all or it sends $F5 instead of $FA). This isn't a problem with the library (I hope) as said keyboard had a habit of not being picked up by the BIOS of the PC it used to be on, so it is broken. When I plug in my normal keyboard, it works perfectly.

The main modules that will be available are AT (for byte-level comms - not optional), Mouse, Keyboard and Device.

Device hasn't been written yet, but the idea is that this (optional) module can be used to identify the device that has been attached to the calculator (so, return NZ if nothing, or a value in A that corresponds to keyboard, standard mouse or Intellimouse).

Would anyone use this? :)
CompWiz
Calc King
Posts: 1950
Joined: Thu 13 Oct, 2005 1:54 pm
Location: UB

Post by CompWiz »

I'd like the keyboard support for the calculator. I don't know how much I'd be able to use the mouse though, since it would have to be supported by programs. Does this support US keyboards?
In Memory of the Maxcoderz Trophy Image
User avatar
Saibot84
New Member
Posts: 38
Joined: Fri 17 Feb, 2006 9:14 pm
Location: Jersey City, NJ

Post by Saibot84 »

I would like to include this as a lib/plugin for the OS I'm developing...
User avatar
KermMartian
Calc Wizard
Posts: 549
Joined: Tue 05 Jul, 2005 11:28 pm
Contact:

Post by KermMartian »

I would make an SE for DCS in a hot second.
Image Image Image
User avatar
kalan_vod
Calc King
Posts: 2932
Joined: Sat 18 Dec, 2004 6:46 am
Contact:

Post by kalan_vod »

I could use this in a rts of sorts ;), I really like the mouse.
User avatar
anykey
Extreme Poster
Posts: 420
Joined: Mon 31 Jan, 2005 3:36 am
Location: In the matrix
Contact:

Post by anykey »

amazing!
sorry I can't contribute any to this; I know little about low-level hardware.
@Ben: you are freaking awesome!
I think, therefore iMac
Image
User avatar
benryves
Maxcoderz Staff
Posts: 3080
Joined: Thu 16 Dec, 2004 10:06 pm
Location: Croydon, England
Contact:

Post by benryves »

Seems like the general consensus is that I should release it, so I shall ;)
As mentioned, I have a vast amount of work at the moment preventing me from doing any of my own projects, but this project is pretty much there, just needs wrapping up - nothing too taxing. ;)

Overall, these routines are not too large - the mouse routines (+AT routines), for example, come to a little over 400 bytes at the moment.
User avatar
KermMartian
Calc Wizard
Posts: 549
Joined: Tue 05 Jul, 2005 11:28 pm
Contact:

Post by KermMartian »

Sweet, that should be perfect.
Image Image Image
User avatar
benryves
Maxcoderz Staff
Posts: 3080
Joined: Thu 16 Dec, 2004 10:06 pm
Location: Croydon, England
Contact:

Post by benryves »

The big challenge with a keyboard is handling various different keyboard layouts in a flexible manner. To understand the challenge, here's a quick run down of how a keyboard operates.

When a key is pressed or released, the keyboard transmits a sequence of bytes. The format of this is:
  • (Optional) $E0 if the key is an enhanced/extended key.
  • (Optional) $F0 if the key is being released (not sent if pressed).
  • The scancode itself.
For some of the complex keys (such as the duplicate navigation keys on a 102 key keyboard), the keyboard sends a lengthy sequence of presses and released. We'll ignore these for the moment.

The old Emerson code was pretty much hard-coded to a UK layout. It would look on one of two tables (depending on whether the scancode was enhanced or not) to work out what the value of the key was, and then convert that to an ASCII-ish value after handling modifiers. You could load different tables, but the behaviour depended on modifiers being in the same place and having the same effect on all devices.

The new system is geared towards being much more flexible. The way I intend on structuring the layout files is a bit like this...

First up, you have a list of available scancodes. One scancode represents one key. This table is an index onto further data for each key.

A key can be one of two types - a "modifier" (Shift, Num Lock, AltGr, Ctrl) or a "valued" (A, B, 6, Home) key. A modifier key won't actually return a value, but will be used to modify the current state of the keyboard.

Modifier keys map onto a bit index for the status byte. This byte holds the current modifier state of the keyboard. Multiple modifier keys can share the same bit - for example, both Shift keys could share bit 0, both Ctrl keys could share bit 1 - but as there's only one AltGr key, that would have bit 2 all to itself. Which bit you pick doesn't matter. The keys would also have an "LED" bit index - this could be used to set/reset the LED status on the keyboard.

Modifier keys can be either temporary (Shift, AltGr, Ctrl) or a toggle (Num Lock). A temporary key would only set the status bit it is tied to when it is held down, a toggle would switch the status of the bit when pressed.

For each value key, you would have a bitmask which contains the bits of the status byte that can affect it. For example, for the space key you would have a bitmask of 0 - it produces a space whatever the state of the modifier keys. For something like 5 you would have a bitmask of whatever the bitmask for shift is - it can either be 5 or %. Something like E would have to have a bitmask of Ctrl OR Shift OR Caps Lock OR AltGr. And so on. :)

There's a rough editor for all this:

Image

When the code working out what value the key is, based on modifiers, it would take the current status and AND it with the bitmask of which modifiers affect it. It could then use the resulting value as an index into the different values associated with that key and return it.

The return values can be one of two types - a character or control code that corresponds to the key ('A', '1', BS), or a "non-displayable" key (Page Up, Left). Users will have to handle values < 32 (or 127) themselves (for example, it is expected that the Del key returns character 127, DEL, or that Enter returns 13, CR).

Hopefully this system is flexible enough for most layouts!
User avatar
benryves
Maxcoderz Staff
Posts: 3080
Joined: Thu 16 Dec, 2004 10:06 pm
Location: Croydon, England
Contact:

Post by benryves »

OK, I now have it loading and managing layouts based on a layout variable (I've arranged a 102 key UK layout file). I need to get it to flag if a key is non-character key, then get the editor to export .8xp/.83p files (currently it just exports an assembly listing). The old (and rather bizarre) event-handler method has been scrapped, and there are now a few functions:

Keyboard.LoadLayout
Input: None.
Output: NZ on failure.
Other: Loads the default layout from a file on the calculator, if one is installed.

Keyboard.GetScancode
Inputs: None.
Outputs: NZ on failure/no key. A is scancode. C is set if the key was pressed, reset if released. S is set if the key was an extended key, reset if not.

Keyboard.ConvertScancode
Inputs: A is scancode. C for if the key was pressed. S if the key was extended (same as GetScancode output).
Outputs: NZ on unrecognised scancode. A is key code. C is set if the key was pressed, reset if released. S is set if the key is a non-printable key (such as Left or Right. Keys such as Delete, Backspace or Enter all have ASCII codes, so are treated as printable).
Other: The status of the keyboard is updated, including LEDs.

Keyboard.GetKey
Inputs: None.
Outputs: Same as ConvertScancode, but also returns NZ if no key was pressed.

Once I have it (cleanly) handling non-printable keys, I just need to polish off the Device routines (for working out what the connected device is, and providing a few common functions).
Post Reply