It is currently Sun Mar 18, 2018 6:56 am

 All times are UTC - 7 hours

 Page 5 of 5 [ 64 posts ] Go to page Previous  1, 2, 3, 4, 5
 Print view Previous topic | Next topic
Author Message
 Post subject: Re: the Power GlovePosted: Sat May 09, 2015 3:41 pm

Joined: Sun Mar 03, 2013 1:52 am
Posts: 104
Location: Texas, USA
LoneKiltedNinja wrote:
01b = position [...]
11b = “D. POSITION” (unknown term)

It stands for "dominant position". Both 01 and 11 are handled by the same flow. The bit that is different between them is checked later on:
Code:
SetPosition:
IFBIT   1,[B]           ; Is this a vector dominant gesture ?
JP      VDTYPE          ;     (absolute only) (??)

JP      NG6

; Vector dominant position:
; Gesture can only BECOME true if the vector is the largest
; of the three vectors (X, Y, Z), AND the gesture is currently false.
; If vector is NOT dominant, it will not become true.
;
VDTYPE:
LD      A,[X]           ; Check this gesture's vector (X, Y or Z)
AND     A,#03           ; Mask unneeded bits
IFNE    A,DOMVEC        ; Does the vector type match the dominant one ?
JMP     NextGesture     ; Do nothing if no match.
NG6:
JMP     SetGesture

LoneKiltedNinja wrote:
positively matched (PTRUE) [...] not yet evaluated (RFALSE) [...] definitively nonmatched (NTRUE)

Here's what positive and negative mean:
Code:
forward   up
-z     +y
_
|\ ^
\|
left  <--+-->  right
-x      |\     +x
v _|
backward
down     +z
-y

The absolute position gestures seem to be testing the distance you've moved from the "center" point. (You set the center point with the Center button.) The relative position gestures seem to be testing the distance you've moved from a "turning" point.

A relative position gesture always takes two gesture positions. This gesture test is always testing both the positive and negative directions of the requested axis. So you always get results for both up AND down, or right AND left, or backward AND forward. (The first position contains the relative gesture definition and returns the "positive" result bit. The second position contains the no-op code and returns the "negative" result bit.) PTRUE means only the positive direction was true. NTRUE means only the negative direction was true. RFALSE means the entire relative gesture was false.

LoneKiltedNinja wrote:
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.,

The logic parsing source code is difficult to understand. As an alternative for now, I'm examining what the indented logic steps look like in NGL.EXE to help imply what the logic parsing in the glove does.

I'm using DOSBox and running NGL.EXE inside of it. Here's a guide to NGL.EXE: ngl.txt

Here are the basic steps to investigate the logic indentation:
Press Alt+L to go to the Logic page.
Press Left or Right to change lines on the right side of the page.
Press Plus or Minus to change logic items.
If a gesture is needed, press Up or Down to highlight it on the left side and Enter to choose it.
If an action is needed, press Enter to cycle through the actions.
Press Page Up to refresh the indentation on the first page or return back to the first page.
Press Page Down to go to the second page or refresh the indentation on the second page.

LoneKiltedNinja wrote:
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.

