the Power Glove

Discuss technical or other issues relating to programming the Nintendo Entertainment System, Famicom, or compatible systems. See the NESdev wiki for more information.

Moderator: Moderators

LoneKiltedNinja
Posts: 63
Joined: Mon Jul 07, 2008 7:40 pm

Post by LoneKiltedNinja »

I'm sure nocash has already done this as well, but... yeh. The ALU opcodes in the cop888 seem to have no alignment any which way to the behaviors he's documented for the 8 and 16-bit instructions. Which, sadly, means there's probably some internal ROM being run that takes the data and parses it out as a sort of meta code set. And really, with so many bits seeming to correspond to raw data parameters, there wasn't much room at all for them to be proper CPU opcodes :P

And speaking of opcodes and programming... ugh. I can see why reading whatever is there would be a pain. Looks like the only way in or out of this chip for bulk data transfer is the MICROWIRE/PLUS bus which, at a very high level, looks to be an 8-bit-at-a-time automatic serial protocol. Very nice, presumably, when dealing with data from a shift register, but not set up for a good old-fashioned address->data query. For that matter, indications seem to point to the ROM being on-board and not even accessible directly to the program running within it- all opcodes resolve to an independent data-space address map. Allegedly chunks of ROM can be transferred to data RAM, but to do that you'd presumably need to be running your own code in the ROM to begin with.
LoneKiltedNinja
Posts: 63
Joined: Mon Jul 07, 2008 7:40 pm

Post by LoneKiltedNinja »

nocash wrote:PCB at the front of the glove (on the hand): http://www.instructables.com/files/deri ... .LARGE.jpg (component side), and http://www.instructables.com/files/deri ... .LARGE.jpg (solder side). The two speakers seem to be the round black things above index finder and little finger. And, there seems to be a third speaker glued to the middle of the casing; I guess that's where the "beep" sounds are coming from.

PCB for the button part (on the arm): http://www.instructables.com/files/deri ... .LARGE.jpg (showing a fragment of the solder side only). Not much seen there, judging from the solder pads, it doesn't look as if there's a CPU on the component side (unless it'd be a SMD chip). So far, I'd guess that the CPU is located in that mysterious "junction box" (the small box that most photographers never mind taking pictures of when they are posing with their glove).
Okay. So the brain isn't in the front of the glove, and it's not in the controller part of the glove (unless it's the IC evident on the reverse side of that PCB). Which leaves the box-shaped things. And box-shaped things with easily accessible screws aren't as bad to open.

I opened up the junction box (first box off the short lead to the NES plug) and the brain isn't there. Just some resistors and a couple "ST" brand LM324N A935 ICs which, without bothering to look them up because I'm lazy, I'd guess would be some manner of shift-register or serialization controller. (EDIT: nope. It's a quad op-amp. - http://www.datasheetcatalog.com/datashe ... 324N.shtml) http://www.psychsoftware.org/stuff/temp ... 020329.JPG

Which leaves the boxes in the frame. Frame box #1 (literally, they have numbers: 1, 2, 3) contains a minimalist PCB with one tiny Texas Instruments TL062CP 939EB (EDIT: another op-amp - http://www.datasheetcatalog.com/datashe ... 62CP.shtml). http://www.psychsoftware.org/stuff/temp ... 020330.JPG Ditto on box #3 (out of order only because it was more accessible than the corner), which also has the main wire harness out to the Junction Box. http://www.psychsoftware.org/stuff/temp ... 020331.JPG
Box 2 has 2 boards- a clone of #1/#3, and the LED board containing a somewhat prominent Texas Instruments / MALAYSIA 8935AS SN74LS164N. Which still doesn't look big enough to be a proper CPU. (EDIT: THIS is a shift-register. Serial-in-parallel-out shift reg, precisely, meaning it's probably taking a bitstream in and using it to drive all the LEDs at once - http://www.datasheetcatalog.com/datashe ... 164N.shtml) http://www.psychsoftware.org/stuff/temp ... 020332.JPG

Save copies of the photos if you want them; I'm not going to guarantee perma-hosting, at least not in that location.

There's certainly nothing big enough to be a cop888 in any of those locations. I seem to recall reading somewhere that the brain chip was indeed in the glove, which may mean it is on the backside of the D-pad PCB.
nocash
Posts: 1405
Joined: Fri Feb 24, 2012 12:09 pm
Contact:

Post by nocash »

Many thanks for uploading the photos!

Yes, the COP should be 44pin SMD chip on the control-pad board; since it's SMD, one can't see solder pads on the PCB-back-side photo that I've found.

As how I understand the COP pinouts: The microwire feature is used to receive serial data from NES. And in the opposite direction, the 4021 parallel-in serial-out shift register is used to send serial data to NES.

And there's a 8x3 keyboard matrix; 3 outputs, and 8 inputs; ie. the thing outputs a LOW level on one row, and checks if any column inputs go LOW (=button is pressed). The pull-ups are just there to drag the columns HIGH if the button isn't pressed (so there's just logic LOW and HIGH on that pins, no analog stuff).

For the microphones, I'd have expected 3 inputs (though Tim has listed only two pins going to "near receivers") (but I'd guess there might be one more microphone pin somewhere).

The whole NES data, LED data, and MICrophone data is squeezed through the 9pin connector on the junction box: Two pins for VCC and GND, three pins for NES connector, and presumably three pins for the microphones. That would would leave only 1 spare pin. Should be pretty impossible to control the six LEDs through that 1 spare pin...

That's why I was suggesting that 4021 shift-register (and the wires in the cable) are shared for both COP-to-NES and COP-to-LED. So, the 4021's serial-output is wired both to NES, and to the 74LS165's serial-input on the LED board (and the 74LS165's parallel output then wired to the LEDs).

