What's new

Scarletspeedstr

Student
Joined
Jun 28, 2017
Messages
87
Reaction score
30
Location
Pennsylvania, USA
Last night I popped in Nine Dragons just to verify normal carts were fine. I booted, then went into settings and did a system reset. I powered down, took out Nine Dragons and booted Espgaluda which then loaded normally. I then swapped to Ketsui and had garbled graphics again. Repeated the reset procedure with Nine Dragons, and then Ketsui loaded fine. If I reset with one of the conversion carts, a subsequent conversion won’t boot, but if I do a system reset after having booted Nine Dragons, all seems fine. I did this five times last night, and considered it a win for the evening. I’d still like to try a different PGM board with these at some point, but for now I have a quirky way of getting them to load.
 

Fluffy

Grand Master
Joined
Dec 15, 2018
Messages
538
Reaction score
936
Location
UK
I forgot to post this:

Python:
import struct

with open ("DOJDUAL.bin", "rb") as f:
	src = bytearray (f.read())

kovsh_tab = [
	0xe7, 0x06, 0xa3, 0x70, 0xf2, 0x58, 0xe6, 0x59, 0xe4, 0xcf, 0xc2, 0x79, 0x1d, 0xe3, 0x71, 0x0e,
	0xb6, 0x90, 0x9a, 0x2a, 0x8c, 0x41, 0xf7, 0x82, 0x9b, 0xef, 0x99, 0x0c, 0xfa, 0x2f, 0xf1, 0xfe,
	0x8f, 0x70, 0xf4, 0xc1, 0xb5, 0x3d, 0x7c, 0x60, 0x4c, 0x09, 0xf4, 0x2e, 0x7c, 0x87, 0x63, 0x5f,
	0xce, 0x99, 0x84, 0x95, 0x06, 0x9a, 0x20, 0x23, 0x5a, 0xb9, 0x52, 0x95, 0x48, 0x2c, 0x84, 0x60,
	0x69, 0xe3, 0x93, 0x49, 0xb9, 0xd6, 0xbb, 0xd6, 0x9e, 0xdc, 0x96, 0x12, 0xfa, 0x60, 0xda, 0x5f,
	0x55, 0x5d, 0x5b, 0x20, 0x07, 0x1e, 0x97, 0x42, 0x77, 0xea, 0x1d, 0xe0, 0x70, 0xfb, 0x6a, 0x00,
	0x77, 0x9a, 0xef, 0x1b, 0xe0, 0xf9, 0x0d, 0xc1, 0x2e, 0x2f, 0xef, 0x25, 0x29, 0xe5, 0xd8, 0x2c,
	0xaf, 0x01, 0xd9, 0x6c, 0x31, 0xce, 0x5c, 0xea, 0xab, 0x1c, 0x92, 0x16, 0x61, 0xbc, 0xe4, 0x7c,
	0x5a, 0x76, 0xe9, 0x92, 0x39, 0x5b, 0x97, 0x60, 0xea, 0x57, 0x83, 0x9c, 0x92, 0x29, 0xa7, 0x12,
	0xa9, 0x71, 0x7a, 0xf9, 0x07, 0x68, 0xa7, 0x45, 0x88, 0x10, 0x81, 0x12, 0x2c, 0x67, 0x4d, 0x55,
	0x33, 0xf0, 0xfa, 0xd7, 0x1d, 0x4d, 0x0e, 0x63, 0x03, 0x34, 0x65, 0xe2, 0x76, 0x0f, 0x98, 0xa9,
	0x5f, 0x9a, 0xd3, 0xca, 0xdd, 0xc1, 0x5b, 0x3d, 0x4d, 0xf8, 0x40, 0x08, 0xdc, 0x05, 0x38, 0x00,
	0xcb, 0x24, 0x02, 0xff, 0x39, 0xe2, 0x9e, 0x04, 0x9a, 0x08, 0x63, 0xc8, 0x2b, 0x5a, 0x34, 0x06,
	0x62, 0xc1, 0xbb, 0x8a, 0xd0, 0x54, 0x4c, 0x43, 0x21, 0x4e, 0x4c, 0x99, 0x80, 0xc2, 0x3d, 0xce,
	0x2a, 0x7b, 0x09, 0x62, 0x1a, 0x91, 0x9b, 0xc3, 0x41, 0x24, 0xa0, 0xfd, 0xb5, 0x67, 0x93, 0x07,
	0xa7, 0xb8, 0x85, 0x8a, 0xa1, 0x1e, 0x4f, 0xb6, 0x75, 0x38, 0x65, 0x8a, 0xf9, 0x7c, 0x00, 0xa0,
]