I looked around the code again. I think the gesture definitions are evaluated the same way in both the "glove" mode and the "joystick" mode. As you say, the \$0800 gesture will always return false. (It's checking the middle finger, but with no flex bits set to check, it will always return false.) However, when you start the "glove" mode, it looks like you could send other multiple gestures, and the the 7th and 8th bytes of the return packet will be a bit field of the gesture results.

Here is the place in PG.MAC that defines the addresses sent in the return packet:
Code:
IATABLE:                ;(allow space here for 16 values)
.BYTE   XABS
.BYTE   YABS
.BYTE   ZABS
.BYTE   ROTATION
.BYTE   FLEXMAP
.BYTE   SWR0H
.BYTE   GSTAT1
.BYTE   GSTAT2
.BYTE   RVALID
(If you request bytes after the end of this table, I guess the code after this table will be interpreted as addresses.)

Here are various lines from PGMEM.INC that describe these addresses
Code:
XABS            =       00C     ; Current horizontal position
YABS            =       00E     ; Current vertical position
ZABS            =       010     ; Distance from screen
ROTATION        =       012     ; 0 - 12 (new in LSN, old in MSN)
FLEXMAP         =       02C     ; 2 Bit flex current positions
SWR0H           =       0F6     ; History - last switch code
GSTAT1          =       0F0     ; Gesture status map 16 bits
GSTAT2          =       0F1
RVALID          =       05F     ; Used only in glove mode

LoneKiltedNinja wrote:
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 PG.MAC:
Code:
LOGIC:

IFBIT   7,TEMPLATE      ; Is this a glove mode program ?
JMP     MAINLOOP                ; Return from COMPUTE subroutine

I think TEMPLATE is the beginning of the template, so it's checking the high bit of the 16-bit section header, which, as indicated in the comment, means it's a "glove mode" program. As we know, the 8-bit section of a glove mode template contains 2 bytes used to request which bytes to send back, so the code here is skipping the logic parsing.

nocash's everynes.htm wrote:
Finally, "PROGRAM E" has EXTRA SIX BYTES after the 8bit opcode area (indicated in bit7 of the 8bit Area's header). The bytes there are 00h,00h,00h,00h,57h,57h, purpose is unknown.

When using the glove, there are seperate turbo settings for A and B that you can enable or disable and change the speed for. If the program template you load only needs to send normal button presses, it will be set up to obey any turbo settings you had specified. (The button presses are specified to use turbo, but with no turbo settings defined in the program, it will use whatever you had set up.)

However, some of the template programs have a repeated button press as one of the outputs. In this case, the template loads its own turbo settings. In these programs, the normal button presses are hard coded as normal button presses, and the repeated button presses use the program-specified turbo settings.

In the templates shown in PGTEMPL.INC or when you export a template in NGL.EXE, the high bit of the logic header indicates two bytes of turbo information will follow the logic. Based on exports from NGL.EXE, the format of each turbo byte is like this:
Code:
-e-rrrrr

e = enabled
rrrrr = rate 0 to 31

However, the "extra 6 bytes" in Program E start with four "00" bytes, then two turbo bytes. As best I can tell from reading the PG.MAC code, this is a bug, Program E should only have an extra 2 bytes on the end (\$57 \$57).

Edit: I looked at the code further to make sure I could back up the claim that Program E's "extra 6" should only be an "extra 2" and discovered I may be wrong.

When a template is loaded from ROM, the high bit of the logic header means there are 2 turbo bytes after the logic. The code checks for this and stores the turbo bytes in the proper places. (In PG.MAC, see LoadATemplate: and XTRA:) But when a template is sent from the NES, I couldn't find any code that checks the high bit of the logic header and stores the turbo bytes in the proper places.

It looks like the template is stored in address \$30 and can be up to \$30 bytes in size. And the turbo bytes are stored right after that in \$60 and \$61.

Various lines from PGMEM.INC:
Code:
TEMPLATE   =   030   ; 48 bytes_________
TEMPSIZE   =   030   ; Template size
PUL1RATE   =   060   ; pulse rate and mode
PUL2RATE   =   061

So it may be that Program E actually is correct. If you need to send a template from the NES to the glove that uses program-specified turbo, you may need to pad the template to the maximum size of \$30 bytes, then send the two turbo bytes, so they'll get written to the proper addresses.

Edit 2: Here are Program E's transmission bytes from nocash's post earlier in this thread:
Code:
brawler_tx_packet_06h:
db   32,69,04,0C,01,28,01,2C,1D,18,00,00,01,41,01,45
db   20,0C,42,84,98,B0,19,87,16,84,17,83,11,20,88,2F
db   82,C1,BF,62,70,22,44,81,33,45,82,18,98,00,00,00
db   00,57,57
You can see it contains one size byte, \$30 template bytes, then the 2 turbo bytes.

Top

 Post subject: Re: the Power GlovePosted: Fri May 29, 2015 9:05 am

Joined: Mon Jul 07, 2008 7:40 pm
Posts: 61
Bavi_H wrote:
LoneKiltedNinja wrote:
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.

I looked around the code again. I think the gesture definitions are evaluated the same way in both the "glove" mode and the "joystick" mode. As you say, the \$0800 gesture will always return false. (It's checking the middle finger, but with no flex bits set to check, it will always return false.) However, when you start the "glove" mode, it looks like you could send other multiple gestures, and the the 7th and 8th bytes of the return packet will be a bit field of the gesture results.

Here is the place in PG.MAC that defines the addresses sent in the return packet:
Code:
IATABLE:                ;(allow space here for 16 values)
.BYTE   XABS
.BYTE   YABS
.BYTE   ZABS
.BYTE   ROTATION
.BYTE   FLEXMAP
.BYTE   SWR0H
.BYTE   GSTAT1
.BYTE   GSTAT2
.BYTE   RVALID
(If you request bytes after the end of this table, I guess the code after this table will be interpreted as addresses.)

Here are various lines from PGMEM.INC that describe these addresses
Code:
XABS            =       00C     ; Current horizontal position
YABS            =       00E     ; Current vertical position
ZABS            =       010     ; Distance from screen
ROTATION        =       012     ; 0 - 12 (new in LSN, old in MSN)
FLEXMAP         =       02C     ; 2 Bit flex current positions
SWR0H           =       0F6     ; History - last switch code
GSTAT1          =       0F0     ; Gesture status map 16 bits
GSTAT2          =       0F1
RVALID          =       05F     ; Used only in glove mode

LoneKiltedNinja wrote:
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 PG.MAC:
Code:
LOGIC:

IFBIT   7,TEMPLATE      ; Is this a glove mode program ?
JMP     MAINLOOP                ; Return from COMPUTE subroutine

I think TEMPLATE is the beginning of the template, so it's checking the high bit of the 16-bit section header, which, as indicated in the comment, means it's a "glove mode" program. As we know, the 8-bit section of a glove mode template contains 2 bytes used to request which bytes to send back, so the code here is skipping the logic parsing.

Thanks for finding this. My brain was kinda fried after finding and digesting so much of the joystick mode code, so I hadn't gotten around to looking for the glove mode code again even though that's what I'd gone in looking for to begin with.

This is all consistent with my earlier empirical observations.
GSTAT1 and GSTAT2 always return 0 in the canonical glove-mode config, but I would be not at all surprised if it was possible to intentionally combine raw glove mode data and gesture evaluations. In my (now sorely out of date) devkit writeup, I noted what I termed "modes" at the time, which appeared (by varying the low nybble of the second init byte, what we now know as the 16-bit opcode count) to return different sets of data, some of which included gesture/flag-like behavior.

RVALID is simply 6 bits indicating whether each of the 3 receivers is reading pings from each of the 2 emitters.

And scanning the code for other uses of TEMPLATE (16-bit header byte), the structure now seems fairly conclusive:

Code:
;
;  glovemode   /  beep   / halt   / inhibit download   /  # gestures (4)         /
;

so the canonical \$C1 is saying "this is a glove-mode program with 1 gesture, beep when you start parsing it."
But based on the number of places I'm seeing bit 7 checked to abort further processing, there's definitely a bit more analysis needed of the extent to which gestures are processed in glove mode. On the one hand, glove mode does appear to have gesture return fields and I have empirically (if inadvertently and clumsily) demonstrated that a glove-mode init can take additional gesture defs and thereby return different/unusual data; on the other hand, there are multiple places in the code which appear, at first glance, to say gesture evaluations are aborted in glove mode...

The REAL magic, which looks increasingly less likely now that we know the return data table is hardcoded, would be if there was a way to specify in the config packet that the Glove doesn't even need to query/compute certain values. I'd love to be able to e.g. get just x/y position at 30 or 60 FPS rather than the whole table (or whatever subset I mask in) at 10-15fps.

_________________
Psych Software- failing to profit from retro/indie development since before it was cool
http://www.psychsoftware.org

Top

 Post subject: Re: the Power GlovePosted: Sat May 30, 2015 10:32 am

Joined: Sun Mar 03, 2013 1:52 am
Posts: 104
Location: Texas, USA
LoneKiltedNinja wrote:
on the other hand, there are multiple places in the code which appear, at first glance, to say gesture evaluations are aborted in glove mode...
I don't think so. Based on my interpretation of the code (see edit and attachment below), the main thing that glove mode skips is the logic steps.

There are two main parts of the template processing.

Gesture processing -- Tests for certain gestures and assigns a true or false values to the gesture flags.

Logic processing -- Examines the gesture flags using the "if-then" encoded logic bytes and determines what controller buttons to send (or to make a beep, or to toggle unused gesture flags as general purpose flags).

In both joystick mode and glove mode templates, the 16-bit section of the template defines the gestures. The gestures are evaluated for both kinds of templates.

In a joystick mode template, the 8-bit section defines the logic steps that determines what controller buttons to send.

In a glove mode template, the 2 bytes in the 8-bit section define which return bytes you want.

Again, the main thing that glove mode seems to skip is the logic processing.

LoneKiltedNinja wrote:
The REAL magic, which looks increasingly less likely now that we know the return data table is hardcoded, would be if there was a way to specify in the config packet that the Glove doesn't even need to query/compute certain values. I'd love to be able to e.g. get just x/y position at 30 or 60 FPS rather than the whole table (or whatever subset I mask in) at 10-15fps.
I agree it looks like the glove is always computing all of the X, Y, Z, R, and finger positions, and there's no way to selectively disable some of those computations to save time. (I don't understand why you think the "hardcoded return data table" is evidence for that. The table defines the order of the return data bytes, but you can still selectively turn each return data byte off or on to make the return packet smaller. If the glove wanted to disable some computations to save time, it might check which data bytes were requested to see what computations to disable. In that case, the return data table definition wouldn't prove the computations are always done.)

Edit: The attached file glove-mode-checks.txt shows the six places I found glove mode being checked (IFBIT 7, TEMPLATE).

Top

 Post subject: Re: the Power GlovePosted: Sun Dec 18, 2016 6:59 pm

Joined: Sun Mar 03, 2013 1:52 am
Posts: 104
Location: Texas, USA
The JavaScript code below parses the Power Glove programs and displays the results in a readable format. The parsing methods are based on the source code for the Power Glove onboard processor executable code: fourms.nesdev.com, electrongate.com. It parses the 14 programs built into the glove, as well as the transmission packets stored in Super Glove Ball and Bad Street Brawler.

parse-template-bytes.zip

Top

 Display posts from previous: All posts1 day7 days2 weeks1 month3 months6 months1 year Sort by AuthorPost timeSubject AscendingDescending
 Page 5 of 5 [ 64 posts ] Go to page Previous  1, 2, 3, 4, 5

 All times are UTC - 7 hours

#### Who is online

Users browsing this forum: Yahoo [Bot] and 7 guests

 You cannot post new topics in this forumYou cannot reply to topics in this forumYou cannot edit your posts in this forumYou cannot delete your posts in this forumYou cannot post attachments in this forum

Search for:
 Jump to:  Select a forum ------------------ NES / Famicom    NESdev    NESemdev    NES Graphics    NES Music    Homebrew Projects       2017 NESdev Competition       2016 NESdev Competition       2014 NESdev Competition       2011 NESdev Competition    Newbie Help Center    NES Hardware and Flash Equipment       Reproduction    NESdev International       FCdev       NESdev China       NESdev Middle East Other    General Stuff    Membler Industries    Other Retro Dev       SNESdev       GBDev    Test Forum Site Issues    phpBB Issues    Web Issues    nesdevWiki