User:Zzo38/Emulator plugin format

From NESdev Wiki
< User:Zzo38
Revision as of 04:23, 23 June 2013 by Zzo38 (talk | contribs)
Jump to navigationJump to search

Mapper

#define OPEN_BUS 0xFFFF
#define CIRAM_BANK_0 0x8000
#define CIRAM_BANK_1 0x8400
#define BUS_CONFLICT 0x1000

typedef struct Mapper {
  // Provided by host
  NSF_Interface*nsf;
  const U8*prg_rom;
  U8*prg_ram;
  U8*prg_battery_ram;
  const U8*chr_rom;
  U8*chr_ram;
  U8*chr_battery_ram;
  // Provided by plugin
  void(*destroy)(Mapper*);
  void(*reset)(Mapper*);
  U16(*prg_read)(Mapper*,U16);
  U16(*prg_write)(Mapper*,U16,U8);
  U16(*chr_access)(Mapper*,U16);
  U16(*chr_read)(Mapper*,U16);
  U16(*chr_write)(Mapper*,U16,U8);
  void(*quick_save)(Mapper*,U8*);
  void(*quick_restore)(Mapper*,const U8*);
} Mapper;

typedef struct Mapper_Info {
  U8 version; // R
  U8 mirroring; // R
  U16 id; // R
  U32 prg_rom_size; // R
  U32 prg_ram_size; // R/W
  U32 prg_battery_ram_size; // R/W
  U32 chr_rom_size; // R
  U32 chr_ram_size; // R/W
  U32 chr_battery_ram_size; // R/W
  FILE*ines; // R
  int save_size; // W
  U8 audio_ext; // W
} Mapper_Info;

int define_mapper(U16 id,const char*name,(Mapper*)(*init)(Mapper_Info*));
  • OPEN_BUS: Returned by some functions to indicate that there is no data in the cartridge, or that you are not writing to CIRAM.
  • CIRAM_BANK_0: Returned from some functions to indicate read/write the CIRAM when CIRAM A10 is low.
  • CIRAM_BANK_1: Returned from some functions to indicate read/write the CIRAM when CIRAM A10 is high.
  • BUS_CONFLICT: Should be bitwise OR by the other value to indicate that there is a bus conflict; the emulator can ignore it or keep track of a counter of bus conflicts.
  • Mapper: The structure to store the mapper data in the memory. It is possible for the plugin to add additional fields at the end.
    • nsf: The NSF interface.
    • prg_rom: PRG ROM.
    • prg_ram: Non-battery PRG RAM.
    • prg_battery_ram: Battery PRG RAM.
    • chr_rom: CHR ROM.
    • chr_ram: Non-battery CHR RAM.
    • chr_battery_ram: Battery CHR RAM.
    • destroy: It should free the mapper data since it isn't used anymore. The emulator automatically frees the data that it initializes by itself. It might also be called before reset is called if the emulator is unable to use this mapper for some reason.
    • reset: Indicate a hard or soft reset (the first one is hard reset and the rest is soft reset).
    • prg_read: Read data from PRG address space. Normally, the high eight bits of the return should be cleared if there is a data to read on the cartridge.
    • prg_write: Write data to PRG address space.
    • chr_access: The address line of CHR is updated, even though it isn't read/write.
    • chr_read: Read data from CHR address space.
    • chr_write: Write data to CHR address space.
    • quick_save: Should write any data specific to the mapper (other than the RAM) into the buffer which is provided.
    • quick_restore: Should read any data specific to the mapper (other than the RAM) from the buffer which is provided.
  • NSF_Interface: Provide functions for expansion audio, audio input, IRQ input, timers, and CPU cycle counters.
  • Mapper_Info: The structure of the information provided by the iNES header and emulator.
    • version: Zero for "DiskDude" files, one for old iNES format, two for NES 2.0 format, 255 if this isn't applicable.
    • mirroring: Nametable mirroring mode.
    • id: The iNES mapper number.
    • prg_rom_size: PRG ROM size in bytes.
    • prg_ram_size: PRG RAM size in bytes.
    • prg_battery_ram_size: PRG battery RAM size in bytes.
    • chr_rom_size: CHR ROM size in bytes.
    • chr_ram_size: CHR RAM size in bytes.
    • chr_battery_ram_size: CHR battery RAM size in bytes.
    • ines: File handle of iNES ROM image file. This might sometimes be not available for some reason.
    • save_size: The size of quick save data needed by this mapper.
    • audio_ext: Specify what audio expansion chip is used, in the same format as NSF. Note that, some emulator might ignore this specification.
  • define_mapper: Define a mapper. If there is more than one having the same ID number, it will try them in the reverse order of being defined until the init function returns nonzero.
    • id: The NES 2.0 mapper number.
    • name: The name of the mapper in ASCII format.
    • init: The initialization function, which is called when hard reset (but not when soft reset). It should allocate the Mapper structure, write the necessary changes to Mapper_Info if applicable, and set up the "provided by plugin" fields and its own fields (the emulator will automatically set up the others).