With "Error Flags" I meant you "occlusion" byte, which would be the last byte transferred (If you are doing it the way as Super Glove Ball). So, in analog mode the LED bits should blink between 3Fh (1 frame; no errors) and FFh (2 frames, not ready).

Bit0-3 of that value would be the four "direction-LEDs", bit4-5 would be "start/select" (which have no LEDs), and bit 6-7 would be the two "button LEDs".

So, with the 3Fh/FFh values, the upper four LEDs should glow permanently, and lower two LEDs should flimmer (which may look as they are dimmed to medium brightness). At least, I'd think that it'd look like so in Glove Ball. EDIT: Or more likely vice-versa: FFh=All LEDs OFF, 3Fh=Lower 2 LEDs ON.

During the transfer, all LEDs would blink more or less "randomly" while new data is shifted-in, but that should occur only for very short moments, probably one won't see that at all.

Ah, okay, didn't knew that 3rd OBJ was intended for in your test program. I don't have transfer "timeouts" yet emulated, so packets in my emu doesn't run in sync with the test program - which caused the 3rd OBJ to jump randomly. Sorry for the confusion.
LoneKiltedNinja
Posts: 63
Joined: Mon Jul 07, 2008 7:40 pm

Post by LoneKiltedNinja »

For the microphones, I'd have expected 3 inputs (though Tim has listed only two pins going to "near receivers") (but I'd guess there might be one more microphone pin somewhere).
If they're going to the LM324s in the junction box proper, those receiver pins may be the serial send/receive pins for communication with the NES. This also makes sense because the WR# write pin is reported as tying directly to a LM324 pin, while the RD# read pin is reported as tying to likely some Resistor/Capacitor buffer before entering digital world. The COP888 does have direct serial I/O capacity. And in fact, certain write-ups describe that particular series of chips as being pathologically serial, even in the way it reads instructions from its own internal ROM.

I also have some doubts that the designers would have necessarily allocated pins for all 3 mics and 2 speakers in parallel given that they only need one speaker/mic pair at a time. I'd suspect the speakers are in the "from top of glove" pin set (in fact... XMTR is probably [trans]MiTteR). The microphones are a little bit of a puzzle, but one which may be illuminated if we ask why 8 op-amp 'gates' are needed for 2, or at most 3, lines communicating with the NES, particularly when each mic PCB has its own dual op-amp chip. My analog EE is very rusty, but I could see a possibility of them hacking together a primitive multiplexor or delay circuit to serialize the mic returns if there's no obvious parallel pin set on the COP888.
The whole NES data, LED data, and MICrophone data is squeezed through the 9pin connector on the junction box: Two pins for VCC and GND, three pins for NES connector, and presumably three pins for the microphones. That would would leave only 1 spare pin. Should be pretty impossible to control the six LEDs through that 1 spare pin...
I have seen no indication that the LEDs are programmer-accessible; read or write. They seem to be automatically operated. But with the serial-to-parallel chip boxed in on the LED PCB, one pin could very easily control all LEDs if the LED state is determined on the microcontroller.
With "Error Flags" I meant you "occlusion" byte, which would be the last byte transferred (If you are doing it the way as Super Glove Ball). So, in analog mode the LED bits should blink between 3Fh (1 frame; no errors) and FFh (2 frames, not ready).

Bit0-3 of that value would be the four "direction-LEDs", bit4-5 would be "start/select" (which have no LEDs), and bit 6-7 would be the two "button LEDs".

