mirror of
https://github.com/holub/mame
synced 2025-07-03 00:56:03 +03:00
More NES work: [Robert Bohms]
* Fixes bug in nes_apu that caused errors reading $4015 * Adds length counter status bits to $4015 * Fixes 4-screen mirroring (PPU regression) * Fixed cham24 Also, I fixed the tab lengths in nes_apu.c
This commit is contained in:
parent
1934fb76af
commit
80f73ab376
File diff suppressed because it is too large
Load Diff
@ -50,8 +50,8 @@ typedef UINT8 boolean;
|
|||||||
|
|
||||||
typedef struct queue_s
|
typedef struct queue_s
|
||||||
{
|
{
|
||||||
int pos;
|
int pos;
|
||||||
unsigned char reg,val;
|
unsigned char reg,val;
|
||||||
} queue_t;
|
} queue_t;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@ -86,88 +86,89 @@ typedef struct queue_s
|
|||||||
/* Square Wave */
|
/* Square Wave */
|
||||||
typedef struct square_s
|
typedef struct square_s
|
||||||
{
|
{
|
||||||
uint8 regs[4];
|
uint8 regs[4];
|
||||||
int vbl_length;
|
int vbl_length;
|
||||||
int freq;
|
int freq;
|
||||||
float phaseacc;
|
float phaseacc;
|
||||||
float output_vol;
|
float output_vol;
|
||||||
float env_phase;
|
float env_phase;
|
||||||
float sweep_phase;
|
float sweep_phase;
|
||||||
uint8 adder;
|
uint8 adder;
|
||||||
uint8 env_vol;
|
uint8 env_vol;
|
||||||
boolean enabled;
|
boolean enabled;
|
||||||
} square_t;
|
} square_t;
|
||||||
|
|
||||||
/* Triangle Wave */
|
/* Triangle Wave */
|
||||||
typedef struct triangle_s
|
typedef struct triangle_s
|
||||||
{
|
{
|
||||||
uint8 regs[4]; /* regs[1] unused */
|
uint8 regs[4]; /* regs[1] unused */
|
||||||
int linear_length;
|
int linear_length;
|
||||||
int vbl_length;
|
int vbl_length;
|
||||||
int write_latency;
|
int write_latency;
|
||||||
float phaseacc;
|
float phaseacc;
|
||||||
float output_vol;
|
float output_vol;
|
||||||
uint8 adder;
|
uint8 adder;
|
||||||
boolean counter_started;
|
boolean counter_started;
|
||||||
boolean enabled;
|
boolean enabled;
|
||||||
} triangle_t;
|
} triangle_t;
|
||||||
|
|
||||||
/* Noise Wave */
|
/* Noise Wave */
|
||||||
typedef struct noise_s
|
typedef struct noise_s
|
||||||
{
|
{
|
||||||
uint8 regs[4]; /* regs[1] unused */
|
uint8 regs[4]; /* regs[1] unused */
|
||||||
int cur_pos;
|
int cur_pos;
|
||||||
int vbl_length;
|
int vbl_length;
|
||||||
float phaseacc;
|
float phaseacc;
|
||||||
float output_vol;
|
float output_vol;
|
||||||
float env_phase;
|
float env_phase;
|
||||||
uint8 env_vol;
|
uint8 env_vol;
|
||||||
boolean enabled;
|
boolean enabled;
|
||||||
} noise_t;
|
} noise_t;
|
||||||
|
|
||||||
/* DPCM Wave */
|
/* DPCM Wave */
|
||||||
typedef struct dpcm_s
|
typedef struct dpcm_s
|
||||||
{
|
{
|
||||||
uint8 regs[4];
|
uint8 regs[4];
|
||||||
uint32 address;
|
uint32 address;
|
||||||
uint32 length;
|
uint32 length;
|
||||||
int bits_left;
|
int bits_left;
|
||||||
float phaseacc;
|
float phaseacc;
|
||||||
float output_vol;
|
float output_vol;
|
||||||
uint8 cur_byte;
|
uint8 cur_byte;
|
||||||
boolean enabled;
|
boolean enabled;
|
||||||
boolean irq_occurred;
|
boolean irq_occurred;
|
||||||
const address_space *memory;
|
const address_space *memory;
|
||||||
signed char vol;
|
signed char vol;
|
||||||
} dpcm_t;
|
} dpcm_t;
|
||||||
|
|
||||||
/* APU type */
|
/* APU type */
|
||||||
typedef struct apu
|
typedef struct apu
|
||||||
{
|
{
|
||||||
/* Sound channels */
|
/* Sound channels */
|
||||||
square_t squ[2];
|
square_t squ[2];
|
||||||
triangle_t tri;
|
triangle_t tri;
|
||||||
noise_t noi;
|
noise_t noi;
|
||||||
dpcm_t dpcm;
|
dpcm_t dpcm;
|
||||||
|
|
||||||
/* APU registers */
|
/* APU registers */
|
||||||
unsigned char regs[0x17];
|
unsigned char regs[0x17];
|
||||||
|
|
||||||
/* Sound pointers */
|
/* Sound pointers */
|
||||||
void *buffer;
|
void *buffer;
|
||||||
|
|
||||||
#ifdef USE_QUEUE
|
#ifdef USE_QUEUE
|
||||||
|
|
||||||
/* Event queue */
|
/* Event queue */
|
||||||
queue_t queue[QUEUE_SIZE];
|
queue_t queue[QUEUE_SIZE];
|
||||||
int head,tail;
|
int head, tail;
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
int buf_pos;
|
int buf_pos;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
int step_mode;
|
||||||
} apu_t;
|
} apu_t;
|
||||||
|
|
||||||
/* CONSTANTS */
|
/* CONSTANTS */
|
||||||
|
@ -244,12 +244,6 @@ static const nes_interface cham24_interface_1 =
|
|||||||
|
|
||||||
static MACHINE_RESET( cham24 )
|
static MACHINE_RESET( cham24 )
|
||||||
{
|
{
|
||||||
/* switch PRG rom */
|
|
||||||
UINT8* dst = memory_region(machine, "maincpu");
|
|
||||||
UINT8* src = memory_region(machine, "user1");
|
|
||||||
|
|
||||||
memcpy(&dst[0x8000], &src[0x0f8000], 0x4000);
|
|
||||||
memcpy(&dst[0xc000], &src[0x0f8000], 0x4000);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static PALETTE_INIT( cham24 )
|
static PALETTE_INIT( cham24 )
|
||||||
@ -282,8 +276,16 @@ static VIDEO_UPDATE( cham24 )
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static DRIVER_INIT( cham24 )
|
|
||||||
|
static MACHINE_START( cham24 )
|
||||||
{
|
{
|
||||||
|
/* switch PRG rom */
|
||||||
|
UINT8* dst = memory_region(machine, "maincpu");
|
||||||
|
UINT8* src = memory_region(machine, "user1");
|
||||||
|
|
||||||
|
memcpy(&dst[0x8000], &src[0x0f8000], 0x4000);
|
||||||
|
memcpy(&dst[0xc000], &src[0x0f8000], 0x4000);
|
||||||
|
|
||||||
/* uses 8K swapping, all ROM!*/
|
/* uses 8K swapping, all ROM!*/
|
||||||
memory_install_readwrite8_handler(cpu_get_address_space(cputag_get_cpu(machine, "ppu"), ADDRESS_SPACE_PROGRAM), 0x0000, 0x1fff, 0, 0, SMH_BANK(1), 0);
|
memory_install_readwrite8_handler(cpu_get_address_space(cputag_get_cpu(machine, "ppu"), ADDRESS_SPACE_PROGRAM), 0x0000, 0x1fff, 0, 0, SMH_BANK(1), 0);
|
||||||
memory_set_bankptr(machine, 1, memory_region(machine, "gfx1"));
|
memory_set_bankptr(machine, 1, memory_region(machine, "gfx1"));
|
||||||
@ -299,6 +301,10 @@ static DRIVER_INIT( cham24 )
|
|||||||
memory_install_readwrite8_handler(cpu_get_address_space(cputag_get_cpu(machine, "ppu"), ADDRESS_SPACE_PROGRAM), 0x2000, 0x3eff, 0, 0, nt_r, nt_w);
|
memory_install_readwrite8_handler(cpu_get_address_space(cputag_get_cpu(machine, "ppu"), ADDRESS_SPACE_PROGRAM), 0x2000, 0x3eff, 0, 0, nt_r, nt_w);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static DRIVER_INIT( cham24 )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
static GFXDECODE_START( cham24 )
|
static GFXDECODE_START( cham24 )
|
||||||
/* none, the ppu generates one */
|
/* none, the ppu generates one */
|
||||||
GFXDECODE_END
|
GFXDECODE_END
|
||||||
@ -309,6 +315,7 @@ static MACHINE_DRIVER_START( cham24 )
|
|||||||
MDRV_CPU_PROGRAM_MAP(cham24_map)
|
MDRV_CPU_PROGRAM_MAP(cham24_map)
|
||||||
|
|
||||||
MDRV_MACHINE_RESET( cham24 )
|
MDRV_MACHINE_RESET( cham24 )
|
||||||
|
MDRV_MACHINE_START( cham24 )
|
||||||
|
|
||||||
/* video hardware */
|
/* video hardware */
|
||||||
MDRV_SCREEN_ADD("screen", RASTER)
|
MDRV_SCREEN_ADD("screen", RASTER)
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
* Micro Machines has minor rendering glitches (needs better timing).
|
* Micro Machines has minor rendering glitches (needs better timing).
|
||||||
* Mach Rider has minor road rendering glitches (needs better timing).
|
* Mach Rider has minor road rendering glitches (needs better timing).
|
||||||
|
* Rad Racer demonstrates road glitches: it changes horizontal scrolling mid-line.
|
||||||
|
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
@ -380,7 +381,6 @@ static void draw_background( const device_config *device, UINT8 *line_priority )
|
|||||||
|
|
||||||
const pen_t *color_table;
|
const pen_t *color_table;
|
||||||
const pen_t *paldata;
|
const pen_t *paldata;
|
||||||
// const UINT8 *sd;
|
|
||||||
|
|
||||||
int tilecount = 0;
|
int tilecount = 0;
|
||||||
|
|
||||||
@ -447,19 +447,16 @@ static void draw_background( const device_config *device, UINT8 *line_priority )
|
|||||||
|
|
||||||
if (start_x < VISIBLE_SCREEN_WIDTH)
|
if (start_x < VISIBLE_SCREEN_WIDTH)
|
||||||
{
|
{
|
||||||
UINT8 plane1, plane2; // use extended size so I can shift!
|
UINT8 plane1, plane2;
|
||||||
paldata = &color_table[4 * (((color_byte >> color_bits) & 0x03))];
|
paldata = &color_table[4 * (((color_byte >> color_bits) & 0x03))];
|
||||||
// start = scroll_y_fine * line_modulo;
|
|
||||||
|
|
||||||
// need to read 0x0000 or 0x1000 + 16*nametable data
|
// need to read 0x0000 or 0x1000 + 16*nametable data
|
||||||
address = ((this_ppu->tile_page) ? 0x1000 : 0) + (page2 * 16);
|
address = ((this_ppu->tile_page) ? 0x1000 : 0) + (page2 * 16);
|
||||||
// plus something that accounts for y
|
// plus something that accounts for y
|
||||||
// address -= (scanline % 8);
|
|
||||||
address += scroll_y_fine;
|
address += scroll_y_fine;
|
||||||
|
|
||||||
plane1 = memory_read_byte(device->space[0], (address & 0x1fff));
|
plane1 = memory_read_byte(device->space[0], (address & 0x1fff));
|
||||||
plane2 = memory_read_byte(device->space[0], (address + 8) & 0x1fff);
|
plane2 = memory_read_byte(device->space[0], (address + 8) & 0x1fff);
|
||||||
// plane2 = plane2 << 1;
|
|
||||||
|
|
||||||
/* render the pixel */
|
/* render the pixel */
|
||||||
for (i = 0; i < 8; i++)
|
for (i = 0; i < 8; i++)
|
||||||
@ -618,30 +615,23 @@ static void draw_sprites( const device_config *device, UINT8 *line_priority )
|
|||||||
plane1 = memory_read_byte(device->space[0], (index1 + sprite_line) & 0x1fff);
|
plane1 = memory_read_byte(device->space[0], (index1 + sprite_line) & 0x1fff);
|
||||||
plane2 = memory_read_byte(device->space[0], (index1 + sprite_line + 8) & 0x1fff);
|
plane2 = memory_read_byte(device->space[0], (index1 + sprite_line + 8) & 0x1fff);
|
||||||
|
|
||||||
// sd = gfx_element_get_data(device->machine->gfx[gfx_bank], index1 % total_elements) + start;
|
|
||||||
// if (size > 8)
|
|
||||||
// gfx_element_get_data(device->machine->gfx[gfx_bank], (index1 + 1) % total_elements);
|
|
||||||
|
|
||||||
if (pri)
|
if (pri)
|
||||||
{
|
{
|
||||||
/* draw the low-priority sprites */
|
/* draw the low-priority sprites */
|
||||||
for (pixel = 0; pixel < 8; pixel++)
|
for (pixel = 0; pixel < 8; pixel++)
|
||||||
{
|
{
|
||||||
// UINT8 pixelData = flipx ? sd[7-pixel] : sd[pixel];
|
|
||||||
UINT8 pixelData;
|
UINT8 pixelData;
|
||||||
if (flipx)
|
if (flipx)
|
||||||
{
|
{
|
||||||
pixelData = (plane1 & 1) + ((plane2 & 1) << 1);
|
pixelData = (plane1 & 1) + ((plane2 & 1) << 1);
|
||||||
plane1 = plane1 >> 1;
|
plane1 = plane1 >> 1;
|
||||||
plane2 = plane2 >> 1;
|
plane2 = plane2 >> 1;
|
||||||
// sd[7 - pixel]
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pixelData = ((plane1 >> 7) & 1) | (((plane2 >> 7) & 1) << 1);
|
pixelData = ((plane1 >> 7) & 1) | (((plane2 >> 7) & 1) << 1);
|
||||||
plane1 = plane1 << 1;
|
plane1 = plane1 << 1;
|
||||||
plane2 = plane2 << 1;
|
plane2 = plane2 << 1;
|
||||||
// sd[pixel];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* is this pixel non-transparent? */
|
/* is this pixel non-transparent? */
|
||||||
@ -1037,11 +1027,11 @@ READ8_HANDLER( ppu2c0x_palette_read )
|
|||||||
{
|
{
|
||||||
ppu2c0x_chip *this_ppu = get_token(space->cpu);
|
ppu2c0x_chip *this_ppu = get_token(space->cpu);
|
||||||
{
|
{
|
||||||
// it's a palette
|
|
||||||
// ERROR: doesn't currently handle monochrome!
|
|
||||||
if (this_ppu->regs[PPU_CONTROL1] & PPU_CONTROL1_DISPLAY_MONO)
|
if (this_ppu->regs[PPU_CONTROL1] & PPU_CONTROL1_DISPLAY_MONO)
|
||||||
return (this_ppu->palette_ram[offset & 0x1f] & 0x30);
|
return (this_ppu->palette_ram[offset & 0x1f] & 0x30);
|
||||||
else return (this_ppu->palette_ram[offset & 0x1f] & 0x3f);
|
|
||||||
|
else
|
||||||
|
return (this_ppu->palette_ram[offset & 0x1f] & 0x3f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1242,9 +1232,6 @@ WRITE8_DEVICE_HANDLER( ppu2c0x_w )
|
|||||||
{
|
{
|
||||||
/* store the data */
|
/* store the data */
|
||||||
memory_write_byte(device->space[0], tempAddr, data);
|
memory_write_byte(device->space[0], tempAddr, data);
|
||||||
|
|
||||||
/* mark the char dirty */
|
|
||||||
// gfx_element_mark_dirty(device->machine->gfx[intf->gfx_layout_number], tempAddr >> 4);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
@ -1273,28 +1260,14 @@ void ppu2c0x_spriteram_dma( const address_space *space, const device_config *dev
|
|||||||
int i;
|
int i;
|
||||||
int address = page << 8;
|
int address = page << 8;
|
||||||
|
|
||||||
// logerror("sprite DMA: %d (scanline: %d)\n", page, this_ppu->scanline);
|
|
||||||
for (i = 0; i < SPRITERAM_SIZE; i++)
|
for (i = 0; i < SPRITERAM_SIZE; i++)
|
||||||
{
|
{
|
||||||
UINT8 spriteData = memory_read_byte(space, address + i);
|
UINT8 spriteData = memory_read_byte(space, address + i);
|
||||||
memory_write_byte(space, 0x2004, spriteData);
|
memory_write_byte(space, 0x2004, spriteData);
|
||||||
// ppu2c0x_w(device, PPU_SPRITE_DATA, spriteData);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// should last 513 CPU cycles.
|
// should last 513 CPU cycles.
|
||||||
cpu_adjust_icount(space->cpu, -513);
|
cpu_adjust_icount(space->cpu, -513);
|
||||||
|
|
||||||
// ????TODO : need to account for PPU rendering - this is roughly 4.5 scanlines eaten up.
|
|
||||||
// Because the DMA is only useful during vblank, this may not be strictly necessary since
|
|
||||||
// the scanline timers should catch us up before drawing actually happens.
|
|
||||||
#if 0
|
|
||||||
{
|
|
||||||
scanline_callback(device);
|
|
||||||
scanline_callback(device);
|
|
||||||
scanline_callback(device);
|
|
||||||
scanline_callback(device);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*************************************
|
/*************************************
|
||||||
|
Loading…
Reference in New Issue
Block a user