Post Reply 
 
Thread Rating:
  • 1 Votes - 5 Average
  • 1
  • 2
  • 3
  • 4
  • 5
WPC NoFreeOnly
03-02-2011, 08:25 PM
Post: #1
WPC NoFreeOnly
This work with most except for CV:

Step 1. Find assembly code for the actual free-only flag check, here is a bit of tzone assembly that was the basis of these instructions:

6061D 461D: 1C FE ANDCC #$00FE ; strip the carry-bit
6061F 461F: 6D 9F 81 AB TST [-$FFFF7E55] ; test F7E55
60623 4623: 26 05 BNE $462A ; FREE ONLY WILL JUMP Because Z bit is not set!
60625 4625: BD 87 1E JSR $871E

For different games, the 5th and 6th bytes would be different so search for:
1CFE6D9Fxxyy26zzBDwwqq Where the xx, yy, zz, ww and qq are don't care (unknown) bytes. Actually I just search for 1CFE6D and if there is only 1 instance of this found in the entire ROM, it is likely the one you're looking for.

When found, take the xxyy bytes (81AB in this example) and move down to the next 0x10000 plus xxyy in the memory. I'm not sure the paging memory at this time, but for tzone, the actual assembly is at 6061F, and we want to go to 781AB. The 81AB came from the assembly and the 7 was the next 0x10000 from current (current is 0x60000).

For MM, the above assembly was found at E0663 and the xxyy was 81AE, so we then look at F81AE.

Step 2. Look at the xxyy referenced above. For tzone we look at 781AB and for MM we look at F81AE. The 2-bytes here are used to look up the final byte. The 2-bytes on tzone at 781AB are E84D. The 2-bytes for mm at F81AE Are E887. Take these 2-bytes and use the current 0x10000 chunk of ROM and go there. For example for tzone we go to 0x7E84D and of mm we go to 0xFE887.

Step 3. The byte referenced above should be a 0x01 which needs changed to 0x00 to remove free-only.
Find all posts by this user
Quote this message in a reply
03-10-2011, 07:31 PM
Post: #2
RE: WPC NoFreeOnly
Note, these directions can also be used to make a normally coin-operated ROM into a free-only ROM, for most WPC pins (even pins that have never had a free-only ROM officially released).
Find all posts by this user
Quote this message in a reply
07-24-2011, 12:12 PM
Post: #3
RE: WPC NoFreeOnly
(03-02-2011 08:25 PM)mrglee Wrote:  Actually I just search for 1CFE6D and if there is only 1 instance of this found in the entire ROM, it is likely the one you're looking for.

I tried this technique with White Water LH6 rom but I couldn't find 1CFE6D hex code inside.

Do you have an idea why ?
I would like so much setting coins back (I always play with tokens in my house with all my games).

Thank you !
Lilian
Find all posts by this user
Quote this message in a reply
07-25-2011, 07:31 PM
Post: #4
RE: WPC NoFreeOnly
Looks like on that ROM they changed the code so it won't take coins, similar to the CV home rom. It's going to be more than just flipping a bit. We'd probably have to disassemble the ROM in order to get it to take coins. This isn't something that can be done overnight.
Find all posts by this user
Quote this message in a reply
07-26-2011, 09:03 AM
Post: #5
RE: WPC NoFreeOnly
Okay, too bad.

If you have some idea or if I can help to test in some way, let me know.

Big thanks for your work and shares !
Find all posts by this user
Quote this message in a reply
07-27-2011, 06:50 PM
Post: #6
RE: WPC NoFreeOnly
Consider the following code snippet from IJ_L7 ROM
(may want to copy-paste the following into Notepad, looks better there)