So, with the 3Fh/FFh values, the upper four LEDs should glow permanently, and lower two LEDs should flimmer (which may look as they are dimmed to medium brightness). At least, I'd think that it'd look like so in Glove Ball. EDIT: Or more likely vice-versa: FFh=All LEDs OFF, 3Fh=Lower 2 LEDs ON.

During the transfer, all LEDs would blink more or less "randomly" while new data is shifted-in, but that should occur only for very short moments, probably one won't see that at all.
If anything, it might make sense if the LEDs reflected every single byte of data output by the glove to the NES, not just one particular "final" field. That's closer to the actual appearance of the LEDs. Very rarely is one lamp ever solidly illuminated in raw mode; I've only ever seen a combination of solid and flicker when I've gotten into really unorthodox configurations with more static garbage fields than dynamic data.

But if the glove's output packets are splitting off to drive the LEDs, that's even more evidence that the output packets are serialized by the time they hit the junction box, as nothing in the junction box or frame would serialize the data prior to the LED serial-to-parallel chip.

Reexamining my photos, it's fairly clear that the wiring through the frame is

Box 1:
- Hot (red)
- Ground (black)
- Mic1 data (brown)

Box2:
- all Box1
+ Mic2 data (gray)
+ LED data+clock (green/blue)

Box3:
- all Box1
- all Box2
+ Mic3 data (mic data likely recolored yellow/orange/pink on exit; not sure which is which without re-opening the box and looking at the trace side)

From there, it would probably be easy enough to look at the traces on the junction PCB to see if blue/green share any connections with the to-NES port or figure out where yellow/orange/pink go. I may try that at some point, but it sounds like you could really stand to get your own glove :)
nocash
Posts: 1405
Joined: Fri Feb 24, 2012 12:09 pm
Contact:

Post by nocash »

one pin could very easily control all LEDs if the LED state is determined on the microcontroller.
The shift register (on the LED board) needs Data and Clk (two pins).
If anything, it might make sense if the LEDs reflected every single byte of data output by the glove to the NES, not just one particular "final" field.
Yes, exactly. Just what I was saying. But you would barely see them (blinking only for very short moments), so only the final ones (which last for longer time) should be visible.
That's closer to the actual appearance of the LEDs. Very rarely is one lamp ever solidly illuminated in raw mode; I've only ever seen a combination of solid and flicker when I've gotten into really unorthodox configurations with more static garbage fields than dynamic data.
What's with the Super Glove Ball game? That should be the normal/official case... I couldn't find any videos or descriptions how it should look like.

But I would stay with my theory: The two button LEDs should be flimmering, the four direction LEDs should be off - unless you cover the speakers/microphones, then some of the direction LEDs should flimmer, too (in respect to the lower 4 occlusion bits).
it would probably be easy enough to look at the traces on the junction PCB to see if blue/green share any connections with the to-NES port or figure out where yellow/orange/pink go.
What traces? You've uploaded only component side photos. But, following traces on photos would be a pain anyways (easiest would be using a multimeter to check for 0 ohm connections).

Yeah, having a glove at hand would be nice... and the NES CompuTrainer from RacerMate... and all the other odd NES controllers. But I don't have the money and storage to buy all that stuff.
User avatar
Roni
Posts: 114
Joined: Fri Sep 26, 2008 7:55 pm
Location: Montreal
Contact:

Post by Roni »

Well it seems that the power glove does have ring finger control, in addition to thumb, index and middle fingers, but the middle one on mine is broken. (no response, FingersByte bits 2-3 stuck at "10")

It's probably likeky that the flex sensor in these gloves degrades over time or was just fragile. I wonder if it can be repaired.

So what's the verdict on the reads? Has it been determined if the glove can send a full packet of reliable data in less than three NTSC frames?
nocash
Posts: 1405
Joined: Fri Feb 24, 2012 12:09 pm
Contact:

Post by nocash »

