It is currently Thu Dec 14, 2017 9:48 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 64 posts ]  Go to page Previous  1, 2, 3, 4, 5
Author Message
 Post subject: Re: the Power Glove
PostPosted: Sat May 09, 2015 3:41 pm 
Offline

Joined: Sun Mar 03, 2013 1:52 am
Posts: 99
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:
        JSR     GADB
        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.


About the "extra 6 bytes"...
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
 Profile  
 
 Post subject: Re: the Power Glove
PostPosted: Fri May 29, 2015 9:05 am 
Offline

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:
;
; 16-bit header TEMPLATE byte
;  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
 Profile  
 
 Post subject: Re: the Power Glove
PostPosted: Sat May 30, 2015 10:32 am 
Offline

Joined: Sun Mar 03, 2013 1:52 am
Posts: 99
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).


Attachments:
glove-mode-checks.txt [5.41 KiB]
Downloaded 52 times
Top
 Profile  
 
 Post subject: Re: the Power Glove
PostPosted: Sun Dec 18, 2016 6:59 pm 
Offline

Joined: Sun Mar 03, 2013 1:52 am
Posts: 99
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


Attachments:
parse-template-bytes.zip [4.54 KiB]
Downloaded 28 times
Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 64 posts ]  Go to page Previous  1, 2, 3, 4, 5

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 7 guests


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

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group