;----------------------------------;--------------------------------------------
; PutCreditsAndBallInPlayInSmallFontOnBottomOfDMD()
;
; This routine loads up the "Credits" text string to RAM $0326 and then calls $D8FB
; to draw the ASCII text onto the DMD RAM. This function is called early during the
; attract mode to show credits on the bottom of the display along with the last
; played scores on the top portion of the DMD.
;
; This is also called during game play, so basically this is called whenever the
; 'Credits' needs to be shown on the bottom of the DMD.
;
; Called from $6B4A above.
;
34 76 PSHS U,Y,X,B,A ; Save registers
BD 99 B2 JSR $99B2 ; ValidateXGetPointerIntoY()
25 3A BCS $6CAE ; If C got set, some serious problem, skip to the end, No 'credits' text at all
BD 89 48 JSR $8948 ;
5E 83 39 ; ValidateCreditCountAndDisplayinSmallfontBottomOfDMD()
;
; This routine puts "CREDITS" along with the actual number of credits
; into RAM $0326 as a null-terminated ASCII string.
;
;
7F 02 D8 CLR $02D8 ; RAM $02D8 gets 0x00
31 C4 LEAY ,U ; Y gets U
BD BA 3F JSR $BA3F ; CopyASCIIStringFrom0326toYandVerifyLength()
96 8D LDA $8D ; A gets byte from $8D
26 1D BNE $6CA3 ; If $8D byte is non-zero skip down to $6CA3
;
;
; The following chunk of code will pre-pend the "Ball x" string in
; front of the number of credits
;
BD B2 5C JSR $B25C ; PutCurrentBallInPlayNumberInRamAt0326()
8E 03 26 LDX #$0326 ; X gets RAM $0326
BD BA 65 JSR $BA65 ; AdvanceXUntilNULLIsFound()
CC 20 20 LDD #$2020 ; D gets 2 space characters
ED 81 STD ,X++ ; Put 2 spaces
ED 81 STD ,X++ ; Put 2 spaces
ED 81 STD ,X++ ; Put 2 spaces
6F 84 CLR ,X ; Put a NULL
10 8E 03 26 LDY #$0326 ; Y bets 0x0326 address of ASCII string "BALL x" in RAM
30 C4 LEAX ,U ; Copy X to U this is the address of the END of the string
BD BA 48 JSR $BA48 ; AppendStringInXBufferAfterYBuffer()
;
;
;
BD 99 E3 JSR $99E3 ; SearchAndAddUTo_030A_LinkedList()
;
BD D8 FB JSR $D8FB ; PutASCIITextOntoDMD()
00 00 ; Index 0x00, ASCII string already put to $0326, "Credits"
02 ;
40 1F ;
35 F6 PULS A,B,X,Y,U,PC ; Done, RTS
;----------------------------------;--------------------------------------------


So an easy pattern to search for is the ED81ED81ED816F84.
These are the bytes that insert a couple spaces between "Ball #" and credit count
when forming small text that appears at the bottom of the DMD during game play.

Looking at the WW_H6 ROM we find this at 2 locations.
Lets look at each location, one here at around ROM file offset 0xEEE7F.
Looking a few bytes previous, we find what is pretty close to the IJ function.
I'll paste some bytes here from WW_H6 ROM starting from offset 0xEEBC8 which
appears to be the likely start of the similar function as that shown above.

34 36 ; Push Y,X,B,A
32 E8 EC ; LEAS -$FFFFFF14,S
BD 89 D2 ; Call paged function...
45 DC 38 ; Likely the ValidateCreditCountAndDisplayInSmallfontBottomOfDMD() function
7F 02 D8 ; Put a 0x00 at ram $2D8
31 E4 ; LEAY ,S
BD BA 43 ; Probably check if game in play, puts indicator in to ram $8D
96 8D ; probably checks if game is presently in progress so skip "ball #" text below
26 1D ; SKip to the BDD6A8 if $8D is nonzero
; I think the following chunk will put "Ball #" text into the buffer.
BD B2 51
8E 03 26
BD BA 69
CC 20 20
ED 81
ED 81
ED 81
6F 84
10 8E 03 26
30 E4
BD BA 4C
; Done with "Ball #" text generation
BD D6 A8 ; Function to put ASCII text into DMD ram
00 00 ; 0000 means the text string alread in ram at $326
02 ; additional function parameter, tbd
40 1F ; additional function parameter, tbd
32 E8 14 ; LEAS $14,S, fix up stack
35 B6 ; Pop registers, return