Less than 3 frames? No, I think the latest info was 4 frames, and sometimes 3 frames (see http://nesdev.com/bbs/viewtopic.php?p=92301#92301) the only later news was that there is the "ready byte", if you are polling it once per frame then you should get the possible rate, without getting into unstable situations. If 3 or 4 frames is too slow for your purposes - you could try to poll it more than once per frame; and maybe receive data every 2.5 or 3.5 frames.

No idea if it's possible to repair the flex sensors, how they do look like, and if one can buy replacement parts. Is it difficult to disassemble them?
If they are actually broken then you are probably in trouble - soldering would probably melt them, and conductive silver would probably break as soon as you flex the fingers. If you are lucky, then it's just a dirty contact between the wire & sensor.
Bavi_H
Posts: 193
Joined: Sun Mar 03, 2013 1:52 am
Location: Texas, USA
Contact:

Re: the Power Glove

Post by Bavi_H »

I don't have a Power Glove, but was reading about it today, and found the technical information in this thread very interesting.

One additional thing I'm interested in is if it's possible to manually enter advanced programs on the glove's keypad.

In the Power Glove manual, the Problems and Solutions (page 34) says (emphasis mine):
P: I would like to use different motions with the game I am playing.
S: The glove comes with 14 different programs, each with different moves. [...] Special games like Bad Street Brawler have more programs on them. There will also be special "editing" codes published in magazines for more games.
This makes it sound like advanced programs could be manually entered on the glove keypad.

I think it is unusual the glove requires you to press ENTER twice to load a program. Wouldn't one ENTER press suffice? I suspect there's a hidden reason two ENTER presses are required. Perhaps you are able to enter advanced programming steps after the first ENTER press and the second ENTER press finally ends the programming mode.

Perhaps someone with a Power Glove would be interested in testing if undocumented key sequences in the programming mode have any effect...
LoneKiltedNinja
Posts: 63
Joined: Mon Jul 07, 2008 7:40 pm

Re: the Power Glove

Post by LoneKiltedNinja »

Yeah... I haven't done much with the PowerGlove recently from a research standpoint, although there will be a new release of Nesglovphone with one or two new features as soon as I get around to doing a demo recording. These days, if anything, my focus is shifting to Virtual Boy ( http://www.planetvb.com/content/downloa ... stsvb.html ), but that's a discussion for another thread.

But so far as I remember, the bottleneck is not so much on sending the data- you can poll it to your heart's content just like any input device- the glove's internals simply can't build new packets instantaneously, so if you ask it to put a lit of data in the packet, you need to give it sufficient time to get ready. If you want it to be ready faster, ask for fewer data fields. I have no recollection of how/whether there was a "ready" byte and I'm too lazy to review the whole thread, but it would make a lot of sense if one does exist, and if so, yes, the process would be along the lines of: read header/ready byte -> check "ready" state -> if ready, read more (data packet) bytes.

I could conceive of alternate explanations for needing to press Enter twice to change programs- early digital state machine systems were not always the prettiest hacks- but the notion of user-programmability is intriguing. There is, with certainty, some small microcontroller in the glove, and my experiments with initialization codes seemed to suggest that there were swaths of data in there not necessarily related to normal intended operation. The riddle which may never be answered is whether the raw data "modes" I discovered were intentional-but-not-yet-documented, or simply artifacts of deterministic program/junk data that was never intended to be indexed into. That might help clear up whether "programming" modes via the keypad were a fully flexible specification system, or just a hypothetical back-door to get at similar deterministic alternate behavior that wouldn't be worth documenting until someone wanted/needed it.

As to repair, I now have 2 Gloves (the one that came with my full setup, and a second which, in isolation, had likely long since been relegated to a costume prop), but I'm still not brave enough to do a teardown until one fails so absolutely that I can't use it for anything else. The sensors are some manner of thin sheet laminated into the rubber fingers of the glove, so repairing/replacing them would be impossible without destroying the glove as-such (which is not to say that after surgery, you might not find another fabric glove to bond the electronics back onto). The access screws for the rectangular block on the glove (the "gamepad"/keyboard) are accessible enough, but that's not where the flex sensor leads likely originate, and the screws to get into the oblong emitter nodule (assuming it's not just glued together) are on the far side of the glove fabric. I'm pretty sure I've seen a few pics of both sets of internals, but didn't glean any earth-shakingly useful information from them at the time.
Psych Software- failing to profit from retro/indie development since before it was cool
http://www.psychsoftware.org
slobu
Posts: 276
Joined: Tue Jul 12, 2011 10:58 am

Re: the Power Glove

Post by slobu »

Seems to me the boys that played with VR and attaching the PowerGlove to the PC par. port would have figured out the mysteries. I wonder if any good FAQs still exist from those days..
LoneKiltedNinja
Posts: 63
Joined: Mon Jul 07, 2008 7:40 pm

Re: the Power Glove

Post by LoneKiltedNinja »

BIG AND I MEAN HUGE NEWS
When poking around for resources on the Miracle Piano, I stumbled across the website of Paul White, one of the retired original engineers on the Miracle and Power Glove. After striking up a conversation, he was willing to share the recollections and resources he had accumulated.
The power glove used a special control script to convert various gestures into Nintendo button presses. I think you would punch in the appropriate code on the PG keypad to select the gesture template for the game you wanted to play. The PG to Nintendo interface was simple, like a button controller, so standard games would work without modification. As I see you know, there was also the raw mode, where special software on the Nintendo side could read the various glove parameters directly.
Of course, that isn't too new. What is new and merits a big, long,
drumrollllllllllllllllll....
I found some nice Power Glove information for you. The source code and
various utilities are available here:

[attached to post]

The PG uses a National Semiconductor COP888 microcontroller.
You may be able to find info about the assembly language syntax on the
web. If not, I may still have some data books around somewhere.

I haven't tried running the NGL.EXE program, but I seem to recall it has
something to do with generating gesture templates, or some such.
ASM888.EXE COP888 assembler
HEXLM.EXE Hex to Load Module utility
LMHEX.EXE Load Module to Hex utility
NGL.EXE Nintendo Glove Language utility ?
PG.MAC Main Power Glove source
PGCON.INC Power Glove constants
PGMEM.INC Power Glove memory definitions
PGTEMPL.INC Power Glove template include file
COP888.INC COP888 header file
Most of the assembly code is pretty straightforward reading, with the possible exception of the "X" command. As I recall, the COP processor doesn't have a STORE command as such, but it does have an eXchange command that swaps the accumulator with the specified memory location.

Unfortunately I don't have copies of the PG schematic, because it wasn't created on my computer. I think I must have worked from a printed copy, which I no longer have. There are references in the code to some "high voltage" stuff. There was an output pin connected to an inductor/diode/capacitor circuit, and it had to be pulsed periodically to generate a high voltage for the piezoelectric ultrasonic beepers. They needed a fairly high voltage to get loud enough to provide a reasonable range. You can probably figure out the rest.
Yes, to all initial indications, this is THE SOURCE TO THE EXECUTABLE CODE EMBEDDED ON THE ONBOARD PROCESSOR OF THE POWER GLOVE. I say "to all initial indications" because I don't have time right now to fully investigate, but the source and comments look believable, and if it is, this is huge and ought to crack the whole apparatus wide open to proper emulation.

* editorial note: being in software development myself, I could easily see how this might be an earlier or later version than actually ended up on the Glove if it's just the copy that Paul dropped on a floppy for his own collection. Still, it's NaN% more than I think we've ever had to work with, and odds are since he did the actual coding and had his hands on the source most readily, even if it isn't the shipped build, it's pretty darn close and ought to at least be concretely testable against actual Glove behavior.
Attachments
PGarchive.zip
PowerGlove onboard controller source & tools
(96.64 KiB) Downloaded 272 times
Last edited by LoneKiltedNinja on Wed Aug 27, 2014 6:50 pm, edited 3 times in total.
Psych Software- failing to profit from retro/indie development since before it was cool
http://www.psychsoftware.org
LoneKiltedNinja
Posts: 63
Joined: Mon Jul 07, 2008 7:40 pm

Re: the Power Glove

Post by LoneKiltedNinja »

...and of course BATCAVE is the re-entry point to BATLOOP. Makes perfect sense. And ye gods this is well-commented.

I have not experienced this much happy while reading ASM since digesting the Virtual Boy sacred scrolls :D
PG.MAC wrote: ; Set up upload pointers
;
BT:
LD A,
RLC A ; Locate bitmap of upload values in template
AND A,#01E ; mask all but gesture byte count
INC A ; Add 2 for template header and logic byte
INC A ; count
ADD A,#TEMPLATE
X A,B
LD A,[B+] ; Save bitmap in GSTAT
X A,GSTAT1
LD A,[B+]
X A,GSTAT2 ;
; Build list of data addresses following logic in template
LD A,B ; RAM address in B is transferred to X
PUSH A
X A,X ;
POP A
X A,GBASE ; Save pointer for upload routine to use

LD CREG,#0 ; Initialize bit counter
BATLOOP:
LD A,CREG
JSR GBX ; Get B pointer to GSTAT1 or 2 and A=bitmask
AND A,
IFNE A,#0
JP PUTONE
BATCAVE:
JSR INCREG ; Increment CREG
IFNE A,#15 ; (value of CREG before incrementing) = 15 ?
JP BATLOOP

LD A,#0FF
X A,[X] ; Put FF marker at end of list
JMP ZSTAT

PUTONE: ; Put a pointer in the table
LD A,CREG
ADD A,#L(IATABLE)
LAID
X A,[X+]
JP BATCAVE
Psych Software- failing to profit from retro/indie development since before it was cool
http://www.psychsoftware.org
User avatar
thefox
Posts: 3134
Joined: Mon Jan 03, 2005 10:36 am
Location: 🇫🇮
Contact:

Re: the Power Glove

Post by thefox »

Pretty cool! The tools run fine in DOSBox.
Download STREEMERZ for NES from fauxgame.com! — Some other stuff I've done: fo.aspekt.fi
Bavi_H
Posts: 193
Joined: Sun Mar 03, 2013 1:52 am
Location: Texas, USA
Contact:

