Gravitar on Space Duel PCB

philmurr

Active member
vacBacker
Feedback
46 (100%)
Credits
2,350CR
I've a feeling this could end up as THE project of the year...

Looking good Neil
smiley20.gif
 

Mitchell Gant

Active member
vacBacker
Feedback
2 (100%)
Credits
884CR
I took a couple of short video clips last night

https://www.youtube.com/watch?v=px-1_rRvp6g

[tube]px-1_rRvp6g[/tube]

The three hexagon shapes have a glitch at minimum size that I need to find and fix on that screen.

https://www.youtube.com/watch?v=aXbPT_hzKz0

[tube]aXbPT_hzKz0[/tube]

This one is really to test the analogue scaling (zoom) hardware is working on the modified board.

Another problem you can't see here is that I have some code to read the buttons to step forwards and backwards through the test screens. It works fine on MAME, but on the real hardware it is not de-bounced sufficiently so skips past a couple of screens unless you hit the button just right.

Hurray Banana2016-08-18 13:00:09
 

Mitchell Gant

Active member
vacBacker
Feedback
2 (100%)
Credits
884CR
A quick update, I've made a little more progress on the switchable hardware and software, it's more or less working but still got some glitches and head scratching to make it perfect.

High score save doesn't seem to work on Black Widow, but seems OK on other two games, and I've had it in a state where it won't switch out of Space Duel without powering off.

http://www.youtube.com/watch?v=SBCURiMcX1o


Hurray Banana2016-09-03 03:47:04
 

Mitchell Gant

Active member
vacBacker
Feedback
2 (100%)
Credits
884CR
One of the problems when converting Gravitar to run on Space Duel hardware is the button input circuitry differences. Gravitar expects to read two addresses $8000 and $8800 where all 8 bits correspond to a button input. Space Duel reads 8 addresses from $900 to $907 but only bits 6 and 7 correspond to buttons.

When converting Gravitar I wrote some code that would read the Space Duel addresses and construct an 8 bit value that mapped the Space Duel buttons to the Gravitar pattern.

I then searched the Gravitar code to look for any reads of address $7800, $8000 and $8800 and replaced the read instructions with a jump to subroutine pointed at my conversion code. There were only a handful of reads found and it was fairly quick to replace, so it appeared to work OK.

But one part of the game code did not work correctly which was the test mode. In test mode both Gravitar and Space Duel use a similar screen where there are a few rows of binary digits shown as 0's or 1's. Pressing a button changes the 0 to a 1 and there's a short beep sound to confirm the button press.

GravitarSelfTestScreen1.jpg


My converted Gravitar code did beep correctly but would not change the 0 to a 1 on screen, which was a puzzle.

I've tried to find the part of code responsible for some time but not had much success until now. After a fair bit of MAME debugger breakpoints and tracing back the test mode screen draw for 0's and 1's I finally found the part that does the test mode.

The basic reason it was not working is that instead of a simple read of the addresses $7800, $8000 or $8800 that the rest of the game code uses, the test code sets up a 16 bit pointer in RAM and uses that with the 6502 Indirect Indexed addressing mode to read from the input addresses. It then reads the three addresses from a short loop and then prints out the state of each bit using 0's and 1's on the screen.

The routine starts at $EC41 for Gravitar Rev 3. The first part of the routine reads from POKEY registers on both POKEY chips to get two bytes that represent the two 8 way DIP switches on the PCB that are connected to the POKEY pot ports. This part was already working as I'd done a simple search and replace on any reads and writes to the POKEY addresses and moved them to the Space Duel addresses.

EC41 loc_EC41:

EC41 LDX #0Fh ; Button test 0/1 display

EC43 STX byte_22

EC45 STA POKEY_1+0Bh ; POKEY 1 POTGO

EC48 NOP

EC49 LDA POKEY_1+8 ; Read POKEY 1 POT register

EC4C STA byte_24 ; Store POT bits in RAM temp

EC4E STA POKEY_0+0Bh ; POKEY 0 POTGO

EC51 NOP

EC52 LDA POKEY_0+8 ; Read POKEY 0 POT register

Then the test code enters a loop of 16 counts starting at $EC55 to print a 0 or 1 for each of those two bytes.

EC55 loc_EC55:

EC55 PHA ; Test POKEY DIP switches x 16

EC56 AND #1

EC58 CLC

EC59 JSR sub_DE54 ; Test 0/1 buttons

EC5C LSR byte_24

EC5E PLA

EC5F ROR A

EC60 DEC byte_22

EC62 BPL loc_EC55 ; Test POKEY DIP switches x 16

After exiting the loop it moves the vector beam to a new screen position ready for the next line of 0's and 1's.

EC64 LDA #0D0h

EC66 LDY #0

EC68 LDX #0F8h ; Move to next line for text draw position

EC6A JSR sub_E48A ; Insert draw/move vector to new position

Next a loop count of 8 is set up and a 16 bit pointer at $38/39 is initialised to $7800. This was the culprit causing the problem!

EC71 LDA #78h ; Upper byte of address points to $7800 (Coin/test inputs)