The WW_H6 ROM also has a match for the pattern ED81ED81ED816F84 at ROM offset 0xEEE7F.
Here are the bytes from that area starting at offset 0xEED5C which is the likely
start of this routine in WW_H6. You can see it appears to do the same thing as previous
except has 2x the calls to the same code. It's likely this is just a result of the
effort to rip out the coin-up functionality from the software:

34 36 ; Push Y,X,B,A
32 E8 EC ; LEAS -$FFFFFF14,S
BD 89 D2 ; Call paged function...
45 DC 38 ; Likely the ValidateCreditCountAndDisplayInSmallfontBottomOfDMD() function
7F 02 D8 ; Put a 0x00 at ram $2D8
31 E4 ; LEAY ,S
BD 89 D2 ; Call paged function...
45 DC 38 ; Likely the ValidateCreditCountAndDisplayInSmallfontBottomOfDMD() function
7F 02 D8 ; Put a 0x00 at ram $2D8
31 E4 ; LEAY ,S
BD BA 43 ; Probably check if game in play, puts indicator in to ram $8D
96 8D ; probably checks if game is presently in progress so skip "ball #" text below
26 1D ; SKip to the BDD6A8 if $8D is nonzero
; I think the following chunk will put "Ball #" text into the buffer.
BD B2 51
8E 03 26
BD BA 69
CC 20 20
ED 81
ED 81
ED 81
6F 84
10 8E 03 26
30 E4
BD BA 4C
; Done with "Ball #" text generation
BD D6 A8 ; Function to put ASCII text into DMD ram
00 00 ; 0000 means the text string alread in ram at $326
02 ; additional function parameter, tbd
40 1F ; additional function parameter, tbd
32 E8 14 ; LEAS $14,S, fix up stack
35 B6 ; Pop registers, return


So let's look at the IJ_L7 ValidateCreditCountAndDisplayInSmallfontBottomOfDMD()


;----------------------------------;--------------------------------------------
; ValidateCreditCountAndDisplayinSmallfontBottomOfDMD()
;
; Called from $6C77,20 during attract mode just before the 'Credits' is drawn onto the
; bottom of the DMD using a small font
;
34 14 PSHS X,B ; Save X and B
;
BD 5A EE JSR $5AEE ; ValidateNumberOfCreditsinRAM()
;
24 07 BCC $5E91 ; If C is clear all is good so far, skip to $5E91
;
; ..otherwise a problem,..
8E 00 00 LDX #$0000 ; X gets 0x0000 We will display ZERO credits
C6 00 LDB #$00 ; B gets 0x00 We will display ZERO credits
20 06 BRA $5E97 ; Skip down to $5E97
;
F6 1D AA LDB $1DAA ; B gets byte from $1DAA, this is the NUMBER OF CREDITS!!
BE 1D AB LDX $1DAB ; X gets bytes from $1DAB and $1DAC possibly 1/2 credit count??
;
8D 02 BSR $5E9B ; DisplayCreditsStringinSmallFontBottomOfDMD()
;
35 94 PULS B,X,PC ; Done, RTS
;----------------------------------;--------------------------------------------


Now lets look at the 45 DC 38 address in your WW_H6 ROM and see if it looks anything similar:
This WPC address $45DC,38 corresponds to ROM offset 0xE05DC


34 16 ; PSHS X,B,A
CC 00 00 ; LDD #$0000
!!! Note IJ_L7 has a bunch of validation stuff here for credits and ends up
!!! with whole number of credits in B and half credits in X
1F 01 ; TFR D,X
BD 45 AC ; Call $45AC, Possibly the equilivant of: DisplayCreditsStringinSmallFontBottomOfDMD()
35 16 ; PULS A,B,X