Re: the Power Glove

Post by Bavi_H »

Previously:
  • The Power Glove manual mentions "special editing codes", maybe pressing something between the first and second Enter press would do something?
  • The source code for the Power Glove onboard processor executable code
I immediately looked over the source code when it was posted, and it does suggest some editing abilities are available from the Power Glove's keypad. I had wanted to re-examine the code to make sure I didn't make any mistakes, but I haven't had time. For now, here are some notes from when I last looked at it (September 2014).

In the descriptions below, n is a decimal digit, and x, y, and z are hexadecimal digits. [ ]* means you can press the enclosed sequence 0 or more times. To enter hexadecimal digits, use the following buttons:

digit: A B C D E F
button: A B Left Up Down Right


Press Prog to enter the program mode. In the program mode, you can press:
n Enter
Load template n.

n n Enter
Load template nn.

A x Enter y y [z z]* Enter
Insert a gap of x bytes starting at offset yy in the template definition bytes, then begin overwriting with bytes zz.

B x Enter y y [z z]* Enter
Delete x bytes starting at offset yy in the template definition bytes, then begin overwriting with bytes zz.
You can press Prog to clear the last digit (or byte? need to check the code again to confirm).

You can chain load and edit commands one after another. After your last command, press Enter a second time to exit the program mode.

Also, you can press Prog Prog Prog to reset all. (That is, press Prog to enter programming mode, then Prog Prog to reset all.)


I may have made some mistakes interpreting the code. And we aren't sure if the code is the same as used on production units.
LoneKiltedNinja
Posts: 63
Joined: Mon Jul 07, 2008 7:40 pm

Re: the Power Glove

Post by LoneKiltedNinja »

A new potential side project led me back to my old PG notes, they in turn led me more properly into the PG.MAC source code, and while I didn't find answers to the raw-mode questions I had, I did conclusively find the section related to parsing the input stream for custom joypad processing. Nocash got remarkably close in his analysis; I can only really provide confirmation.

Omitting the very first header byte, packet length, which (perhaps naturally) does not appear to be part of the TEMPLATE data proper, the structure does appear to be a header byte preceding N 16-bit gesture definitions, followed by a second header byte and N 8-bit gesture-logic statements.

Specifically,

Line 2041 of PG.MAC begins what is likely the parsing section for what were previously termed the “16-bit opcodes”, referring to a “gesture header byte” and a “gesture data byte”

I am assuming TEMPLATE is the address of the start of the received message structure.

First, an initial gesture address GADDR is computed (1 byte after TEMPLATE) and cached.

Then, the contents of address TEMPLATE are loaded, masked with 0x0F, and interpreted as the count of gestures to follow; consistent with earlier reverse-engineering of the “16-bit Block Header.”
If >0, this count is stored in NYREG and gesture loop counter GNUM is initialized to 1.

Looping over an incrementing GADDR, 2 bytes are read (cached by address) for each gesture entry:

The first byte is a header and gets masked by 0x3F prior to processing. It would appear this mask is used to ignore “last state” and “1-shot” flag bits.
The second byte is a data byte; cached in X.

If the entire gesture header (after the 3F mask) is 0x00, this is a noop (“A gesture type of 00 would be flex with no fingers set in the bitmap”).
otherwise, the header byte is masked with 0x03 and is identified as one of
00b = flex-only
01b = position
10b = orientation
11b = “D. POSITION” (unknown term)

Values of 0 and 2 (00b and 10b) are explicitly tested to jump to respective GFLEX and GORIENT subroutines; 1 and 3 (01b and 11b) fall through, caching some convenience variables before entering the position subroutine GPOSITION.

GPOSITION interprets the cached X data byte as a “vector” lookup. It RLCs the value (presumably arithmetic rotate-left with carry) to double it, then masks it with 0x06, apparently to isolate vales (in the 2 masked-in bits) of
00b = X-axis
01b = Y-axis
10b = Z-axis
11b = don’t-care
before adding the masked value to a base address, using the resulting address (by storing it in B and then loading from the addresses contained in “B+” (postincrement) and B) to look up what appears to be the current and old position vectors (on that axis?)
Flow then JSRs into GADB, with a comment indicating that the data pointer in B is to the gesture header byte (presumably upon return, as it is not so going in).
The header (data at address B) is bit-tested (REL = bit 2, according to PGCON.INC) to determine if an absolute or relative gesture is being specified; relative jumps to subroutine RELATIVE, absolute falls through.

