It is currently Fri Oct 19, 2018 5:07 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 656 posts ]  Go to page Previous  1 ... 40, 41, 42, 43, 44
Author Message
PostPosted: Sat Oct 13, 2018 12:55 am 
Offline

Joined: Sun Apr 13, 2008 11:12 am
Posts: 7671
Location: Seattle
Yup!

werewolfslayr925 wrote:
board <- {
mappernum = 26, vram_mirrorfind = false, ppu_ramfind = true
cpu_rom = {size_base = 2 * mega, size_max = 4 * mega, banksize = 0x2000},
ppu_rom = {size_base = 2 * mega, size_max = 2 * mega, banksize = 0x0400},
}
Every NES cartridge has two places for memory: the CPU and the PPU.
On the cartridge, the CPU must always be able to see ROM but may additionally have RAM ; the PPU may have either, or very rarely, both.
"ppu_ramfind" does exactly what it says: find out if the cartridge has RAM for the PPU, and if so, skip the PPU ROM dumping stage.

The PPU can use the data it sees in one of two different ways: one is a set of small 8x8 pictures (a "pattern table") ; the other is how those 8x8 pictures are arranged on the screen (a "name table"). The NES includes RAM inside for the purpose of holding these name tables, but only two. However, it can logically address four nametables, so those two name tables have to be arranged into four slots. Different cartridges provide different arrangements.
"vram_mirrorfind" is specifically used when the arrangement is a fixed function of the physical cartridge, instead of extra hardware on the cartridge making it adjustable as the game progresses. (hardware like NROM, CNROM, GNROM, among many others)

For each of the CPU and PPU roms:
size_base is the smallest dump to even begin trying to dump.
"mega" is 1048576 bits, or 131072 bytes.
size_max is the largest size ROM to ever support

A game for the NES could use up to 32 KiB of ROM for the CPU, and 8 KiB of ROM for the PPU. This got cramped quickly, and so people decided it'd be useful to add ICs to the game board that allows the game to see multiple different chunks of ROM at the same time. These "mappers" are where the name came from.
Different "mappers" support different divisions; from something like ANROM which can has to switch all 32 KiB at the same time (hence "banksize" = 0x8000) to something smaller like MMC3, which can switch 8 KiB at a time (hence banksize = 0x2000).
Similar constraints exist for PPU memory, ranging from CNROM's 8 KiB (banksize = 0x2000) down to MMC3's 1 KiB (banksize = 0x400).


Top
 Profile  
 
PostPosted: Sat Oct 13, 2018 8:46 am 
Offline

Joined: Sat Oct 02, 2010 5:49 pm
Posts: 38
Okay, that's all nice and kind of explains the numbers and commands towards the top of the script. What about all the stuff underneath that? And how do I get this all to function for the VRC6 or any other board? Is there a clear formula I can use to just plug in numbers?

EDIT: Okay, so taking another look at the commentary on the script, I'm guessing that the information there is for the "function cpu_dump" and "function ppu_dump" commands. How do I convert that information to a language the kazzo/anago program can understand?

What's the difference between "cpu_write" and "cpu_read"? How does the "for(local i = 0 etc.)" thing work into this?

See the problem? I'm not a programmer, and I don't understand this.


Top
 Profile  
 
PostPosted: Sat Oct 13, 2018 1:20 pm 
Offline

Joined: Sun Apr 13, 2008 11:12 am
Posts: 7671
Location: Seattle
werewolfslayr925 wrote:
What's the difference between "cpu_write" and "cpu_read"? How does the "for(local i = 0 etc.)" thing work into this?
Anago uses a scripting language called "Squirrel" which looks similar to the C programming language. So a lot of these choices are explicitly designed to be familiar to someone who's already programmed in C, instead of anything else.

The NES's CPU and PPU both have the ability to "read" (get data from) and "write" (put data into) their associated memory.

These "mapper" ICs need to be configured by the game as the game progresses so that the game can read the data it wants to. This is almost always done by having the CPU write specific numbers to specific locations. But the very reason that we have several hundred different mappers is because so many different IC were used.

For example, one of the simplest mappers is CNROM. The corresponding script is similarly simple:

1- CNROM doesn't support more than 32 KiB of PRG, so:
1a- cpu_rom = { size_base = 0x8000, size_max = 0x8000, banksize = 0x8000 },
1b- function cpu_dump(d, pagesize, banksize) { cpu_read(d, 0x8000, 0x4000); cpu_read(d, 0xc000, 0x4000); }

(For some random reason, Anago doesn't support reading 32 KiB at a time, so dumping scripts must instead "read the first 16 KiB, then read the following 16 KiB")

2- CNROM supports four 8 KiB CHR banks, so:
2a- ppu_rom = { size_base = 0x8000, size_max = 0x8000, banksize = 0x2000 },
2b- function ppu_dump(d, pagesize, banksize) { for(local i = 0; i < pagesize; i++) { cpu_write(d, 0x8000, i); ppu_read(d, 0, banksize); }}},

Confusing naming: "pagesize" is the number of pages, not the size of the page. (it's the size in terms of pages)

The word "for" means "do the following bit some number of times". In this specific case, the "for ( local i = 0; i < pagesize; i++)" means "do this pagesize times, and the variable 'i' should have the value 0,1,2 ... up through one less than pagesize"

cpu_write(d, 0x8000, N); means "pretend to be the NES's CPU, and write the number i to the address 0x8000". By comparing against our documentation on the wiki, this should select the Nth bank.
ppu_read(d, 0, BANKSIZE); means "pretend to be the NES's PPU, and read BANKSIZE bytes starting at address 0 and going up"

Does this make sense?


Honestly, I was just hoping you might understand enough to be able to understand how to modernize the VRC6 script for the newer runtime, not wanting you to figure this all out on your own. I'm perfectly happy to continue helping with random new scripts.

(Have you encountered hexadecimal before?)


Top
 Profile  
 
PostPosted: Sat Oct 13, 2018 2:13 pm 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 20674
Location: NE Indiana, USA (NTSC)
Would it be legal to name the pagesize variable pagecount instead?


Top
 Profile  
 
PostPosted: Sat Oct 13, 2018 3:51 pm 
Offline

Joined: Sat Oct 02, 2010 5:49 pm
Posts: 38
lidnariq wrote:
Anago uses a scripting language called "Squirrel" which looks similar to the C programming language. So a lot of these choices are explicitly designed to be familiar to someone who's already programmed in C, instead of anything else.


I'm very unfamiliar with any programming language, really. I can make a some sense of a small fraction of what's going on, but only in the way that I know a handful of words in Greek or a tiny bit of kanji. I never studied this, never got pushed to do so, and don't really have the desire.

Quote:
The NES's CPU and PPU both have the ability to "read" (get data from) and "write" (put data into) their associated memory.

These "mapper" ICs need to be configured by the game as the game progresses so that the game can read the data it wants to. This is almost always done by having the CPU write specific numbers to specific locations. But the very reason that we have several hundred different mappers is because so many different IC were used.


Right! This I understand. I've read about it and discussed this with friends who are more knowledgeable about the hardware than I am.

Quote:
For example, one of the simplest mappers is CNROM. The corresponding script is similarly simple:

1- CNROM doesn't support more than 32 KiB of PRG, so:
1a- cpu_rom = { size_base = 0x8000, size_max = 0x8000, banksize = 0x8000 },
1b- function cpu_dump(d, pagesize, banksize) { cpu_read(d, 0x8000, 0x4000); cpu_read(d, 0xc000, 0x4000); }


Quote:
(For some random reason, Anago doesn't support reading 32 KiB at a time, so dumping scripts must instead "read the first 16 KiB, then read the following 16 KiB")


Okay, so the italicized bit explains something that's been puzzling me for a long time. Thanks for pointing that out.

2- CNROM supports four 8 KiB CHR banks, so:
2a- ppu_rom = { size_base = 0x8000, size_max = 0x8000, banksize = 0x2000 },
2b- function ppu_dump(d, pagesize, banksize) { for(local i = 0; i < pagesize; i++) { cpu_write(d, 0x8000, i); ppu_read(d, 0, banksize); }}},

Confusing naming: "pagesize" is the number of pages, not the size of the page. (it's the size in terms of pages)

The word "for" means "do the following bit some number of times". In this specific case, the "for ( local i = 0; i < pagesize; i++)" means "do this pagesize times, and the variable 'i' should have the value 0,1,2 ... up through one less than pagesize"

cpu_write(d, 0x8000, N); means "pretend to be the NES's CPU, and write the number i to the address 0x8000". By comparing against our documentation on the wiki, this should select the Nth bank.
ppu_read(d, 0, BANKSIZE); means "pretend to be the NES's PPU, and read BANKSIZE bytes starting at address 0 and going up"

Does this make sense?[/quote]

This part, not so much. I'm sorry :(

Quote:
(Have you encountered hexadecimal before?)


Of course. I make chiptunes using LSDJ. I also play lots of Japanese games which involves patching them and tweaking said patches in a hex editor. I've also tried my hand at translating a game which involved lots of hex-level editing.

I'm familiar with the hexadecimal numbering system. I get the amounts the numbers represent for the most part in the context of the Kazzo. I just don't understand the programming very well because I never formally studied programming nor did I ever successfully teach myself. Like I said, every time I try or someone tries to teach me, it's never done in a way I can grasp; I'm never given a clear paradigm for understanding a programming language.

Quote:
Honestly, I was just hoping you might understand enough to be able to understand how to modernize the VRC6 script for the newer runtime, not wanting you to figure this all out on your own. I'm perfectly happy to continue helping with random new scripts.


That's really generous of you. I really wouldn't know where to begin with the VRC6 script (obviously). I'm sorry I'm ignorant of the programming aspect of this :( How should I change the script that I've got?


Top
 Profile  
 
PostPosted: Sat Oct 13, 2018 4:35 pm 
Offline

Joined: Sun Apr 13, 2008 11:12 am
Posts: 7671
Location: Seattle
werewolfslayr925 wrote:
This part, not so much. I'm sorry :(
Hm.

How about:

"the code in the cpu_dump and ppu_dump sections are instructions how to imitate the NES's CPU in order to get data off the cartridge" ?

The specifics have to do with how each individual mapper works. Using the same example, CNROM says "display PPU bank # N when the game writes N to its 'register'". So the ppu_dump section says "count through every useful value of N, tell the cartridge to display that section, then retrieve that data to the computer"

Quote:
Like I said, every time I try or someone tries to teach me, it's never done in a way I can grasp; I'm never given a clear paradigm for understanding a programming language.
In my experience, having a big enough incentive is often the difference. Unfortunately, Squirrel isn't really a good choice for starting...

Quote:
I really wouldn't know where to begin with the VRC6 script (obviously). How should I change the script that I've got?
Right now, you have the bit at the very top (the stuff between /* */, a "comment" that is ignored by Anago) from the VRC6 script, and the rest is the MMC3 script. So that explains what went wrong.

You should hopefully be able to just start with the existing VRC6 script, change just the very first bit ("board", "mappernum", "cpu_rom", "ppu_rom") to look right, and shouldn't have to change the rest of the VRC6 script.


Top
 Profile  
 
PostPosted: Tue Oct 16, 2018 5:13 pm 
Offline

Joined: Sat Oct 02, 2010 5:49 pm
Posts: 38
lidnariq wrote:
werewolfslayr925 wrote:
This part, not so much. I'm sorry :(
Hm.

How about:

"the code in the cpu_dump and ppu_dump sections are instructions how to imitate the NES's CPU in order to get data off the cartridge" ?


I think that makes more sense.

Quote:
Right now, you have the bit at the very top (the stuff between /* */, a "comment" that is ignored by Anago) from the VRC6 script, and the rest is the MMC3 script. So that explains what went wrong.

You should hopefully be able to just start with the existing VRC6 script, change just the very first bit ("board", "mappernum", "cpu_rom", "ppu_rom") to look right, and shouldn't have to change the rest of the VRC6 script.


Okay, so, here's what I got on my own (I'm not sure the numbers are right, because I'm not sure how to convert e.g. 256K as it says on the wiki to hex):

Code:
/*VRC6 type B/351949A/address bus A0=R1, A1=R0
CPU memory bank
cpu address|rom address    |page|task
$8000-$bfff|n * 0x4000     |even|write area + write 0x2aaa
$c000-$dfff|0x04000-0x05fff|2   |write 0x5555
-------------------------------------
$8000-$bfff|n * 0x4000     |odd |write area + write 0x5555
$c000-$dfff|0x02000-0x03fff|1   |write 0x2aaa
$e000-$efff|末尾           |fix |boot area, 未使用

PPU memory bank
ppu address|rom address    |page|task
$0000-$03ff|0x02800-0x02bff|0x0a|write (0x2aaa & 0x03ff) + 0
$0400-$07ff|0x05400-0x057ff|0x15|write (0x5555 & 0x03ff) + 0x400
$1000-$1fff|n * 0x1000     |n   |write area*/


board <- {

   mappernum = 26, vram_mirrorfind = false,
 ppu_ramfind = true
   cpu_rom = {size_base = 0x2000, size_max = 0x4000,
      banksize = 0x4000},

   ppu_rom = {size_base = 0x2000, size_max = 0x4000,
      banksize = 0x0400}

}


function cpubank_even_set(d, bank, cpu_banksize)

{

   cpu_command(d, 0x2aaa, 0x8000, cpu_banksize);

   cpu_command(d, 0x5555, 0xc000, 0x2000);

   cpu_write(d, 0x8000, bank)
   cpu_write(d, 0xc000, 2)

}


function initalize(d, cpu_banksize, ppu_banksize)

{

   cpubank_even_set(d, 0, cpu_banksize);

   cpu_command(d, 0, 0x8000, cpu_banksize);


   ppu_command(d, 0x2aaa, 0, ppu_banksize);

   ppu_command(d, 0x5555, 0x0400, ppu_banksize);

   ppu_command(d, 0, 0x0800, ppu_banksize);


   cpu_write(d, 0xb003, 0); //work ram disable

   cpu_write(d, 0xd000, 0x0a);

   cpu_write(d, 0xd002, 0x15);

   cpu_write(d, 0xd001, 0x00);

   cpu_write(d, 0xd003, 0x00);

}


function cpu_transfer(d, start, end, cpu_banksize)

{

   local i;
   for(i = start; i < end - 2; i += 2)
   {

      cpubank_even_set(d, i, cpu_banksize);

      cpu_program(d, 0x8000, cpu_banksize);


      cpu_command(d, 0x5555, 0x8000, cpu_banksize);

      cpu_command(d, 0x2aaa, 0xc000, 0x2000);

      cpu_write(d, 0x8000, i | 1)

      cpu_write(d, 0xc000, 1)

      cpu_program(d, 0x8000, cpu_banksize);

   }

   cpubank_even_set(d, i, cpu_banksize);

   cpu_program(d, 0x8000, cpu_banksize);


   cpu_command(d, 0x5555, 0x8000, cpu_banksize);

   cpu_command(d, 0x2aaa, 0xc000, 0x2000);
   cpu_write(d, 0x8000, i | 1)
   cpu_write(d, 0xc000, 1)

   cpu_program(d, 0x8000, cpu_banksize);

}



function ppu_transfer(d, start, end, ppu_banksize)

{

   for(local i = start; i < end; i += 4)
   {

      cpu_write(d, 0xe000, i | 0);
   
      cpu_write(d, 0xe002, i | 1);

      cpu_write(d, 0xe001, i | 2);

      cpu_write(d, 0xe003, i | 3);

      ppu_program(d, 0x1000, ppu_banksize * 4);

   }

}


Unfortunately, the command prompt says that "the index 'cpu_dump' does not exist. I assume that means I have to give a command for "cpu_dump" (and ppu_dump as well) which I'm unsure how to do.


Honest question: if this is so easy for programmers and arantius has the scripts up on his GitHub, why don't these work? Why are the scripts incomplete?


Top
 Profile  
 
PostPosted: Tue Oct 16, 2018 5:27 pm 
Offline

Joined: Sun Apr 13, 2008 11:12 am
Posts: 7671
Location: Seattle
.......

I'm just gonna be super embarrassed for a moment, because I hadn't looked closely enough to notice that the "konami_vrc6.af" file is only for programming Flash memory transplanted onto a VRC6-using cart, not for downloading the contents of VRC6-using carts.

My fault.


Here's a quick & dirty attempt at a VRC6a/b dumping script:

(change mappernum to 24 for VRC6a; no other changes should be necessary)
Code:
board <- {
  mappernum = 26,
  cpu_rom = { size_base = 262144, size_max = 262144, banksize = 0x4000 },
  ppu_rom = { size_base = 131072, size_max = 262144, banksize = 0x400 },
  ppu_ramfind = false, vram_mirrorfind = false
};

function cpu_dump(d, pagesize, banksize) {
  for (local i = 0; i < pagesize - 1; i += 1) {
    cpu_write(d, 0x8000, i);
    cpu_read(d, 0x8000, banksize);
  }
  cpu_write(d, 0xc000, 0xFE);
  cpu_read(d, 0xc000, banksize);
}

function ppu_dump(d, pagesize, banksize) {
  cpu_write(d, 0xB003, 0x20);
  for (local i = 0; i < pagesize; i += 1) {
    cpu_write(d, 0xD000, i);
    ppu_read(d, 0, banksize);
  }
}
edit: fix ppu_rom / cpu_rom


Last edited by lidnariq on Tue Oct 16, 2018 6:15 pm, edited 1 time in total.

Top
 Profile  
 
PostPosted: Tue Oct 16, 2018 5:59 pm 
Offline

Joined: Sat Oct 02, 2010 5:49 pm
Posts: 38
lidnariq wrote:
.......

I'm just gonna be super embarrassed for a moment, because I hadn't looked closely enough to notice that the "konami_vrc6.af" file is only for programming Flash memory transplanted onto a VRC6-using cart, not for downloading the contents of VRC6-using carts.

My fault.


Here's a quick & dirty attempt at a VRC6a/b dumping script:

(change mappernum to 24 for VRC6a; no other changes should be necessary)
Code:
board <- {
  mappernum = 26,
  cpu_romsize = 2 * mega, cpu_banksize = 0x4000,
  ppu_romsize = 2 * mega, ppu_banksize = 0x400,
  ppu_ramfind = false, vram_mirrorfind = false
};

function cpu_dump(d, pagesize, banksize) {
  for (local i = 0; i < pagesize - 1; i += 1) {
    cpu_write(d, 0x8000, i);
    cpu_read(d, 0x8000, banksize);
  }
  cpu_write(d, 0xc000, 0xFE);
  cpu_read(d, 0xc000, banksize);
}

function ppu_dump(d, pagesize, banksize) {
  cpu_write(d, 0xB003, 0x20);
  for (local i = 0; i < pagesize; i += 1) {
    cpu_write(d, 0xD000, i);
    ppu_read(d, 0, banksize);
  }
}


Okay, now the file types make sense to me:

.af = Anago Flash (for cart flashing)
.ad = Anago Dump (for dumping carts)
.ag = Anago ??? (typo maybe?)

Anyway...

The script you posted gave me the usual "cpu_rom does not exist", "ppu_rom does not exist", etc. errors, so I modified it accordingly to the best of my ability:

Code:
board <- {
   mappernum = 26, vram_mirrorfind = false,
 ppu_ramfind = true
   cpu_rom = {size_base = 0x2000, size_max = 0x4000,
      banksize = 0x4000},

   ppu_rom = {size_base = 0x2000, size_max = 0x4000,
      banksize = 0x0400}

};

function cpu_dump(d, pagesize, banksize) {
  for (local i = 0; i < pagesize - 1; i += 1) {
    cpu_write(d, 0x8000, i);
    cpu_read(d, 0x8000, banksize);
  }
  cpu_write(d, 0xc000, 0xFE);
  cpu_read(d, 0xc000, banksize);
}

function ppu_dump(d, pagesize, banksize) {
  cpu_write(d, 0xB003, 0x20);
  for (local i = 0; i < pagesize; i += 1) {
    cpu_write(d, 0xD000, i);
    ppu_read(d, 0, banksize);
  }
}


At this point it gave me an error that said:

Code:
cpu_romsize is not connected 0x004000/0x002000

AN ERROR HAS OCCURED [script logical error]

CALLSTACK
*FUNCTION [dump()] dumpcore.nut line [47]

LOCALS
[ppu_dumpsize] 8192
[cpu_dumpsize] 8192
[ppuarea_memory] 0
[vram] 0
[increase_ppu] 1
[increase_cpu] 1
[mappernum] 26
[script] "vrc6.ad"
[d] USERPOINTER
[this] TABLE



EDIT: Whoops! Just saw your edit. Dumping now...

...and we have a correct CPU dump! PPU is off, though: CRC32 = 297fa51a...


Last edited by werewolfslayr925 on Tue Oct 16, 2018 6:28 pm, edited 1 time in total.

Top
 Profile  
 
PostPosted: Tue Oct 16, 2018 6:28 pm 
Offline

Joined: Sun Apr 13, 2008 11:12 am
Posts: 7671
Location: Seattle
werewolfslayr925 wrote:
Okay, now the file types make sense to me:

.af = Anago Flash (for cart flashing)
.ad = Anago Dump (for dumping carts)
.ag = Anago ??? (typo maybe?)
also .ae ... and .ai (i = Include?)

I initially found a few .ag with both flashing and dumping support, but ... not all of them, so...

Quote:
cpu_rom = {size_base = 0x2000, size_max = 0x4000, banksize = 0x4000},
ppu_rom = {size_base = 0x2000, size_max = 0x4000, banksize = 0x0400}
Those numbers are wrong, unfortunately. Maybe I should try using decimal; it's obvious what 262144 is, in ways that 2*mega and 0x40000 aren't.

I edited my previous post to use the correct terminology.

Quote:
At this point it gave me an error that said:

Code:
cpu_romsize is not connected 0x004000/0x002000
I ... don't know what to do with that. I don't understand why sometimes it uses one set (Xpu_romsize) and sometimes the other (Xpu_rom.size_base). I assume this is two different versions of the client, but really don't know.

... unless in this specific case it's saying that you can't have a size_base smaller than 0x4000 (16KiB, the smallest supported by the .nes fileformat)?


Top
 Profile  
 
PostPosted: Tue Oct 16, 2018 6:40 pm 
Offline

Joined: Sat Oct 02, 2010 5:49 pm
Posts: 38
lidnariq wrote:
I edited my previous post to use the correct terminology.

I noticed! We have a correct CPU dump! However, the PPU dump is off and the title screen is glitchy. CRC32 is 297fa51a.

EDIT: WAIT! SPOKE TOO SOON! I doubled the PPU dump
Code:
anago.exe d12 vrc6.ad madara.nes

and it gave a dump that matches bootgod's database!! So here's a script for Madara (and the other VRC6b game):
Code:
/*
This script requires a doubled PPU dump

Use the following command in Anago:

anago.exe d12 [script_name].ad [file_name].nes
*/

board <- {
  mappernum = 26,
  cpu_rom = { size_base = 262144, size_max = 262144, banksize = 0x4000 },
  ppu_rom = { size_base = 131072, size_max = 262144, banksize = 0x400 },
  ppu_ramfind = false, vram_mirrorfind = false
};

function cpu_dump(d, pagesize, banksize) {
  for (local i = 0; i < pagesize - 1; i += 1) {
    cpu_write(d, 0x8000, i);
    cpu_read(d, 0x8000, banksize);
  }
  cpu_write(d, 0xc000, 0xFE);
  cpu_read(d, 0xc000, banksize);
}

function ppu_dump(d, pagesize, banksize) {
  cpu_write(d, 0xB003, 0x20);
  for (local i = 0; i < pagesize; i += 1) {
    cpu_write(d, 0xD000, i);
    ppu_read(d, 0, banksize);
  }
}


Is anyone able to test this on a copy of Akumajou Densetsu and/or Esper Dream 2?


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 656 posts ]  Go to page Previous  1 ... 40, 41, 42, 43, 44

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 3 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group