Now lets look at the code at WW_H6 WPC Address $45AC,38 which got called in previous function:
This WPC adress $45AC,38 corresponds to ROM offset 0xE05AC


34 06 ; PSHS B,A
1C FE ; ANDCC #$00FE, Clear C bit
BD 86 EA ; Call $86EA, Likely: Call paged function indexed by 2-byte parameter
80 DF ; 0x80DF, at ROM 0xF80DF is $778E,3D, at ROM 0xF778E is just RTS, so nothing. (debug hook)
25 23 ; BCS down 0x23 bytes to the rts 35 86. If debug hook set C bit, no text.
4F ; Clr A
BD 89 D2 ; Call paged function...
6D 75 39 ; Likely credit-dot check. C-bit gets set when no error/no dot
89 00 ; ADCA #00, Copy C-bit, if set, into A
1F 89 ; TFR A,B, Copy C-bit indicator into B. 01 means no credit dot.
8E 81 4F ; LDX #$814F, WPC String index for "FREE ONLY"
; 0x8000 is table indicator
; 0x014F is string number for "FREE ONLY"
!!!
!!! Here the equilivant IJ_L7 function has function call to check if the free only
!!! bit it set, and if so, skip over the following;
!!! Function call to check if user has set "free play" mode, if so load X
!!! with index for "FREE PLAY" string.
!!! Else, functions are called to check # of credits, and depending on whether
!!! there is whole or fractional credits, the appropriate string is loaded with
!!! credit count.
!!!
BD 89 D2 ; Call paged function...
40 37 39 ; Probably: function to put ASCII string pointed to by X into ram at $326
5D ; TSTB, check if credit dot should be shown. (show when B==0)
26 0C ; BNE down 0xC bytes, skip to the end, no credit dot
8E 03 26 ; LDX #$0326, Address in RAM with ASCII string
BD BA 69 ; Call $BA69, Function to Advance X until NULL if found
86 2E ; LDA #$2E, Our friend the credit dot, ASCII '.'
A7 84 ; STA ,X, Push credit dot onto end of string
6F 01 ; CLR $0001,X, Put NULL terminator after the dot
35 86 ; PULS A,B,PC, done


So in addition to fixing up the above function, there should be another function
for printing large font credit count (the above function is only for the small
font printing at the bottom edge of the DMD). Also the switch-matrix handler for
coin switches needs to be coded up as well which could be another long procedure.
Depending on exactly how much code was removed, it may be extermelly difficult to
put coins back in, but they did leave the Pricing adjustments in the menu system
so there is hope that it may not be totally impossible! If we're lucky we could
just copy similar code from WW_L5 into the WW_L6 rom and fix up the above function
and the large-text equilivant.

For fun, I see the "CREDITS %B" string is 5 minus "FREE ONLY" so try changing
the 8E 81 4F to 8E 81 4B. Next you can hack in # of credits to faux show into B
register by changing bytes 1F89 (just prior to the 8E814F) to C602. This puts
2 into B so it will show "CREDITS 2" but that hack leaves non-zero value in B which
will cause credit dot to never show on small text mode. This hack is for
education purposes only, I think it'd be crazy to actually burn a ROM with such
changes. I test this sort of thing in PinMame.

Of course this hack is cosmetic only, the switch-matrix would need fixed up and this
function would need to actually read # of credits and account for half/credits
and also the user adjustment for "free play" mode as well.
Find all posts by this user
Quote this message in a reply
07-27-2011, 08:39 PM
Post: #7
RE: WPC NoFreeOnly
I noticed in pinmame that the function I show above actually is called for both the small font display of "credits" at the bottom edge of the DMD <and> the full sized "credits" that appears centered on the DMD. I mis-named the function.