ABSOLUTE evaluation logic appears, in a nutshell, to:
- check whether the gesture data byte is direction-consistent with the current ongoing direction vector (CURR) sign, aborting/resetting detection otherwise
- take the absolute value of the current vector (CURR)
- shift-mask the data byte (X) down to 6 bits even: 2 arithmetic right rotations followed by a mask with 0x3E, retaining 2 of the top 4 and 3 of the bottom 4 bits
- test/return if the processed data value is greater than the CURR ongoing gesture vector

subsequent comments/subroutines indicate that only the largest single-axis (x/y/z) gesture so-detected will return as true/triggered, and only if it was previously false.

RELATIVE evaluation logic is trickier, and appears to
- look up a “turning point” (cached in TURN) by first masking the data byte (X) by 0x03 to get an axis code (as before) then adding that to TURNX (presumably a table address), and reading the data in the resultant address (via B)
- subtract the TURN point from the CURR current vector (cacheing the result in CMT)
- GADB-lookup the header and shift-mask it into a “RESET” value: 1 arithmetic right rotate, mask with 0x1C to “Keep 5 bit magnitude, 3 bit resolution” and cache it in CREG. So apparently the original header was a 2-bit requested data type and a 3-bit reset value of still-ambiguous function.
- perform a sophisticated walk down a table of tristate gesture component definitions, continuing to track the gesture I believe so long as the current gesture is positively matched (PTRUE) and the next gesture is not yet evaluated (RFALSE) as opposed to definitively nonmatched (NTRUE); PTRUE and NTRUE being determined by +/- difference from SET (X data value, processed to 6-bit similarly to before)
- reset the turn point for detection if the current vector (C===CURR) and turn point (T===CMT===CURR-TURN) both exceed the last vector(?); fail if the difference between the current vector and turn point exceeds the reset threshold CREG as previously computed. Meaning the original header was a 2-bit requested data type and a 3-bit reset sensitivity, or to borrow the format of subsequent comments:

Code: Select all

;
; Motion gesture Header byte:
; Last	/1 shot	/ RESET (3)	/RELATIVE (1)	/ 0   / 1   ;
;
; Data byte:
;  SET (5)	/  DIRECTION / AXIS (2)	/
;


Finger gesture processing is probably best summarized by the big comment

Code: Select all

;
; Flex gesture Header byte:
;             <-- second finger  <-- first finger <--
; Last	/1 shot	/THUMB	/INDEX	/MIDDLE	/RING	/ 0	/ 0	;
;
; Data byte - Set bitmap:  2nd finger / first finger
;  3	/  2	/  1	/  0	/  3	/  2	/  1	/  0	/
;
; Finger map specifies 1 or 2 fingers.  If both are true,
; gesture becomes true.  If either are false, gesture becomes false.
indicating a system of looking for “bitmap” levels on either 1 or 2 fingers and returning an AND match

likewise with orientation

Code: Select all

; Orientation gesture Header byte:
;
; Last	/1 shot	/	/	/	/	/ 1	/ 0	;
;
; Data byte:
;
; End position 			/ Start position 		;
;
which match nocash’s analysis rather precisely.

The only mystery is whether the single 0x0800 entry present in the gesture block of the “raw mode” packet is anything more significant than a vacuous middle finger.


Parsing then proceeds to a “Gesture logic” (line 2499) statement parser/processor which begins with a check of bit 7 of (presumably) what we’ve been calling the 8-bit section header, aborting back to the main loop if true (meaning the “extra 6 bytes” nocash observed are doubly confusing…)

From here (line 2506), things begin to get crazy, appearing (as nocash surmised) to be a whole metalanguage of “logic statements,” “indent states,” truth tables, processes, etc., implemented in assembly, to act on bytecode, all for the purpose of chaining the defined gestures (16-bit opcodes) into evaluation sequences to yield true/false button states.

The 8-bit opcodes appear to reduce to control codes in the low 3 bits of the high nybble as defined

Code: Select all

LOGJMP:			; Logic statement jump table
	.BYTE	L(LTMPN)	; 0
	.BYTE	L(LIFG)		; 1
	.BYTE	L(LTIFG)	; 2
	.BYTE	L(LEIFG)	; 3
	.BYTE	L(LANDG)	; 4
	.BYTE	L(LORG)		; 5
	.BYTE	L(LENDIF)	; 6
	.BYTE	L(LELSEDO)	; 7
Those 8 control codes jump to handlers with header comments as follows:

LTMPN

Code: Select all

; Load template N now, then restart.
editorial note: “template” appears to be the internal term for a set of gestures + logic, or in our nomenclature, 16-bit + 8-bit opcodes

LIFG

Code: Select all

;
; "IF (G)"
; evaluates the state of gesture G and sets the state
; of the current indent level accordingly if the state of the
; previous indent level is true.
;
LTIFG