Input device

typedef struct InputDevice {
  // Provided by host
  U16 sound; // class 0 only
  U8 light;
  void(*irq_write)(InputDevice*,int); // class 0 only
  int(*irq_read)(InputDevice*); // class 0 only
  void(*display)(InputDevice*,UserDisplay*);
  // Provided by plugin
  void(*destroy)(InputDevice*);
  void(*connect)(InputDevice*,U8);
  void(*disconnect)(InputDevice*);
  void(*irq_trigger)(InputDevice*,int); // class 0 only
  U8(*read)(InputDevice*);
  U8(*read_other)(InputDevice*); // class 0 only
  void(*write)(InputDevice*,U8);
  // Provided by plugin -- MIDI events
  void(*note_off)(InputDevice*,U8,U8,U8);
  void(*note_on)(InputDevice*,U8,U8,U8);
  void(*key_pressure)(InputDevice*,U8,U8,U8);
  void(*parameter)(InputDevice*,U8,U8,U8);
  void(*program)(InputDevice*,U8,U8);
  void(*channel_pressure)(InputDevice*,U8,U8);
  void(*pitch_wheel)(InputDevice*,U8,U16);
  void(*sysex)(InputDevice*,const U8*,U32);
  void(*tune)(InputDevice*);
  void(*reset)(InputDevice*);
} InputDevice;

int define_input_device(const char*name,int class,(InputDevice*)(*init)(void));
  • InputDevice: The structure to store the input device data in the memory. It is possible for the plugin to add additional fields at the end.
    • sound: 2A03 audio mixed with microphone (no expansion audio).
    • light: Tell the light sense of the light gun.
    • irq_write: Set the IRQ pin of Famicom expansion port high or low, which will trigger IRQ in the CPU and the cartridge can also read it.
    • irq_read: Read the IRQ pin of Famicom expansion port, which is whatever the cartridge set it to. If it doesn't set, it is high.
    • display: To display data to the user.
    • destroy: Used to free the input device memory.
    • connect: The device is connected. The argument is the initial OUT0, OUT1, OUT2; if it isn't on the expansion port then only OUT0 is used.
    • disconnect: The device is disconnected.
    • irq_trigger: Used if the cartridge asserts the IRQ. The argument is the new value 0 or 1.
    • read: Called when the CPU request data from this port. Any unused pins should be high.
    • read_other: Called when the CPU request data of the bit1 of the $4016 register for devices connected to the expansion port. All other bits must be high.
    • write: Called when CPU set the OUT0, OUT1, OUT2 pins.
    • note_off: MIDI message for note off. Parameter is channel, key, velocity. (Note for this and other MIDI messages: Please use only the low bit of the channel number; the other three bits are used for the emulator's purpose.)
    • note_on: MIDI message for note on. Parameter is channel, key, velocity.
    • key_pressure: MIDI message for key pressure. Parameter is channel, key, pressure.
    • parameter: MIDI message for parameter. Parameter is channel, control number, control data.
    • program: MIDI message for program change.
    • channel_pressure: MIDI message for channel pressure.
    • pitch_wheel: MIDI message for pitch wheel.
    • sysex: MIDI system exclusive message. The data and length is specified as the parameter.
    • tune: MIDI tune request message.
    • reset: MIDI reset message.
  • UserDisplay: A structure to display information to the user.
  • define_input_device: Add a new input device into the emulator.
    • name: The name of a input device in ASCII format.
    • class: Specify the device class. 0=Famicom expansion port, 1=NES controller port, 2=NES controller port with only bit0, 3=NES controller port with only bit0 and only eight data in the latch like the standard controller protocol. If a class 1, 2, 3, is connected to expansion port then it is player 2 device.
    • init: Should allocate a InputDevice structure and set up the "provided by plugin" fields and its own fields (the emulator will automatically set up the others).

The emulator will have its own way to somehow convert the user input into MIDI format; for example, by configuration dialog box, configuration files, some combination of this, or others.