rom_size = len(src)

for i in range(rom_size//2):
	x, = struct.unpack_from("<H", src, i * 2)

	if ((i & 0x040080) != 0x000080): x ^= 0x0001
	if((i & 0x004008) == 0x004008 and (i & 0x180000) != 0x000000): x ^= 0x0002
	if ((i & 0x000030) == 0x000010): x ^= 0x0004
	if ((i & 0x000242) != 0x000042): x ^= 0x0008
	if ((i & 0x008100) == 0x008000): x ^= 0x0010
	if ((i & 0x002004) != 0x000004): x ^= 0x0020
	if ((i & 0x011800) != 0x010000): x ^= 0x0040
	if ((i & 0x000820) == 0x000820): x ^= 0x0080

	x ^= kovsh_tab[i & 0xff] << 8

	struct.pack_into("<H", src, i * 2, x)

with open("DDPDOJ_P1.bin", "wb") as f:
	f.write(src)
This is the decryption code from Mame for KOVSH. This will take the version of DoDonPachi that is used for KOVSH boards, and makes it usable in boards where the ASIC doesn't decrypt the ROM.
You'll need Python 3.x and run it in a directory with DOJDUAL.BIN to produce DDPDOJ_P1.BIN.

DoDonPachi uses the default boot address, so should run without the modifications to the PAL you need for Ketsui or Espgaluda.

(Obviously now someone needs to link the encryption/decryption tool I missed ...)
 

oneleaf86

Grand Master
Joined
Nov 14, 2016
Messages
605
Reaction score
943
Location
Melbourne, Australia
Last night I popped in Nine Dragons just to verify normal carts were fine. I booted, then went into settings and did a system reset. I powered down, took out Nine Dragons and booted Espgaluda which then loaded normally. I then swapped to Ketsui and had garbled graphics again. Repeated the reset procedure with Nine Dragons, and then Ketsui loaded fine. If I reset with one of the conversion carts, a subsequent conversion won’t boot, but if I do a system reset after having booted Nine Dragons, all seems fine. I did this five times last night, and considered it a win for the evening. I’d still like to try a different PGM board with these at some point, but for now I have a quirky way of getting them to load.
Check your PGM board to see if the main chip has been reworked or replaced. On one of my boards the main QFP chip had been shoddily replaced and when I tapped my finger on the cart, the glitching would come and go.
 

oneleaf86

Grand Master
Joined
Nov 14, 2016
Messages
605
Reaction score
943
Location
Melbourne, Australia
If anyone is still having issues getting the dual version of DDP to function properly I have a possible solution for you.

Turn DIP 8 off and load black or white label. Once the high score table has been displayed, power off and turn dip 8 back on.

Tried this on 3 different PGM boards and worked every time.
 

Apocalypse

Staff member
Legendary
Joined
Dec 6, 2017
Messages
3,620
Reaction score
6,154
Location
New-Zealand
If anyone is still having issues getting the dual version of DDP to function properly I have a possible solution for you.

Turn DIP 8 off and load black or white label. Once the high score table has been displayed, power off and turn dip 8 back on.

Tried this on 3 different PGM boards and worked every time.
Isn't the real problem that the white label doesn't initialise backup RAM properly?
To me a patch is required.
 

oneleaf86

Grand Master
Joined
Nov 14, 2016
Messages
605
Reaction score
943
Location
Melbourne, Australia
No idea what's functionally wrong the rom, just a work around in the short term for people having issues getting it running.
Just a wild guess though, it seems to me it's the high score table that's causing the errors, if you turn off the high score save hack on DIP 8 it seems to work perfectly.
 

Fluffy

Grand Master
Joined
Dec 15, 2018
Messages
538
Reaction score
936
Location
UK
This is the code I used to generate the PAL equations for KOV2:
Code:
from qm import QM

# produce a pld-compatible equation from the miniterms
def get_equation(minterms, variables):
	if isinstance(minterms,str):
		return "'b'%s" % minterms

	def parentheses(glue, array):
		if len(array) > 1:
			return ''.join(['(',glue.join(array),')'])
		else:
			return glue.join(array)

	or_terms = []
	for minterm in minterms:
		and_terms = []
		for j in range(len(variables)):
			if minterm[0] & 1<<j:
				and_terms.append(variables[j])
			elif not minterm[1] & 1<<j:
				and_terms.append('!%s' % variables[j])
		or_terms.append(parentheses(' & ', and_terms))
	return ' # '.join(or_terms)


def generatePal(a, b, csvName, pldName, siName, pins, desc):
	pinIn = [11,10,9,8,7,6,5,4,3,2,1,13]
	pinOut = [23,22,21,20,19,18,17,16,15,14]

	# generate simple csv table
	with open(csvName, "wt") as f:
		f.write ("%s\n" % ",".join([pins[x] for x in pinIn]+[pins[x] for x in pinOut]))
		for i in range(len(a)):
			s = []
			for j in range(12):
				if i & (1<<j):
					s += ["1"]
				else:
					s += ["0"]
			x = a[i] | ((b[i] & 0xc0) << 2)
			for j in range(10):
				if x & (1<<j):
					s += ["1"]
				else:
					s += ["0"]
			f.write ("%s\n" % ",".join(s))

	# generate test vector
	with open(siName, "wt") as f:
		for key, value in desc.items():
			f.write("%s %s;\n" % (key, value))
		f.write("\nORDER: %s;\n" % ",".join([pins[x] for x in pinIn]+[pins[x] for x in pinOut]))
		f.write("\nVECTORS:\n")
		for i in range(len(a)):
			s = []
			for j in range(12):
				if i & (1<<j):
					s += ["1"]
				else:
					s += ["0"]
			x = a[i] | ((b[i] & 0xc0) << 2)
			for j in range(10):
				if x & (1<<j):
					s += ["H"]
				else:
					s += ["L"]
			f.write ("%s\n" % "".join(s))

	# generate pld file
	with open(pldName, "wt") as f:
		for key, value in desc.items():
			f.write("%s %s;\n" % (key, value))

		f.write("\n/* Inputs */\n")
		for x in pinIn:
			f.write("Pin %i = %s;\n" % (x, pins[x]))
		
		f.write("\n/* Outputs */\n")
		for x in pinOut:
			f.write("Pin %i = %s;\n" % (x, pins[x]))

		f.write("\n/* Logic */\n")
		qm = QM([pins[x] for x in pinIn])
		for i in range(len(pinOut)):
			ones = []
			for j in range(len(a)):
				x = a[j] | ((b[j] & 0xc0) << 2)
				if ((x >> i) & 1) != 0:
					ones.append(j)
			
			print ("solve %s" % pins[pinOut[i]])
			f.flush()
			f.write("%s = %s;\n" % (pins[pinOut[i]], get_equation(qm.solve(ones,[])[1], qm.variables)))

# common description			
desc = {
	"PartNo":	"PAL_CE",
	"Date":     "27/01/2019",
	"Revision": "01",
	"Designer": "Fluffy",
	"Company": 	"None",
	"Assembly": "None",
	"Location": "None",
	"Device":  	"g22v10"
}

# Generate FI_U14
pins = {
	1:"U14_1",
	2:"TA18",
	3:"TA19",
	4:"TA20",
	5:"TA21",
	6:"TA22",
	7:"U14_7",
	8:"U14_8",
	9:"U14_9",
	10:"U14_10",
	11:"U14_11",

	23:"U14_23",
	22:"U14_22",
	21:"TO_U15",
	20:"U14_20",
	19:"TA21_I",
	18:"TA20_I",
	17:"TA19_I",
	16:"TA18_I",
	15:"T_ROM_OE",
	14:"INT_T_ROM_OE",
	13:"U14_13"
}

desc["Name"] = "PGM_FI_U14"

with open("FI_U14_A.bin", "rb") as f:
    a = f.read()
with open("FI_U14_B.bin", "rb") as f:
    b = f.read()

generatePal(a, b, "fi_u14.csv", "fi_u14.pld", "fi_u14.si", pins, desc)

# Generate FI_U15
pins = {
	1:"AS",
	2:"PA16",
	3:"PA23",
	4:"PA22",
	5:"PA21",
	6:"PA20",
	7:"FROM_U14",
	8:"FROM_U17_1",
	9:"U15_9",
	10:"U15_10",
	11:"U15_11",

	23:"INT_P_ROM_OE",
	22:"P_ROM_OE",
	21:"PA21_I",
	20:"PA20_I",
	19:"TO_U10_1",
	18:"TO_U9_15",
	17:"U15_17",
	16:"U15_16",
	15:"M68K_LATCH_ENABLE",
	14:"SRAM_ENABLE",
	13:"U15_13"
}

desc["Name"] = "PGM_FI_U15"

with open("FI_U15_A.bin", "rb") as f:
    a = f.read()
with open("FI_U15_B.bin", "rb") as f:
    b = f.read()

generatePal(a, b, "fi_u15.csv", "fi_u15.pld", "fi_u15.si", pins, desc)
It was just slapped together for those two PALs, so doesn't have a proper user interface. It depends on https://github.com/prekageo/optistate to convert what is essentially a truth table into PLD equations.

This is for 22V10, so it combines the output of two passes. The input is essentially a PAL read like a ROM, i.e. the address lines go through all values from 0 to the end of the ROM, and the values are whatever the PAL returned for that input. At that time I only had a G540, which seems to only support 8-bit ROMs. With a Top3000 you could treat this as a 16-bit ROM and read all 10 output values in one go.

It doesn't detect high impedance outputs, though that could probably be done by comparing two passes with pull-up and pull-down resistors. It doesn't detect registers, or outputs configured for input, either, so you should have rough idea what the PAL does, and look at what they pins are connected to in the circuit.
 

Fluffy

Grand Master
Joined
Dec 15, 2018
Messages
538
Reaction score
936
Location
UK
I was looking through the PCB scans and noticed this one:
http://www.gc8tech.com/wp-content/uploads/2019/03/HC2_BOTTOM_1.jpg

This uses an off-the-shelf Lattice CPLD:
https://uk.farnell.com/lattice-semi...0c/cpld-128mc-3-3v-ispmach-100tqfp/dp/2252885
and an ARM cpu:
https://uk.farnell.com/nxp/lpc2132fbd64/mcu-32bit-arm7tdmi-60mhz-lqfp/dp/1727702

Later games (like Demon Front) apparently run a significant amount of the game logic on the cartridge, so this may be interesting for people developing multi carts.

http://www.gc8tech.com/uncategorized/pgm-hacked-cart-2-pcbs/
 

sheep_nova

Student
Joined
Dec 9, 2018
Messages
43
Reaction score
85
Location
China
My friend planning to make a stock clearance(,let me know if u want^+^.)
 

Attachments

  • 78.jpg
    78.jpg
    183.5 KB · Views: 141

Asure

Professional
Joined
Jul 24, 2015
Messages
399
Reaction score
423
Location
Netherlands
No idea what's functionally wrong the rom, just a work around in the short term for people having issues getting it running.
Just a wild guess though, it seems to me it's the high score table that's causing the errors, if you turn off the high score save hack on DIP 8 it seems to work perfectly.
I didn't test this by credit feeding, but it's likely the stage 4 freeze/crash bug that got reported earlier is still in this one.
It's not related to the protection ASIC though, so possibly this could fix it. Way too busy with work and that damned addictive Apex Legends game still. (100 Kills now and my first win in the pocket ;).)
 

oneleaf86

Grand Master
Joined
Nov 14, 2016
Messages
605
Reaction score
943
Location
Melbourne, Australia
I've played through till the end with dip 8 off without any issues at all.
 
Top