Deleted
Deleted Member
Posts: 0
|
Post by Deleted on Feb 5, 2019 7:48:09 GMT
Now your game can be as cool as After Burner II, Out Run and Operation Wolf!
I did not find anything on the web about the XE-1AP/XE-1AJ and how to program into games, and I really wanted to try something with it. Coincidentally I ended up stumbling on some very suspicious code dicking around $1000 during a disassembly of OutRun I'm making (to understand how they calculate curves in their game)... of course that was the Analog mode support driver. I basically went over it until I understood it, alongside Raphael Assenat's hints about what it was doing, commented the driver and made a .txt explaining how the damn thing works. If anyone wants to integrate analog support in their games, don't be afraid to ask! I really want to see something cool come out of this. Also forgive any mistakes, I finished this at 5 AM, you know how easy it is to mangle up stuff when working like that PS: A copy of the .txt file for archival in-forum.
XE-1AP/J and XHE-3 Adapter Documentation by Punch (February 5th, 2019) https://github.com/AleffCorrea
XHE-3 and Pin Conversion: The XHE-3 Adapter converts the D-Sub 9 Connector from the XE-1AP/J to the Mini-DIN 8 connector on the PC Engine controller port through a 74HC157 multiplexer (much like a real 2-button pad) as follows (2,4): Pin XE-1AP/J 74'Pin SEL XHE-3 Mini DIN 8 N/A - - - 1 (VCC) 1 Digital_UP 1 Low 2 6 Trigger_1 1 High 2 4 Digital_RIGHT 2 Low 3 7 Trigger_2 2 High 3 2 Digital_DOWN 3 Low 4 N/A Select(XHE Btn) 3 High 4 3 Digital_LEFT 4 Low 5 N/A Run(XHE Btn) 4 High 5 N/A - SEL - 6 8 ANALOG SGNL(PULLUP) - - 7 (PCE CLR pin) N/A - - - 8 (Ground) As you can see, without specific support to the XE-1AP/J's ANALOG mode, the controller just acts as a regular, digital controller. That is, when the multiplexer's SEL line is HIGH, you can get the directional buttons through the least significant nibble from a $1000 read, and same when the SEL line is pulled LOW for the 4 remaining face buttons. We can, however, observe that, quite curiously, that instead of the XHE-3 connect the console CLR and the 74HC157's OE pins together through pin 7, like in regular 2-button controllers, the CLR pin connects directly to pin 8 in the XE-1 controller. This turns out to be the signal for the request of the analog data! Reading Analog Data: The $1000 I/O Port mapped on the PC Engine CPU allows us to read pins 2 to 5 through bits 4~7, and write to the SEL and CLR pins through bits 0 and 1. If we don't touch CLR (does any game write to this to disable the controller?) then the XHE-3 compatible controller will act happily like a 2-button pad. And indeed that's all there is to it to the compatible controllers XE-1PRO and XE-1ST2, which are compatible according to the adaptor's box, but don't have any analog facilities. The XE-1AP and XE-1AJ (and its rebranded version, the Sharp CZ-8NJ2 "CyberStick") however, can and will output ANALOG data through the digital ports if the game is programmed to do so. There are few official games that do so, one of them being OutRun, and all by NEC Avenue (maybe they subcontracted Dempa to program). This is the way OutRun does it: (a CPU cycle has 0.1396648 microsecs on 7.16Mhz) Note: some timings might not be as strict as what is shown here, 74HC157 r/w 11 cycle delays may or may not matter. ;************************************************************************************* Signal XE-1AP/J to start transfer procedure: 1. Write zeroes to the joypad port $1000 to put the PCE's CLR pin to LOW. 2. Roughly 16 CPU cycles later (~2.24 microseconds), write 0000_0010 (#$2) to $1000 to put the CLR pin HIGH again. Reading the Analog data: 3. Spend 11 cycles to set up a loop waiting for data to be sent. 4. For each 13 cycles (~1.81 microseconds), read bits 0 and 1 (& #$03) of $1000 to read both Trigger_1 and Trigger_2 (apparently SEL's line logic state is the inverse of the register value?). Triggers 2 and 1 acts as a signal to read the high/low nibbles, in that order.
Trigger 2 Trigger 1 AND #$03 No data: High Low 2 High Nibble: Low Low 0 Low Nibble: Low High 1 We check both trigger bits to see if the high nibble is ready. IF bits are NON-ZERO, repeat procedure 4 up to 10 times* (18.1 microsec) ELSE proceed to 5. 5. Write #$03 to $1000 then read from $1000, store obtained high nibble into RAM. 6. Repeat 3 and 4 for the low nibble, but this time comparing both trigger bits to #$01 and repeating if not equal.
7. Repeat 3 to 6 until all 6 bytes are read (or 11 nibbles since the 12th one will always be #$F, OutRun does this). *ERROR: If too many tries are made and no valid signal comes, quit. It's probably not an analog controller and should be treated as a regular one.
;************************************************************************************* Thanks to the work by Raphael Assénat(2), we don't need to further delve into the OutRun ROM to extract the button-to-value definitions (thank god!). Here it is, presented as it appears on his website: Byte 7 6 5 4 3 2 1 0 1st A/A' B/B' C D E1 E2 Strt Sel 2nd Stick Y (High) Stick X (High) 3rd Throttle Gear (Hi) 0 0 0 0 4th Stick Y (Low) Stick X (Low) 5th Throttle Gear (Lo) 0 0 0 0 6th A B A' B' 1 1 1 1
After that OutRun goes on immediately to use some values as indexes for tables on the ROM (speed definitions?), but we really don't care... the almighty XE-1AJ is now communicating analog stick data with us, and that's all we want. :) Sources: 1. PCEOutRun disassembly at <insert GitHub page here> 2. https://www.raphnet.net/electronique/xhe3_adapter/index_en.php 3. http://vrai.net/retro/wp-content/uploads/2013/08/tg16_pce_controller_adapter_schematic.png 4. Various PCE 2-Button Pad schematics on the internet Special Thanks to: Raphael Assénat (you're awesome) SuperDeadite (showing us PCE plebs the power of the CyberStick) Vincent "MooZ" Cruz (Couldn't do it without your Etripator PCE Disassembler) And basically everyone who codes for the PC Engine. No excuse to not support analog on your games now! ^^ Dura Codex, Sed Codex. Or something like that.
|
|
Deleted
Deleted Member
Posts: 0
|
Post by Deleted on Feb 5, 2019 7:52:53 GMT
The stolen driver from OutRun  ;analog_driver.asm ;This was extracted from OutRun via Etripator ; (https://github.com/BlockoS/Etripator) ; ;Copyright 1990 DEMPA/Micomsoft/NEC Avenue ;Extraction/Comments by Punch
.bss .org $3a15 ;Just change this to whatever you want. ANALOG_CTRL_1 .ds 11 .code .bank $001 .org $6124 ;Original address in ROM. ;Reads a XE1AP/XE1AJ/CZ-8NJ2's ANALOG values. ;Output ;Carry = 0: Analog data read successufully ;Carry = 1: Failed data transfer XE1AP_Analog_Read: pha phx phy cly ;Start Analog Signal (low) pulse through CLR pin. lda #$00 sta $1000 pha pla nop ;Common wait sequence in between 74HC157 writes. .lowPulseEnd: lda #$02 sta $1000 ;End the low pulse in 2.24 microsecs. pha pla nop ;You'll see this sequence a lot. ldx #$20 .waitHiNibble: dex bne .checkHiSignals jmp .XE1AP_ReadFailure ;If too many tries, quit. .checkHiSignals: ;Wait until signaled to copy High nibble. lda $1000 and #$03 bne .waitHiNibble ;Try until both 'trigger' signals are LOW. lda #$03 sta $1000 ;Change SEL so we can read the buttons/sticks. pha pla nop lda $1000 sta ANALOG_CTRL_1, Y ;Save the nibbles without fancy shifting. iny cpy #$0b beq .XE1APEnd ;Quit when all 11 nibbles are copied. lda #$02 sta $1000 ;Change SEL again to read the next 'trigger' pulse signals. pha pla nop
ldx #$20 .checkLoSignals: ;Wait until signaled to copy Low nibble. dex beq .XE1AP_ReadFailure ;Same deal, fail if too many tries. lda $1000 and #$03 cmp #$01 bne .checkLoSignals ;Try until 'trigger' signals are LOW, HIGH. lda #$03 sta $1000 ;Same deal as before, let's read the buttons/sticks. pha pla nop lda $1000 sta $ANALOG_CTRL_1, Y ;Copy the high nibble. iny bra .lowPulseEnd ;Let's read another pair of nibbles. ;Read success! .XE1APEnd: ;OutRun specific code here (use Etripator cfg to get it). clc ply plx pla rts
;Read fail :( .XE1AP_ReadFailure: lda #$02 ;Resetting $1000 to sensible values for sta $1000;standard joypad. sec ply plx pla rts
|
|
|
Post by soop on Feb 5, 2019 8:45:15 GMT
Wow, do you think we'd be able to ROM hack existimg games to provide support? And what games would most benefit?
Battle Ace, Space Harrier?
|
|
Deleted
Deleted Member
Posts: 0
|
Post by Deleted on Feb 5, 2019 15:41:49 GMT
Wow, do you think we'd be able to ROM hack existimg games to provide support? And what games would most benefit? Battle Ace, Space Harrier? Yaksa, racing games, and maybe even top-down shoot-em-ups (why not?). Given all the wonderful stuff that has been made with fan translations, I don't see why hacks wouldn't be feasible since the code is small and you could correspond X/Y positions of the stick/lever to player movement easily by shifting bits or having a look-up table of "movement speed per axis position" at most... plus 11 bytes in RAM for the controller data and maybe 2 extra bytes for fixed point precision movement if the game doesn't have it for some reason.
tl;dr: insert code/table in an unused ROM area, find 11/13 bytes of free RAM and find player movement code and rewrite it for variable speed increments.
To be honest I intended this more for homebrew games but the idea of hacking existing ones doesn't sound too bad. My next focus will be implementing the controller on Mednafen (as it would make the ANALOG feature much more accessible than it is now with the odd person or two owning the actual controller/sticks) but I'll look into it later when I have time.
|
|
|
Post by soop on Feb 5, 2019 15:54:34 GMT
Wow, do you think we'd be able to ROM hack existimg games to provide support? And what games would most benefit? Battle Ace, Space Harrier? the odd person or two owning the actual controller/sticks
That would be me  Thanks in advance!
|
|
|
Post by dshadoff on Feb 5, 2019 16:59:45 GMT
Let me see if I understand correctly - the "analogue" X/Y values come in as digital values, correct ? (i.e. you are using the word analogue to indicate that it isn't merely on/off) ...and if I understand correctly, the range is 0-15 on each axis, so it has limited accuracy (please correct me if I'm wrong).
Have you compared against the code for the pachinko controllers (1-axis "analogue" - but I believe that the range is 0-255), or PCE mouse ? I wonder if there is a way to differentiate between these devices, and have a more universal driver.
Dave
|
|
Deleted
Deleted Member
Posts: 0
|
Post by Deleted on Feb 5, 2019 17:50:48 GMT
Let me see if I understand correctly - the "analogue" X/Y values come in as digital values, correct ? (i.e. you are using the word analogue to indicate that it isn't merely on/off) ...and if I understand correctly, the range is 0-15 on each axis, so it has limited accuracy (please correct me if I'm wrong). Have you compared against the code for the pachinko controllers (1-axis "analogue" - but I believe that the range is 0-255), or PCE mouse ? I wonder if there is a way to differentiate between these devices, and have a more universal driver. Dave
Yes, it's just a way to say that the stick isn't on/off, the stick values are converted to digital by the controller itself. Their range is 0-255, an 8-bit value each for the X and Y axis of the "stick" and another one for the "throttle" (which is the lever with rotatable orientation on the XE-1AP and the Throttle/Gearstick on the XE-1AJ). It's just that the High/Low nibbles are split into two different bytes instead of being contiguous... the stick Y axis is split into two, for example, in the 2nd and 4th transmitted byte, on bits 7 to 4.
Do you have a list of games that support the Pachinko controller? Maybe I could do some disassembling to see if I can figure it out. As for the mouse I'd also prefer to find the driver for it in a game to double check, but I believe that the code is already out there somewhere (I have it in my dropbox account but I don't have the source it came from). Building a driver that can detect all those peripherals and read their values is a great idea, and I think it's feasible if we're talking strictly about traditional inputs (analog/digital controllers and at most the Tsushin Keyboard which Chris documented a while back).
PS: I just realized I inverted the bit order in the button table... will fix it right away.
|
|
|
Post by dshadoff on Feb 5, 2019 21:08:52 GMT
Ah, cool - especially about the 0-255 range. For the pachinko controller, only the Pachio-kun games used it, as I recall. Your best bet for disassembly would probably be the HuCard one, Pachio-kun Juuban Shoubu: www.pcengine.co.uk/HTML_Games/Pachio-kun_Juban.htmI had extracted and disassembled the mouse code, many many years ago - so you're probably thinking about that one. I don't recall which game I extracted it from (I don't think any HuCard games ever supported it, so it would have been a CDROM), but I also put the mouse code into the HuC libraries back in 2001, so it should also be there (I always tried to comment as much as possible, so as to facilitate learning). Dave
|
|
|
Post by elmer on Feb 6, 2019 4:21:00 GMT
I did not find anything on the web about the XE-1AP/XE-1AJ and how to program into games, and I really wanted to try something with it. ... I basically went over it until I understood it, alongside Raphael Assenat's hints about what it was doing, commented the driver and made a .txt explaining how the damn thing works. Congratulations and many thanks, that's excellent work! I had extracted and disassembled the mouse code, many many years ago - so you're probably thinking about that one. I don't recall which game I extracted it from (I don't think any HuCard games ever supported it, so it would have been a CDROM), but I also put the mouse code into the HuC libraries back in 2001, so it should also be there (I always tried to comment as much as possible, so as to facilitate learning). Yep, it's in the HuC include directory. That mouse code is from the game "Brandish". The mouse code in "Brandish", "Vasteel2", "Doukyuusei", "Tokimeki Memorial" and "1552 - Tenka Tairan" are all very different, but are obviously all following the same basic algorithm. <EDIT> And the mouse code in "A3", "Lemmings" and "Nemurenu Mori na Ohanashi" as well. There doesn't appear to have been much standardization in the code, the timing delays are all very different, and most of the games only handle a single mouse in the 1st port.
|
|
mooz
Deep Blooper
Posts: 29
|
Post by mooz on Feb 6, 2019 11:31:51 GMT
|
|
|
Post by soop on Feb 6, 2019 14:01:01 GMT
wow, that code is very terse! surprised it's that simple
|
|
|
Post by elmer on Feb 6, 2019 19:30:40 GMT
I did some research on the pachinko controller back then if anyone is interested. Hmmmm, that's nice-n-simple ... but I guess that it means that the pachinko controller isn't compatible with a multitap? And if it's plugged-in by itself, then I think that most of the 6-button compatible games are going to mistake the speed-dial for a 6-button joypad.
|
|
mooz
Deep Blooper
Posts: 29
|
Post by mooz on Feb 6, 2019 20:07:33 GMT
Yes. The pachinko controller acts like a standard pad when plugged to a multitap. If they are coded correctly (hum...) it should not happen as the extra buttons are sent on a second read with direction bits set to one. Pseudo code should be more explanatory : reset joypad (SEL=1 CLR=0 + SEL=1 CLR=1 + delay)
read joypad 1 <= UDLR I II R S read joypad 2 read joypad 3 read joypad 4 read joypad 5
joypad_reset
read joypad 1 <= 1111 III IV V VI read joypad 2 read joypad 3 read joypad 4 read joypad 5
So it may send crap on the 2nd player instead. edit Oh crap I tested with SF2 and indeed the dial acts as a 2nd pad  You have to push it at max cause the lower values will trigger the RUN button. Depending on the position of the dial, SF2 will detect it as a 6 or 2 button pad.
|
|
|
Post by dshadoff on Feb 6, 2019 20:45:23 GMT
Well, pachinko is really a single-player game...
I'm not sure if it's realistic to expect the system to be able to "auto-detect" which controller is attached (unless there's some "calibration" exercise); I was just hoping that they could be supported without having to cobble something together.
Still, it's a good idea to also try to figure out what can't possibly work together (i.e. multitap + peripheral, or MB128 + xxx).
Dave
|
|
|
Post by elmer on Feb 6, 2019 21:07:11 GMT
edit Oh crap I tested with SF2 and indeed the dial acts as a 2nd pad  You have to push it at max cause the lower values will trigger the RUN button. Depending on the position of the dial, SF2 will detect it as a 6 or 2 button pad. Yep, that's basically what I expected. So it's really a controller that you should only use for games that specifically support it, and it should be plugged in by itself. Not a problem, just good to know. Kinda like the XE-1AP/J and XHE-3 ... it's only really useful if it is the only joypad, plugged directly into the PCE (with no multitap). Again, not a problem, just good to know. So, if I'm thinking correctly, a game could try to detect the XE-1AP/J and XHE-3 combo on boot, and then use that specific driver if it is found, or else use a driver that can handle a multitap and a combination of 2-button/6-button/mouse. Which gets back to needing to detect a multitap which, IIRC, we do by looking for all buttons being pressed on joypad #6?
|
|