This means to get WW_H6 ROM to work with coins, we'd need to fix up this one function, and also the switch-handlers for coins and probably the switch-handler for the start button.

This means it's probably do-able, at a worst case situation, if the pricing stuff wasn't in there, we'd have to make a fixed pricing where each coin racks up a credit or something like that. However since pricing adjustments are still in there, probably could restore original functionality, but that's just a guess.
Find all posts by this user
Quote this message in a reply
09-05-2011, 05:51 PM
Post: #8
RE: WPC NoFreeOnly
The original directions for this no-free-only fix were written without understanding of the WPC Banked ROM architecture. Below is an updated set of directions with WPC Banked architecture in mind. These should work for any WPC ROM except for cv_20h and ww_lh6.

New Directions:
Find assembly code for the actual free-only flag check, here is a bit of tzone assembly that was the basis of these instructions:

6061D 461D: 1C FE ANDCC #$00FE ; strip the carry-bit
6061F 461F: 6D 9F 81 AB TST [-$FFFF7E55] ; test F7E55
60623 4623: 26 05 BNE $462A ; FREE ONLY WILL JUMP Because Z bit is not set!
60625 4625: BD 87 1E JSR $871E

Need to search your ROM for the fixed bytes (bytes that will be the same for all games) so in this example it would be 1C FE 6D 9F xx yy 26 05 BD ww qq, where wwqq are don't cares, and xxyy is the free-only pointer pointer in non-banked ROM space.

Once you have your xxyy pointer pointer in non-banked ROM space you need to figure out the ROM-offset that represents this address, derive the free-only pointer from it, and then find the actual free-only byte.

For a 2-megabit ROM, the non-banked memory starts at 0x38000. So for Hurricane-L2, we find the free-only pointer pointer is 0x813F. This means its the (0x813F - 0x8000 = 0x13F) offset into the non-banked ROM hence the ROM address for the free-only pointer pointer is 0x3813F. At 0x3813F is 0xF17B which is the free-only pointer. This means the free-only byte is at (0xF17B - 0x8000 = 0x717B) offset into the non-banked ROM hence the ROM address for the free-only byte is 0x3F17B.

For a 4-megabit ROM, the non-banked memory starts at 0x78000. So for Corvette-2.1, we find the free-only pointer pointer is 0x8187. This means its the (0x8187 - 0x8000 = 0x187) offset into the non-banked ROM hence the ROM address for the free-only pointer pointer is 0x78187. At 0x78187 is 0xE983 which is the free-only pointer. This means the free-only byte is at (0xE983 - 0x8000 = 0x6983) offset into the non-banked ROM hence the ROM address for the free-only byte is 0x7E983.

For a 8-megabit ROM, the non-banked memory starts at 0xF8000. So for Attack From Mars-1.13, we find the free-only pointer pointer is 0x81AE. This means its the (0x81AE - 0x8000 = 0x1AE) offset into the non-banked ROM hence the ROM address for the free-only pointer pointer is 0xF81AE. At 0xF81AE is 0xE887 which is the free-only pointer. This means the free-only byte is at (0xE887 - 0x8000 = 0x6887) offset into the non-banked ROM hence the ROM address for the free-only byte is 0xFE887.

Some of the above may seem redunant because the base address for non-banked ROM addresses ends with 0x8000, we can just skip the math for deriving an offset from starting address in non-banked ROM. In other words when you see an address such as 0xE887, since it's greater than 0x8000 base-address for non-banked memory, all you have to do is add the 5th nibble for whatever ROM size you're working with. So if you are dealing with address 0x81AE for an 8-megabit ROM you just need to add 'F' to make it 0xF81AE. Or if you see address 0x8187 for a 4-megabit ROM, since it's greater than 0x8000 you can just add '7' to derive the ROM address ox78187.
Find all posts by this user
Quote this message in a reply
Post Reply 


Forum Jump:


User(s) browsing this thread: 1 Guest(s)