EC73 STA byte_39

EC75 loc_EC75:

EC75 LDA #7

EC77 STA byte_3A ; Loop count

EC79 LDA #0

EC7B STA byte_38 ; Low byte off address pointer

EC7D TAY ; Clear Y index too

EC7E LDA (byte_38),Y ; Read input port starting at $7800

EC80 EOR #0FFh ; Invert button bits

EC82 AND #7Fh ; Mask top bit 7 (ignore top bit for each address)

After printing each of the 8 bits read in...

EC84 loc_EC84:

EC84 PHA

EC85 AND #1 ; Get button state bit

EC87 CLC

EC88 JSR sub_DE54 ; Insert 0/1 for button test

EC8B PLA

EC8C ROR A ; Shift for next button state bit

EC8D INY

EC8E DEC byte_3A

EC90 BPL loc_EC84

...the code moves the vector beam to the next line position...

EC92 LDA #0D0h

EC94 LDY #0

EC96 LDX #0F8h ; Move to next line for text draw position

EC98 JSR sub_E48A ; Insert draw/move vector to new position

...then adds $800 to the pointer at $38/39 and tests to see if it's hit $9000. If it has it exits the routine, else it loops to draw the next 8 characters.

EC9B LDA byte_39

EC9D CLC

EC9E ADC #8 ; Add $800 to pointer to read $7800, 8000 and 8800 in sequence

ECA0 STA byte_39

ECA2 CMP #90h ; Loop test stops at $9000

ECA4 BCC loc_EC75

ECA6 RTS

The initialising of the pointer is what I was missing in my conversion, as it's hardcoded in the LDA #78 at $EC71. Once I spotted that I realised that was why it doesn't work properly. Interestingly the sound beep feedback when you press a button in test mode is done in another part of code that does read the $7800/8000/8800 addresses directly and had already been converted properly.

Next job is to work out how to convert this code to work on the Space Duel hardware. I'm hoping Black Widow uses the same code and will be now easy to find.
 

Mitchell Gant

Active member
vacBacker
Feedback
2 (100%)
Credits
884CR
Since fixing the button input test mode code last time, I've been trying to play a few games on my actual cab rather than the MAME driver for debugging.

That brought back a problem that Backflipper found for me at Steve's last meet. The rather major problem was that you could seemingly shoot yourelf and lose a ship.

I thought I'd fixed this somehow but realised that it happened on the real PCB, but not on MAME which I'd been using for most of the testing.

My first thoughts were that my extra button input code was slowing something down too much and causing the problem on a real 6502 at 1.5MHz, but not on MAME that is probably much quicker at running it's 6502 emulation.

The button code I'd added was called in place of each read from the Gravitar code that expected to read the Gravitar PCB button input addresses. So rather than read a single address, it instead called this code to reconstruct the Space Duel inputs to look like Gravitar.

Read_GRV_IP2:

BIT Buttons_Opts + 4

BVC Plr_12 ; If Player 1 start pressed

BIT Buttons_Opts + 6

BPL Plr_12 ; And if Player 2 start pressed then

JSR Bank_Exit ; Exit to selection bank

Plr_12:

ROL Buttons_Opts + 7 ; Get Cabinet type in to carry flag

ROL A ; Rotate into result

ROL Buttons_Opts + 6 ; Get Start 2 (SD Game select) in to carry flag

ROL A

PHA

LDA Buttons_Opts + 4

ROL A

ROL A ; Get Start 1 (SD Game select) in to carry flag

PLA

ROL A

ROL Buttons_Opts + 5 ; Get Thrust 2 in to carry flag

ROL A

ROL Buttons_Opts + 3 ; Get Rotate left 2 in to carry flag

ROL A

PHA

LDA Buttons_Opts + 3

ROL A

ROL A ; Get Rotate right 2 in to carry flag

PLA

ROL A

PHA

LDA Buttons_Opts + 1

ROL A

ROL A ; Get Fire 2 in to carry flag

PLA

ROL A

ROL Buttons_Opts + 1 ; Get Shields 2

ROL A

EOR #0FFh ; Invert for SD hardware

RTS

That's a fair bit extra compared to the original single 'LDA $8800' instruction and I realised after a bit more staring at the code that these functions were called several times during the interrupt service routine. That means that the extra code was being called 250 times per second!

Every interrupt would look at the cabinet type, and if it was an upright, or a cocktail and player 1 was up, it would merge the player 1 button data with the player 1 and 2 start button data and store it in Button_Data @ $40. Otherwise it would just read player 2 cocktail button inputs and start button data and store that directly in Button_Data @ $40.

sub_CC8A:

LDA LED_Coin_Ctr ; Read cabinet type from control panel inputs @ $8800

BMI loc_CC93 ; If not an upright cabinet then

LDX byte_CF ; Player up

BNE loc_CCA1 ; If not player 2 of cocktail then jump loc_CCA1

loc_CC93:

LDA LED_Coin_Ctr ; Read control panel inputs @ $8800

AND #0E0h ; Mask out option switch data

STA Button_Data

