prfsnl_gmr wrote: ↑Sat Feb 06, 2021 12:02 pm
Still some games elude me...most Tengen (mapper 64) games
Gyruss
I have given all of these a basic cleaning, and they all look good. Before I embark on an epic “disassemble, deep clean, reassemble, and test on original hardware” quest, does anyone have any tips on dumping any of these games?
Gyruss should work with a CNROM script:
Code: Select all
board <- {
mappernum = 3,
cpu_romsize = 0x8000, cpu_banksize = 0x8000,
ppu_romsize = 0x8000, ppu_banksize = 0x2000,
ppu_ramfind = false, vram_mirrorfind = true
};
function cpu_dump(d, pagesize, banksize)
{
cpu_read(d, 0x8000, 0x4000);
cpu_read(d, 0xc000, 0x4000);
}
function ppu_dump(d, pagesize, banksize)
{
for(local i = 0; i < pagesize; i++){
cpu_write(d, 0x8000, i);
ppu_read(d, 0, banksize);
}
}
I keep getting an error whenever I try to use a script that has "dofile" in it. For example, I'm trying to dump two games: "Famicom Jump" and "Magical Taruruto-kun Fantastic World".
The Jump script is titled bandai_fcg1.ad and this is what it looks like:
Code: Select all
/*
BANDAI FCG-1, FCG-2
FCG-1 + Program ROM + Charcter ROM
ドラゴンボール 大魔王復活
西村京太郎ミステリー ブルートレイン殺人事件 (Irem)
FCG-2 + Program ROM + Charcter ROM
ファミコンジャンプ
魁!!男塾
名門!第三野球部
ドラゴンボール3
悪魔くん
*/
board <- {
mappernum = 16,
cpu_rom = {
size_base = 2 * mega, size_max = 2 * mega,
banksize = 0x4000
},
cpu_ram = {
size_base = 0x0000, size_max = 0x0000,
banksize = 0x2000
},
ppu_rom = {
size_base = 2 * mega, size_max = 2 * mega,
banksize = 0x0400
},
ppu_ramfind = false,
vram_mirrorfind = false
};
const register_offset = 0x6000;
dofile("lz93d50.ai");
And the Taruruto scriptis called "bandai_lz93d50_x24c01.ag" and it looks like this:
Code: Select all
/*
BANDAI FCG-3 + X24C01 style cartridge
SDガンダム外伝 ナイトガンダム物語
1990-08-11 B50EEP, LZ93D50+X24C01
ドラゴンボールZ 強襲!サイヤ人
1990-10-27 DRAGON BALLZ, LZ93D50+X24C01
まじかる☆タルるートくん ファンタスティックワールド
1991-03-21 DRAGON BALLZ-B, LZ93D50+X24C01
まじかる☆タルるートくん2
1992-06-19 DRAGON BALLZ-B, LZ93D50+X24C01 ← 24C02 ではない
*/
board <- {
mappernum = 16,
cpu_rom = {
size_base = 2 * mega, size_max = 2 * mega,
banksize = 0x4000
},
cpu_ram = {
size_base = 0x0080, size_max = 0x0080,
banksize = 0x0080
},
ppu_rom = {
size_base = 1 * mega, size_max = 2 * mega,
banksize = 0x0400
},
ppu_ramfind = false,
vram_mirrorfind = false
};
const register_offset = 0x8000;
dofile("lz93d50.ai");
/*
=====================
X24C01 frame sequence
=====================
<START>[EEPROM address+RW]<A-ACK>[data]<D-ACK><STOP>
<> is 1bit, [] is 8bit, A-ACK is address acknowledge,
D-ACK is data acknowledge, R is 1, W is 0
8bit data send MSB to LSB (bit7 to bit0)
Dragon Ball Z1's program send address LSB to MSB (bug).
slave address does not exist.
--current address read--
<START>[EEPROM address,R]<A-ACK>[EEPROM data]<D-ACK><STOP>
--sequenctial read--
<START>[EEPROM address,R]<A-ACK>|[EEPROM data]<D-ACK>|<STOP>
|<- loop any times ->|
--page write---
|<START>[EEPROM address,W]<A-ACK>|[EEPROM data]<D-ACK>|<STOP>
|<- loop A-ACK is H ->|<- loop 1to4times ->|
*/
function cpu_ram_access(d, pagesize, banksize)
{
local I2C_WRITE = I2C_SEND_L;
local I2C_READ = I2C_SEND_H;
if(mode_is_read(d) == true){
//sequential read
i2c_address_set(d, 0, I2C_READ);
for(local i = 0; i < pagesize * banksize; i++){
for(local bit = 0; bit < 8; bit++){
cpu_write(d, 0x800d, I2C_DIR_WRITE | I2C_CLOCK_L | I2C_SEND_H);
cpu_write(d, 0x800d, I2C_DIR_READ | I2C_CLOCK_H | I2C_SEND_H);
cpu_read_bit_msb(d, 0x6000, 4);
}
//send ack
send_bit(d, I2C_SEND_L);
}
i2c_stop(d);
}else{
//page write (4byte)
for(local i = 0; i < pagesize * banksize; i+=4){
i2c_address_set(d, i, I2C_WRITE);
for(local j = 0; j < 4; j++){
for(local bit = 0; bit < 8; bit++){
local n = I2C_SEND_L;
if(cpu_fetch_bit_msb(d) != 0){
n = I2C_SEND_H;
}
send_bit(d, n);
}
i2c_ack_wait(d);
}
i2c_stop(d);
}
}
}
It says in each
and I have a file named lz93d50.ai with this in it in the same folder:
Code: Select all
//cpu_dump, ppu_dump 内で同名の関数を呼んではいけない
function cpu_dump(d, pagesize, banksize)
{
for(local i = 0; i < pagesize - 1; i += 1){
cpu_write(d, register_offset + 8, i);
cpu_read(d, 0x8000, banksize);
}
cpu_read(d, 0xc000, banksize);
}
function ppu_dump(d, pagesize, banksize)
{
for(local i = 0; i < pagesize; i += 8){
for(local j = 0; j < 8; j += 1){
cpu_write(d, register_offset + j, i + j);
ppu_read(d, j * banksize, banksize);
}
}
}
function program_initalize(d, cpu_banksize, ppu_banksize)
{
cpu_write(d, 0x8008, 0x00);
cpu_command(d, 0x0000, 0x8000, cpu_banksize);
cpu_command(d, 0x02aa, 0xc000, cpu_banksize);
cpu_command(d, 0x0555, 0xc000, cpu_banksize);
cpu_write(d, 0x8000, [0x0a, 0x15, 0]);
ppu_command(d, 0x2aaa, 0, ppu_banksize);
ppu_command(d, 0x5555, 0x0400, ppu_banksize);
ppu_command(d, 0, 0x0800, ppu_banksize);
}
function cpu_transfer(d, start, end, cpu_banksize)
{
for(local i = start; i < end - 1; i +=1){
cpu_write(d, 0x8008, i);
cpu_program(d, 0x8000, cpu_banksize);
}
cpu_program(d, 0xc000, cpu_banksize);
}
function ppu_transfer(d, start, end, ppu_banksize)
{
for(local i = start; i < end; i +=4){
cpu_write(d, 0x8004, [i, i+1, i+2, i+3]);
ppu_program(d, 0x1000, ppu_banksize * 4);
}
}
/*
$800d
7 data direction 0:FCG3->EEPROM (write), 1:EEPROM->FCG3 (read)
6 data, FCG3 -> EEPROM
5 clock
$6000-$7fff
4 data, EEPROM -> FCG3
*/
const I2C_READBIT = 4;
const I2C_DIRBIT = 7;
const I2C_WRITEBIT = 6;
const I2C_CLOCKBIT = 5;
I2C_DIR_READ <- 1 << I2C_DIRBIT;
I2C_DIR_WRITE <- 0 << I2C_DIRBIT;
I2C_SEND_H <- 1 << I2C_WRITEBIT;
I2C_SEND_L <- 0 << I2C_WRITEBIT;
I2C_CLOCK_H <- 1 << I2C_CLOCKBIT;
I2C_CLOCK_L <- 0 << I2C_CLOCKBIT;
function i2c_start(d)
{
cpu_write(d, 0x800d, I2C_DIR_WRITE | I2C_CLOCK_L | I2C_SEND_L);
cpu_write(d, 0x800d, I2C_DIR_WRITE | I2C_CLOCK_L | I2C_SEND_H);
cpu_write(d, 0x800d, I2C_DIR_WRITE | I2C_CLOCK_H | I2C_SEND_H);
cpu_write(d, 0x800d, I2C_DIR_WRITE | I2C_CLOCK_H | I2C_SEND_L);
cpu_write(d, 0x800d, I2C_DIR_WRITE | I2C_CLOCK_L | I2C_SEND_L);
}
function i2c_stop(d)
{
cpu_write(d, 0x800d, I2C_DIR_WRITE | I2C_CLOCK_L | I2C_SEND_L);
cpu_write(d, 0x800d, I2C_DIR_WRITE | I2C_CLOCK_H | I2C_SEND_L);
cpu_write(d, 0x800d, I2C_DIR_WRITE | I2C_CLOCK_H | I2C_SEND_H);
cpu_write(d, 0x800d, I2C_DIR_WRITE | I2C_CLOCK_L | I2C_SEND_H);
cpu_write(d, 0x800d, I2C_DIR_READ | I2C_CLOCK_L | I2C_SEND_H);
}
function i2c_ack_wait(d)
{
cpu_write(d, 0x800d, I2C_DIR_WRITE | I2C_CLOCK_L | I2C_SEND_H);
cpu_write(d, 0x800d, I2C_DIR_READ | I2C_CLOCK_H | I2C_SEND_L);
local n = cpu_read_register(d, 0x6000, 0);
n = n & (1 << I2C_READBIT);
return n == 0;
}
function send_bit(d, v)
{
cpu_write(d, 0x800d, I2C_DIR_WRITE | I2C_CLOCK_L | I2C_SEND_L);
cpu_write(d, 0x800d, I2C_DIR_WRITE | I2C_CLOCK_L | v);
cpu_write(d, 0x800d, I2C_DIR_WRITE | I2C_CLOCK_H | v);
}
function i2c_address_set(d, address, rw)
{
do{
local a = address;
i2c_start(d);
for(local i = 0; i < 7; i++){
send_bit(d, a & I2C_SEND_H);
a = a << 1;
}
send_bit(d, rw);
}while(i2c_ack_wait(d) != true);
}
function eeprom_address_set(d, address)
{
for(local i = 0; i < 8; i++){
local n = I2C_SEND_L;
if(address & 0x80){
n = I2C_SEND_H;
}
send_bit(d, n);
address = address << 1;
}
i2c_ack_wait(d);
}
However I always get this error whenever I run either of the scripts:
Code: Select all
AN ERROR HAS OCCURRED [the index 'dofile' does not exist]
CALLSTACK
*FUNCTION [main()] bandai_lz93d50_x24c01.ag line [32]
LOCALS
[vargv] ARRAY
[this] TABLE
bandai_lz93d50_x24c01.ag open error
Don't know if it makes any difference, but I'm running this via a port in Linux I found
here. I haven't had any issues with some other scripts (CNROM, NROM, etc), though, so I don't think my OS is the problem. Any ideas?