Code: Select all

;
; "THEN IF (G)"
; increments the indent level if the indent flag
; is clear and then performs an IF (G)
;
LEIFG

Code: Select all

;
; "ELSE IF (G)"
; decrements the indent level and clears the indent flag.
;
LANDG

Code: Select all

;
; "AND (G)"
; evaluate the state of gesture G and perform a logical
; AND with the state of the current indent level
;
LORG

Code: Select all

;
; "OR (G)"
; evaluate the state of gesture G and perform a logical
; OR with the state of the current indent level
;

LENDIF

Code: Select all

;
; "ENDIF"
; decrements the indent level
;
LESLEDO

Code: Select all

;
; "ELSE DO"
; pre-decrement the indent level, set current state,
; post-increment the level and set the indent flag.
;
For standard statements (high nybble 0-7), the low nybble is parsed by the EVAL subroutine, which farms the actual parsing off down another rabbit hole, but it looks like it contains a 1-based (1-16 range) index for the 16-bit gesture entry to operate on. Actual parsing process is
- load the byte into A
- mask in the low nybble (by AND with 0x0F)
- subtract 1
- load into B the address of either a (presumably) gesture evaluation state array (GSTAT1) if A<=7 or status flags (GSTAT2) if A>7
- mask down to the low 3 bits (AND 0x07)
- use headache-inducing indirect lookup magic to compute 2^A and store it back in A
- use A as a mask into the data at B (AND A,) and return whether that result is true (0xFF) or false (0x0)

A value of 0 in the low nybble appears to just set a flag to trigger a beep.

A value of 8 or higher in the high nybble indicates THEN (0x8_-0xB_) or ELSE (0xC_+) commands, which appear at first glance to conditionally increment the “indent” level and proceed based on the truthiness of the previous statement or decrement the “indent” level and update the current truthiness consistent with prior and current level results. They also both flow through to a further DoAction handler which calls out that 0xB_ or 0xF_ statements invert the referenced gesture. Subsequent lines seem to indicate this is an inversion of the gesture’s result status or corresponding output bit/byte.

The low nybble, if nonzero, triggers actions based on previously defined gestures.

If >0x08, special handling (DoSpecial) is invoked. This turns out to be another straightforward jump table:

Code: Select all

SPECJP:				; Jump table for special actions
	.BYTE	L(EndAction)	; 9
	.BYTE	L(CTR1CE)	; 10
	.BYTE	L(CentAll)	; 11
	.BYTE	L(CentX)	; 12
	.BYTE	L(CentY)	; 13
	.BYTE	L(CentZ)	; 14
	.BYTE	L(ResAct)	; 15
for noop (EndAct), conditionally resetting everything if it hasn’t been done before (CTR1CE), centering All/X/Y/Z axes (Cent*), or resetting the flex, center-once and beep flags (ResAct).

Otherwise, the corresponding button-bit of the NES joypad is selected (modulo a swap flag which can cause A and B (0x07 and 0x08) to be swapped) and cached on the stack. The original instruction’s bits masked by 0x30 are then checked to see if the action being defined should be “pulsed 2” (0x20), “pulsed 1” (0x10) or continuous (0x0). I.e., out of the original high nybble, which by now we have determined to be on the 0x8_-0xF_ range, the codes 0x8_ and 0xC_ are continuous actions, 0x9_ and 0xD_ are “pulsed 1”, and 0xA_ and 0xE_ are “pulsed 2”. The remaining 0xB_ and 0xF_ were covered earlier in the inversion clause.


So basically, again in a representation akin to other source comments,

Code: Select all

;
; Logic Statement
;  EXT	/  STATEMENT (3)			/  OPSET	/  OPERAND	(3)		/
;
If EXT is 0 then STATEMENT is a basic control command, and based on OPSET, the command is evaluated with the current value of either the gesture (OPSET=0) or status flag (OPSET=1) indexed by OPERAND.

if EXT is 1 then STATEMENT is an action command as
000b = THEN continuous trigger
001b = THEN 1-pulse trigger
010b = THEN 2-pulse trigger
011b = THEN inverted trigger
100b = ELSE continuous trigger
101b = ELSE 1-pulse trigger
110b = ELSE 2-pulse trigger
111b = ELSE inverted trigger

For further help interpreting, it may be useful to consult a COP888 datasheet. I found one at http://www.engineering.uiowa.edu/sites/ ... 010830.pdf
Last edited by LoneKiltedNinja on Fri May 29, 2015 8:39 am, edited 2 times in total.
Psych Software- failing to profit from retro/indie development since before it was cool
http://www.psychsoftware.org
Post Reply