User:Myask/Universal Mapper Description Language: Difference between revisions

From NESdev Wiki
Jump to navigationJump to search
m (→‎Needed features: remove Ouroboros)
(→‎Specification: wikiformatting, small updates)
Line 24: Line 24:
=Specification=
=Specification=
===Comments===
===Comments===
//c-style
//c-style
/*and c-style*/
/*and c-style*/
//Let's also treat all whitespace the same (except newlines terminating //, blocks)
//Let's also treat all whitespace the same (except newlines terminating //, blocks)
//and "to" should be ignored in whitespace
//and "to" should be ignored in whitespace


===Declarations: ===
===Declarations: ===
mapper name begin
mapper name begin
//contents
//contents
end name;
end name;
The outer part. Technically a block started with begin/end. Name optional.
The outer part. Technically a block started with begin/end. Name optional.


mem name (address lines, data lines, writable, class);
mem name (address lines, data lines, writable, class);
-writable can be RAM or ROM.
*writable can be RAM or ROM.
-Class can be PRG, CHR, VRAM, [audio?] and MISC. Class controls default connections, and helps make obvious to readers what a thing is.
*Class can be PRG, CHR, VRAM, [audio?] and MISC. Class controls default connections, and helps make obvious to readers what a thing is.
(see NROM example for default connections. Any prg gets CPU_A, CPU_D, /ROMSEL ("ROMSEL_n"), and optionally the R/W signal if it's a RAM. chr/vram gets PPU_A, PPU_D, read/writes, and enable depending on PPU_A[13] (or /A13 if VRAM)
(see NROM example for default connections. Any prg gets CPU_A, CPU_D, /ROMSEL ("ROMSEL_n"), and optionally the R/W signal if it's a RAM. chr/vram gets PPU_A, PPU_D, read/writes, and enable depending on PPU_A[13] (or /A13 if VRAM)


solder name to /*contents*/; //can block if desired
solder name to /*contents*/; //can block if desired
dip name to /*contents*/; //can block if desired: same as solder for emulator
dip name to /*contents*/; //can block if desired: same as solder for emulator
//dipswitch
*dipswitch
//just different name, really both just a state-based if statement
Just different name, really both just a state-based if statement, and these state bits are not settable except hardware(emulator)-side, unlike…
//and these state bits are not settable except hardware(emulator)-side
register name;  
register name;  
reg name;//short form
reg name;//short form


init name to value; //can refer to iNES header fields like mirroring
init name to value; //can refer to iNES header fields like mirroring
Not that iNES is something we want much of, but it'll cut down on file redundancy.


===Statements:===
===Statements:===
connect x to y to z; //any size netlist, whitespace-separated
connect x to y to z; //any size netlist, whitespace-separated
= x y z; //shortform
= x y z; //shortform
set name to value; //set a state bit
set name to value; //set a state bit
<= x y; //shortform
<= x y; //shortform
===Operators===
===Operators===
bitwise &AND |OR ^XOR ~invert
bitwise & AND | OR ^ XOR ~ invert
logical &&AND ||OR ^^XOR !not
logical &&AND ||OR ^^XOR !not
mathematical + - * binary operations, -negation
mathematical + - * binary operations, -negation
{concatenate, concatenatee} [bus-index:range] {3 duplicate} //as in verilog
<nowiki>{concatenate, concatenatee} [bus-index:range] {3 duplicate} //as in verilog</nowiki>
===Execution blocks===
===Execution blocks===
on CPU_WRITE /*do stuff*/;
on CPU_WRITE /*do stuff*/;
on PPU_WRITE
on PPU_WRITE
on CPU_READ
on CPU_READ
on PPU_READ
on PPU_READ
on CLOCK
on CLOCK
===Handy Shorthand Defines===
===Handy Shorthand Defines===
bankreg name (which bus, width, address lines left on, address lines replaced, address mask selecting=equals what, which bus to write [inc A or D to write], mask to write, written bits);
bankreg name (which bus, width, address lines left on, address lines replaced, address mask selecting=equals what, which bus to write [inc A or D to write], mask to write=equals what,, written bits);
fixedbank (which bus, width, address lines left on, address lines replaced=with what, address mask selecting=equals what);
e.g.
e.g.
bankreg BNROM (CPU, 2, 14:0, 16:15, 16'h8000=16'h8000, CPU_D, 16'h8000, CPU_D[1:0]);
bankreg bnrom (CPU, 2, 14:0, 16:15, 16'h8000=16'h8000, CPU_D, 16'h8000=16'h8000, CPU_D[1:0]);
bankreg BxROM (CPU, 8, 14:0, 22:15, 16'h8000=16'h8000, CPU_D, 16'h8000, CPU_D[7:0]);
 
bankreg bxrom (CPU, 8, 14:0, 22:15, 16'h8000=16'h8000, CPU_D, 16'h8000=16'h8000, CPU_D[7:0]);
 
bankreg gnrom_cpu (CPU, 2, 14:0, 16:15, 16'h8000=16'h8000, CPU_D, 16'h8000=16'h8000, CPU_D[5:4]);
bankreg gnrom_ppu (PPU, 2, 12:0, 14:13, 16'h2000=16'h0000, CPU_D, 16'h8000=16'h8000, CPU_D[1:0]);
 
bankreg magic_series_cpu (CPU, 7, 14:0, 21:15, 16'h8000=16'h8000, CPU_D, 16'h8000=16'h8000, CPU_D[7:1]);
bankreg magic_series_ppu (PPU, 8, 12:0, 20:13, 16'h2000=16'h0000, CPU_D, 16'h8000=16'h8000, CPU_D[7:0]);
 
bankreg unrom (CPU, 3, 13:0, 16:14, 16'hC000=16'h8000, CPU_D, 16'h8000=16'h8000, CPU_D[2:0]);
fixedbank unrom_hi (CPU, 3, 13:0, 16:14=3'b111, 16hC000=16'hC000);


bankreg GNROM_CPU (CPU, 2, 14:0, 16:15, 16'h8000=16'h8000, CPU_D, 16'h8000, CPU_D[5:4]);
bankreg GNROM_PPU (PPU, 2, 12:0, 14:13, 16'h2000=16'h0000, CPU_D, 16'h8000, CPU_D[1:0]);
=[[NROM]]-256 example=
=[[NROM]]-256 example=
  mapper NROM_256V begin
  mapper NROM_256V begin

Revision as of 23:08, 15 July 2016

Needed features

Been thinking about making some better way to talk about mappers, as described in this post among several other places on our boards. Parts/functions

  • Define state bits
    • include easy ROM/RAM chip(/internal) declaration; don't want to exclude MagicFloor nor MMC5/6 from "correct" description
  • Logic
  • Arbitrary address bus size for chips?

Convenience addtions

  • Conditional operations (optional but helps user-side…but makes it harder program-side)
    • some header fields as parameters might be desirable (mirroring, chip sizes)
    • on the other hand, they are different boards in some manner. Perhaps only as solder-pad options?
  • Cartridge connector pins as predefined signal names, or a module (to allow picking 60 or 72-pin)
  • Option to autoconnect power, ground, address lines that are not in file
    • like connecting PPU_A[0:7] to CHR_ROM_A[0:7] if CHR_ROM_A[0:7] do not appear in the description)
    • Also autoconnect CIC

Extra function thoughts

  • Outputs (e.g. LED)
  • Inputs (e.g. DIPswitch, solder pads)
  • Describing expansion port devices in similar manner
  • Describing controller port devices in similar manner

Hard Part

  • Expansion audio (analog, can involve extra oscillators as VRC7 audio does)

Specification

Comments

//c-style
/*and c-style*/
//Let's also treat all whitespace the same (except newlines terminating //, blocks)
//and "to" should be ignored in whitespace

Declarations:

mapper name begin
//contents
end name;

The outer part. Technically a block started with begin/end. Name optional.

mem name (address lines, data lines, writable, class);
  • writable can be RAM or ROM.
  • Class can be PRG, CHR, VRAM, [audio?] and MISC. Class controls default connections, and helps make obvious to readers what a thing is.

(see NROM example for default connections. Any prg gets CPU_A, CPU_D, /ROMSEL ("ROMSEL_n"), and optionally the R/W signal if it's a RAM. chr/vram gets PPU_A, PPU_D, read/writes, and enable depending on PPU_A[13] (or /A13 if VRAM)

solder name to /*contents*/; //can block if desired
dip name to /*contents*/; //can block if desired: same as solder for emulator
  • dipswitch

Just different name, really both just a state-based if statement, and these state bits are not settable except hardware(emulator)-side, unlike…

register name; 
reg name;//short form
init name to value; //can refer to iNES header fields like mirroring

Not that iNES is something we want much of, but it'll cut down on file redundancy.

Statements:

connect x to y to z; //any size netlist, whitespace-separated
= x y z; //shortform
set name to value; //set a state bit
<= x y; //shortform

Operators

bitwise & AND | OR ^ XOR ~ invert
logical &&AND ||OR ^^XOR !not
mathematical + - * binary operations, -negation
{concatenate, concatenatee} [bus-index:range] {3 duplicate} //as in verilog

Execution blocks

on CPU_WRITE /*do stuff*/;
on PPU_WRITE
on CPU_READ
on PPU_READ
on CLOCK

Handy Shorthand Defines

bankreg name (which bus, width, address lines left on, address lines replaced, address mask selecting=equals what, which bus to write [inc A or D to write], mask to write=equals what,, written bits);
fixedbank (which bus, width, address lines left on, address lines replaced=with what, address mask selecting=equals what);

e.g.

bankreg bnrom (CPU, 2, 14:0, 16:15, 16'h8000=16'h8000, CPU_D, 16'h8000=16'h8000, CPU_D[1:0]);
bankreg bxrom (CPU, 8, 14:0, 22:15, 16'h8000=16'h8000, CPU_D, 16'h8000=16'h8000, CPU_D[7:0]);
bankreg gnrom_cpu (CPU, 2, 14:0, 16:15, 16'h8000=16'h8000, CPU_D, 16'h8000=16'h8000, CPU_D[5:4]);
bankreg gnrom_ppu (PPU, 2, 12:0, 14:13, 16'h2000=16'h0000, CPU_D, 16'h8000=16'h8000, CPU_D[1:0]);
bankreg magic_series_cpu (CPU, 7, 14:0, 21:15, 16'h8000=16'h8000, CPU_D, 16'h8000=16'h8000, CPU_D[7:1]);
bankreg magic_series_ppu (PPU, 8, 12:0, 20:13, 16'h2000=16'h0000, CPU_D, 16'h8000=16'h8000, CPU_D[7:0]);
bankreg unrom (CPU, 3, 13:0, 16:14, 16'hC000=16'h8000, CPU_D, 16'h8000=16'h8000, CPU_D[2:0]);
fixedbank unrom_hi (CPU, 3, 13:0, 16:14=3'b111, 16hC000=16'hC000);

NROM-256 example

mapper NROM_256V begin
 //without autofills
 //aside from the mirroring, strikes me as the same as "default connections"?
//component section
 prgrom prg(32KiB); 
 //could also write 256Kib..but seems like a source of many typo problems
 //perhaps go by address line, data line counts?
 chrrom chr(8KiB);
 //only difference between PRG and CHR def'ns are its default connections
 //and outputs
 CIC cic(NES);//allow other chips I guess?

//dynamic components section
 solder h to connect CIRAM_A10 to PPU_A[10];
 solder v to connect CIRAM_A10 to PPU_A[11]; 
 init h iNES.6[0];
 init v ~iNES.6[0];
  //technically redundant per wiki as only V-using boards had solder pads?
  //make "to" as whitespace, allowing nice codelook but not requiring 
 connect CIRAM_CE_n to PPU_A13_n;

//connections: power
 connect VCC prg.vcc cic.vcc chr.vcc;
 connect GND prg.gnd cic.gnd chr.gnd;
  //allow multiple connections per statement
  //considering a shortform lke "=" for connect
//connections: CIC 
 //[omitted]
//connections: PRG
 connect prg.a[14:0] CPU_A[14:0];
 //NROM_128: connect prg.a[13:0] CPU_A[13:0];
 //and connect prg.a[14] VCC; //several ways to do it, really.
 connect prg.d[7:0] CPU_D[7:0];
 connect prg.oe_n prg.ce_n ROMSEL_n; //I suspect I've got these mildly wrong
//connections: CHR
 connect chr.a[12:0] PPU_A[12:0];
 connect chr.d[7:0] PPU_D[7:0];
 connect chr.oe_n chr.ce_n PPU_A[13];

end NROM_256V;