LDA Buttons_Opts ; Read player 1 buttons @ $8000

AND #1Fh ; Mask out option switches

ORA Button_Data ; Merge Player 2 cocktail controls to bit pattern for buttons

loc_CCA1:

EOR #0FFh

STA Button_Data

Although my method of simply replacing the LDA Buttons_Opts and LDA LED_Coin_Ctr with JSR calls worked to prove the gameplay, it can be made a lot faster.

Now the subroutine @ CC8A looks like:

sub_CC8A:

LDA $907 ; Read Space Duel cabinet type into sign

BPL loc_CC93

LDX byte_CF ; Get current player

BNE loc_CCA1 ; Branch if player 2

loc_CC93:

JSR Read_GRV_PL1_IP ; Construct player 1 button data

loc_CCA1:

My new subroutine Read_GRV_PL1_IP constructs the button data byte in the form that Gravitar expects for player 1 rather than doing the AND and OR masking of the original code. Some testing in MAME proved it worked for player 1 and 2 of an upright cab, but I can't test the cocktail 2 player.

Next I burned a flash ROM and put it in my cab to play and... found that the same problem of shooting yourself was still there. Bugger!
 

Mitchell Gant

Active member
vacBacker
Feedback
2 (100%)
Credits
884CR
Next I think maybe it's not a software issue but a hardware issue that is causing this subtle problem.

I looked at my GAL code for the 6502 memory expander and noticed that I'd missed off a Phi2 enable signal when writing to the expander RAM. On my first attempt at a 6502 memory expander I had used a different PCB (the red one in the photos on the first page of this thread). That DID correctly have Phi 2 enable used in its logic equations, so I quickly compiled and burned a GAL chip to try in the newer expander PCB.

That now seems to have cured the 'shooting yourself' problem, but I'm most amazed that anything worked at all before putting in the Phi2 enable signal!

There are still hardware issues though, that seem to be temperature related. I can power up the cab and select Space Duel or Black Widow with no problems, but trying to select Gravitar just gives a blank screen. Unless the test mode switch is flipped, then Gravitar test mode works fine.

After leaving switched on a for 10 minutes or so, trying to select Gravitar gameplay mode works fine, and it can switch in and out for the rest of the time it's powered.

Leaving a few hours and the problem comes back.

Another problem that's appeared is that playing Space Duel seems to have lost some of the sounds, though both POKEY's have been swapped and seems to be OK on Gravitar and Black Widow.

Playing the exact same software in MAME and all works OK.

I also seem to think that sounds were there when I first made my conversion, before putting in the multi game selection.

So the hunt continues!
 

Hurray Banana

Moderator
Staff member
vacBacker
Feedback
8 (100%)
Credits
2,723CR
Mame clears all declared address spaces, maybe something needs explicitly initialising. This has caught me out and Ade had a similar problem on taito l system, working fine in mame but borked on the pcb
 

Mitchell Gant

Active member
vacBacker
Feedback
2 (100%)
Credits
884CR
Mitchell Gant said:
Next I think maybe it's not a software issue but a hardware issue that is causing this subtle problem.

There are still hardware issues though, that seem to be temperature related. I can power up the cab and select Space Duel or Black Widow with no problems, but trying to select Gravitar just gives a blank screen. Unless the test mode switch is flipped, then Gravitar test mode works fine.

I will update what I've found since that last post as it's dragged on far too long now, it appears that it *was* a subtle hardware problem and not related to my software mods at all, which does explain why it worked well in MAME but not on a real PCB.

I'm using a Phillmurr 6502 memory expander PCB, built with 74HCT245 buffer chips as that's what I had plenty of rather than 74LS245's.

It seems that if I use a UM6502A in the expander along with a 74HCT245, there is the problem of running Gravitar until the power has been on a few minutes, pointing to a temperature sensitive problem.

I changed to an old, used 74LS245 that I found and the problem went away!

I then tried a few different 6502 chips that I had, and anything other than a UM6502A worked OK with a 74HCT245 too. I found a Rockwell and a couple of Synertek 6502A's that worked OK with the HCT245.

I then tried each of the four UM6502A's that I had, and every one failed when used with the HCT245!

Picture of failure:

20170314_214945.jpg


I can only think that there is some timing issue when using the UM6502A and a 74HCT245, but only causes a problem when certain 6502 instructions, or sequences of instructions are executed, and Gravitar happens to have code that causes that.

Running Space Duel and Black Widow attract screens certainly seemed OK, but there's no telling if certain parts of those games would also cause a problem when played in anger.

So to anyone using one of Phillmurr's 6502 expander, beware of the UM6502A and 74HCT245 combination!

Here's my solution that arrived today:

20170314_214833.jpg


I now have enough 6502A's and expander boards to be able to test several and see if it really has cured the problem. I've got one PCB with a socket for the 74LS245 buffer so I can swap several of these too.

I didn't get to the bottom of what the actual problem is, I was just happy that I had made some positive progress.

For now I'm moving on with the software mods and hoping that this annoying issue has finally been cured, at least I know what to look out for.
 
Top