mirror of
https://github.com/libretro/FBNeo.git
synced 2024-11-23 08:59:39 +00:00
add driver for Soviet-Ukrainian games by Terminal (TIA-MC1 & kot) [iq_132, dink]
This commit is contained in:
parent
cb7cb4e454
commit
ba7529801b
@ -69,7 +69,7 @@ drvsrc = d_akkaarrh.o d_arcadecl.o d_atarig1.o d_badlands.o d_batman.o d_blstro
|
||||
d_qbert.o d_quizo.o d_rallyx.o d_redclash.o d_renegade.o d_quantum.o d_route16.o d_rpunch.o d_safarir.o d_sauro.o d_scregg.o d_seicross.o d_senjyo.o d_sf.o d_shangkid.o d_shisen.o \
|
||||
d_sidearms.o d_skyarmy.o d_skyfox.o d_skykid.o d_snk.o d_snk6502.o d_snk68.o d_solomon.o d_sonson.o d_spacefb.o d_spdodgeb.o d_speedbal.o d_sprcros2.o \
|
||||
d_srumbler.o d_ssozumo.o d_sstrangr.o d_starwars.o d_stfight.o d_stuntair.o d_sub.o d_suna8.o d_tagteam.o d_tankbust.o d_taxidriv.o d_tail2nose.o d_tbowl.o d_tceptor.o \
|
||||
d_tecmo.o d_tempest.o d_terracre.o d_thedeep.o d_thepit.o d_thief.o d_tigeroad.o d_timelimt.o d_toki.o d_toypop.o d_travrusa.o d_tsamurai.o d_tubep.o d_usgames.o \
|
||||
d_tecmo.o d_tempest.o d_terracre.o d_thedeep.o d_thepit.o d_thief.o d_tiamc1.o d_tigeroad.o d_timelimt.o d_toki.o d_toypop.o d_travrusa.o d_tsamurai.o d_tubep.o d_usgames.o \
|
||||
d_vastar.o d_vball.o d_vicdual.o d_vulgus.o d_wallc.o d_warpwarp.o d_warpsped.o d_wc90.o d_wc90b.o d_williams.o d_wiping.o d_wiz.o d_wwfsstar.o \
|
||||
d_xain.o d_xxmissio.o d_xyonix.o d_zaccaria.o d_zodiack.o d_zwackery.o \
|
||||
\
|
||||
@ -109,7 +109,7 @@ depobj = burn.o burn_bitmap.o burn_gun.o burn_led.o burn_shift.o burn_memory.o
|
||||
asteroids.o ay8910.o burn_y8950.o burn_ym2151.o burn_ym2203.o burn_ym2413.o burn_ym2608.o burn_ym2610.o burn_ym2612.o burn_md2612.o \
|
||||
burn_ym3526.o burn_ym3812.o burn_ymf262.o burn_ymf271.o burn_ymf278b.o bzone.o c6280.o dac.o digitalk.o es5506.o es8712.o exidy440_snd.o flower.o flt_rc.o fm.o fmopl.o ym2612.o gaelco.o hc55516.o \
|
||||
i5000.o ics2115.o iremga20.o k005289.o k007232.o k051649.o k053260.o k054539.o llander.o mpeg_audio.o msm5205.o msm5232.o msm6295.o multipcm.o namco_snd.o c140.o c352.o nes_apu.o \
|
||||
t6w28.o tms5110.o tms5220.o tms36xx.o phoenixsound.o pleiadssound.o pokey.o redbaron.o rf5c68.o s14001a.o saa1099.o samples.o segapcm.o sn76477.o sn76496.o \
|
||||
t6w28.o tiamc1_snd.o tms5110.o tms5220.o tms36xx.o phoenixsound.o pleiadssound.o pokey.o redbaron.o rf5c68.o s14001a.o saa1099.o samples.o segapcm.o sn76477.o sn76496.o \
|
||||
upd7759.o vlm5030.o wiping.o x1010.o ym2151.o ym2413.o ymdeltat.o ymf262.o ymf271.o ymf278b.o ymz280b.o ymz770.o snk6502_sound.o sp0250.o sp0256.o \
|
||||
\
|
||||
adsp2100.o adsp2100_intf.o arm7_intf.o arm_intf.o f8.o h6280_intf.o hd6309_intf.o konami_intf.o m6502_intf.o m6800_intf.o m6805_intf.o m6809_intf.o \
|
||||
|
845
src/burn/drv/pre90s/d_tiamc1.cpp
Normal file
845
src/burn/drv/pre90s/d_tiamc1.cpp
Normal file
@ -0,0 +1,845 @@
|
||||
// FinalBurn Neo TIA-MC1 driver module
|
||||
// Based on MAME driver by Eugene Sandulenko, w/special thanks to Shiru for his standalone emulator and documentation
|
||||
|
||||
#include "tiles_generic.h"
|
||||
#include "z80_intf.h"
|
||||
#include "8255ppi.h"
|
||||
#include "burn_pal.h"
|
||||
#include "tiamc1_snd.h"
|
||||
|
||||
static UINT8 *AllMem;
|
||||
static UINT8 *AllRam;
|
||||
static UINT8 *RamEnd;
|
||||
static UINT8 *MemEnd;
|
||||
static UINT8 *DrvI8080ROM;
|
||||
static UINT8 *DrvSprROM;
|
||||
static UINT8 *DrvTileROM;
|
||||
static UINT8 *DrvI8080RAM;
|
||||
static UINT8 *DrvTileRAM;
|
||||
static UINT8 *DrvSprRAM;
|
||||
static UINT8 *DrvCharRAM;
|
||||
static UINT8 *DrvCharRAMExp;
|
||||
|
||||
static UINT32 *DrvPalette;
|
||||
|
||||
static UINT8 layer_control;
|
||||
static INT32 character_bank;
|
||||
static UINT8 scrollx;
|
||||
static UINT8 scrolly;
|
||||
static UINT8 bg_color;
|
||||
static INT32 update_characters;
|
||||
static INT32 update_colors;
|
||||
|
||||
static INT32 vblank;
|
||||
static UINT32 button_config = 0;
|
||||
|
||||
static UINT8 DrvJoy1[8];
|
||||
static UINT8 DrvJoy2[8];
|
||||
static UINT8 DrvJoy3[8];
|
||||
static UINT8 DrvInputs[3];
|
||||
static UINT8 DrvReset;
|
||||
|
||||
static INT16 Analog[1];
|
||||
|
||||
static INT32 is_gorodki = 0;
|
||||
|
||||
static INT32 nExtraCycles;
|
||||
|
||||
static struct BurnInputInfo DrvInputList[] = {
|
||||
{"P1 Coin", BIT_DIGITAL, DrvJoy3 + 4, "p1 coin" },
|
||||
{"P1 Up", BIT_DIGITAL, DrvJoy2 + 1, "p1 up" },
|
||||
{"P1 Down", BIT_DIGITAL, DrvJoy2 + 5, "p1 down" },
|
||||
{"P1 Left", BIT_DIGITAL, DrvJoy1 + 5, "p1 left"} ,
|
||||
{"P1 Right", BIT_DIGITAL, DrvJoy1 + 1, "p1 right" },
|
||||
{"P1 Button 1", BIT_DIGITAL, DrvJoy3 + 5, "p1 fire 1" },
|
||||
{"P1 Button 2", BIT_DIGITAL, DrvJoy3 + 6, "p1 fire 2" },
|
||||
|
||||
{"Reset", BIT_DIGITAL, &DrvReset, "reset" },
|
||||
|
||||
{"Service Mode", BIT_DIGITAL, DrvJoy2 + 7, "diag" },
|
||||
};
|
||||
|
||||
STDINPUTINFO(Drv)
|
||||
|
||||
#define A(a, b, c, d) {a, b, (UINT8*)(c), d}
|
||||
static struct BurnInputInfo GorodkiInputList[] = {
|
||||
{"P1 Coin", BIT_DIGITAL, DrvJoy3 + 4, "p1 coin" },
|
||||
A("P1 Stick X", BIT_ANALOG_REL, &Analog[0], "p1 x-axis"),
|
||||
{"P1 Button 1", BIT_DIGITAL, DrvJoy3 + 5, "p1 fire 1" },
|
||||
{"P1 Button 2", BIT_DIGITAL, DrvJoy3 + 6, "p1 fire 2" },
|
||||
|
||||
{"Reset", BIT_DIGITAL, &DrvReset, "reset" },
|
||||
|
||||
{"Service Mode", BIT_DIGITAL, DrvJoy2 + 7, "diag" },
|
||||
};
|
||||
#undef A
|
||||
STDINPUTINFO(Gorodki)
|
||||
|
||||
static void __fastcall tiamc1_videoram_write(UINT16 address, UINT8 data)
|
||||
{
|
||||
if ((address & 0x0800) == 0x0000) // b000-b7ff (tiamc1) f000-f3ff (kot)
|
||||
{
|
||||
INT32 offs = address & 0x7ff;
|
||||
|
||||
if (layer_control & 0x1e) { update_characters = 1; }
|
||||
|
||||
if (layer_control & 0x01) DrvTileRAM[offs | 0x0000] = data;
|
||||
if (layer_control & 0x02) DrvCharRAM[offs | 0x0000] = data;
|
||||
if (layer_control & 0x04) DrvCharRAM[offs | 0x0800] = data;
|
||||
if (layer_control & 0x08) DrvCharRAM[offs | 0x1000] = data;
|
||||
if (layer_control & 0x10) DrvCharRAM[offs | 0x1800] = data;
|
||||
}
|
||||
}
|
||||
|
||||
static void __fastcall tiamc1_write_port(UINT16 port, UINT8 data)
|
||||
{
|
||||
switch (port & 0xf0)
|
||||
{
|
||||
case 0x40:
|
||||
case 0x50:
|
||||
case 0x60:
|
||||
case 0x70:
|
||||
DrvSprRAM[port & 0x3f] = ~data;
|
||||
return;
|
||||
|
||||
case 0xc0:
|
||||
if ((port & 0x0f) < 4) tiamc1_sound_timer0_write(port & 3, data);
|
||||
return;
|
||||
|
||||
case 0xd0:
|
||||
switch (port & 0x0c)
|
||||
{
|
||||
case 0x00:
|
||||
ppi8255_w(0, port & 3, data);
|
||||
return;
|
||||
|
||||
case 0x04:
|
||||
tiamc1_sound_timer1_write(port & 3, data);
|
||||
return;
|
||||
|
||||
case 0x08: // actually A
|
||||
tiamc1_sound_gate_write(data);
|
||||
return;
|
||||
}
|
||||
return;
|
||||
|
||||
case 0xa0:
|
||||
BurnPalRAM[port & 0xf] = data;
|
||||
update_colors = 1;
|
||||
return;
|
||||
|
||||
case 0xb0:
|
||||
{
|
||||
switch (port & 0x0f)
|
||||
{
|
||||
case 0x0c:
|
||||
scrolly = data;
|
||||
return;
|
||||
|
||||
case 0x0d:
|
||||
scrollx = data;
|
||||
return;
|
||||
|
||||
case 0x0e:
|
||||
layer_control = data ^ 0x1f;
|
||||
return;
|
||||
|
||||
case 0x0f:
|
||||
bg_color = ((data >> 0) & 1) | ((data >> 1) & 2) | ((data >> 2) & 4) | ((data >> 3) & 8);
|
||||
update_colors = 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static UINT8 __fastcall tiamc1_read_port(UINT16 port)
|
||||
{
|
||||
switch (port & 0xfc)
|
||||
{
|
||||
case 0xd0:
|
||||
return ppi8255_r(0, port & 3);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __fastcall kot_write_port(UINT16 port, UINT8 data)
|
||||
{
|
||||
switch (port & 0xf0)
|
||||
{
|
||||
case 0x00:
|
||||
case 0x10:
|
||||
case 0x20:
|
||||
case 0x30:
|
||||
DrvSprRAM[port & 0x3f] = ~data;
|
||||
return;
|
||||
|
||||
case 0xc0:
|
||||
if ((port & 0x0f) < 4) tiamc1_sound_timer0_write(port & 3, data);
|
||||
return;
|
||||
|
||||
case 0xd0:
|
||||
if ((port & 0x0f) < 4) ppi8255_w(0, port & 3, data);
|
||||
return;
|
||||
|
||||
case 0xe0:
|
||||
BurnPalRAM[port & 0xf] = data;
|
||||
update_colors = 1;
|
||||
return;
|
||||
|
||||
case 0xf0:
|
||||
{
|
||||
switch (port & 0x0f)
|
||||
{
|
||||
case 0x00:
|
||||
scrolly = data;
|
||||
return;
|
||||
|
||||
case 0x04:
|
||||
scrollx = data;
|
||||
return;
|
||||
|
||||
case 0x08:
|
||||
layer_control = (data ^ 1) & 1; // kot != tiamc1
|
||||
character_bank = (data >> 1) << 5;
|
||||
return;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static UINT8 __fastcall kot_read_port(UINT16 port)
|
||||
{
|
||||
switch (port & 0xfc)
|
||||
{
|
||||
case 0xc0: // pit8253
|
||||
return 0xff;
|
||||
|
||||
case 0xd0:
|
||||
return ppi8255_r(0, port & 3);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static UINT8 ppi_port_A_read()
|
||||
{
|
||||
return DrvInputs[0];
|
||||
}
|
||||
|
||||
static UINT8 ppi_port_B_read()
|
||||
{
|
||||
return DrvInputs[1];
|
||||
}
|
||||
|
||||
static UINT8 ppi_port_C_read()
|
||||
{
|
||||
return (DrvInputs[2] & 0x7f) | (vblank ? 0x80 : 0);
|
||||
}
|
||||
|
||||
static tilemap_callback( bg )
|
||||
{
|
||||
TILE_SET_INFO(0, DrvTileRAM[offs | ((layer_control & 0x80) << 3)] + character_bank, 0, 0);
|
||||
}
|
||||
|
||||
static INT32 DrvDoReset()
|
||||
{
|
||||
memset (AllRam, 0, RamEnd - AllRam);
|
||||
|
||||
ZetOpen(0);
|
||||
ZetReset();
|
||||
ZetClose();
|
||||
|
||||
ppi8255_reset();
|
||||
|
||||
layer_control = 0;
|
||||
character_bank = 0;
|
||||
scrollx = 0;
|
||||
scrolly = 0;
|
||||
bg_color = 0;
|
||||
update_characters = 0;
|
||||
update_colors = 0;
|
||||
|
||||
nExtraCycles = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static INT32 MemIndex()
|
||||
{
|
||||
UINT8 *Next; Next = AllMem;
|
||||
|
||||
DrvI8080ROM = Next; Next += 0x010000;
|
||||
|
||||
DrvTileROM = Next; Next += 0x010000;
|
||||
DrvSprROM = Next; Next += 0x010000;
|
||||
|
||||
DrvPalette = (UINT32*)Next; Next += 0x0100 * sizeof(UINT32);
|
||||
BurnPalette = (UINT32*)Next; Next += 0x0020 * sizeof(UINT32);
|
||||
|
||||
AllRam = Next;
|
||||
|
||||
DrvI8080RAM = Next; Next += 0x002000;
|
||||
|
||||
DrvTileRAM = Next; Next += 0x000800;
|
||||
|
||||
DrvSprRAM = Next; Next += 0x000040;
|
||||
DrvCharRAM = Next; Next += 0x002000;
|
||||
BurnPalRAM = Next; Next += 0x000010;
|
||||
|
||||
RamEnd = Next;
|
||||
|
||||
DrvCharRAMExp = Next; Next += 0x004000;
|
||||
|
||||
MemEnd = Next;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void DrvGfxDecode()
|
||||
{
|
||||
INT32 Planes[4] = { STEP4(0x10000*3,-0x10000) };
|
||||
INT32 XOffs[16] = { STEP8(0,1), STEP8(0x8000,1) };
|
||||
INT32 YOffs[16] = { STEP16(0,8) };
|
||||
|
||||
UINT8 *tmp = (UINT8*)BurnMalloc(0x8000);
|
||||
if (tmp == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy (tmp, DrvTileROM, 0x8000);
|
||||
|
||||
GfxDecode(0x0400, 4, 8, 8, Planes, XOffs, YOffs, 0x40, tmp, DrvTileROM);
|
||||
|
||||
memcpy (tmp, DrvSprROM, 0x8000);
|
||||
|
||||
GfxDecode(0x0100, 4, 16, 16, Planes, XOffs, YOffs, 0x80, tmp, DrvSprROM);
|
||||
|
||||
BurnFree (tmp);
|
||||
}
|
||||
|
||||
static void DrvPaletteInit()
|
||||
{
|
||||
static float g_v[8] = { 1.2071F, 0.9971F, 0.9259F, 0.7159F, 0.4912F, 0.2812F, 0.2100F, 0.0000F };
|
||||
static float r_v[8] = { 1.5937F, 1.3125F, 1.1562F, 0.8750F, 0.7187F, 0.4375F, 0.2812F, 0.0000F };
|
||||
static float b_v[4] = { 1.3523F, 0.8750F, 0.4773F, 0.0000F };
|
||||
|
||||
for (INT32 col = 0; col < 256; col++)
|
||||
{
|
||||
INT32 ir = (col >> 3) & 7;
|
||||
INT32 ig = col & 7;
|
||||
INT32 ib = (col >> 6) & 3;
|
||||
float tcol = 255.0f * r_v[ir] / r_v[0];
|
||||
INT32 r = 255 - (int(tcol) & 255);
|
||||
tcol = 255.0f * g_v[ig] / g_v[0];
|
||||
INT32 g = 255 - (int(tcol) & 255);
|
||||
tcol = 255.0f * b_v[ib] / b_v[0];
|
||||
INT32 b = 255 - (int(tcol) & 255);
|
||||
|
||||
DrvPalette[col] = (r << 16) | (g << 8) | b;
|
||||
}
|
||||
}
|
||||
|
||||
static INT32 DrvInit(INT32 romcount)
|
||||
{
|
||||
BurnAllocMemIndex();
|
||||
|
||||
{
|
||||
INT32 k = 0;
|
||||
if (romcount == 6)
|
||||
{
|
||||
if (BurnLoadRom(DrvI8080ROM + 0x00000, k++, 1)) return 1;
|
||||
if (BurnLoadRom(DrvI8080ROM + 0x02000, k++, 1)) return 1;
|
||||
if (BurnLoadRom(DrvI8080ROM + 0x04000, k++, 1)) return 1;
|
||||
if (BurnLoadRom(DrvI8080ROM + 0x06000, k++, 1)) return 1;
|
||||
if (BurnLoadRom(DrvI8080ROM + 0x08000, k++, 1)) return 1;
|
||||
if (BurnLoadRom(DrvI8080ROM + 0x0c000, k++, 1)) return 1;
|
||||
}
|
||||
else if (romcount == 4)
|
||||
{
|
||||
if (BurnLoadRom(DrvI8080ROM + 0x00000, k++, 1)) return 1;
|
||||
if (BurnLoadRom(DrvI8080ROM + 0x02000, k++, 1)) return 1;
|
||||
if (BurnLoadRom(DrvI8080ROM + 0x04000, k++, 1)) return 1;
|
||||
if (BurnLoadRom(DrvI8080ROM + 0x06000, k++, 1)) return 1;
|
||||
}
|
||||
else if (romcount == 3)
|
||||
{
|
||||
if (BurnLoadRom(DrvI8080ROM + 0x00000, k++, 1)) return 1;
|
||||
if (BurnLoadRom(DrvI8080ROM + 0x02000, k++, 1)) return 1;
|
||||
if (BurnLoadRom(DrvI8080ROM + 0x0c000, k++, 1)) return 1;
|
||||
}
|
||||
|
||||
if (BurnLoadRom(DrvSprROM + 0x00000, k++, 1)) return 1;
|
||||
if (BurnLoadRom(DrvSprROM + 0x02000, k++, 1)) return 1;
|
||||
if (BurnLoadRom(DrvSprROM + 0x04000, k++, 1)) return 1;
|
||||
if (BurnLoadRom(DrvSprROM + 0x06000, k++, 1)) return 1;
|
||||
|
||||
DrvGfxDecode();
|
||||
DrvPaletteInit();
|
||||
}
|
||||
|
||||
ZetInit(0); // i8080
|
||||
ZetOpen(0);
|
||||
ZetMapMemory(DrvI8080ROM, 0x0000, 0xdfff, MAP_ROM);
|
||||
ZetMapMemory(DrvI8080RAM, 0xe000, 0xffff, MAP_RAM);
|
||||
ZetSetWriteHandler(tiamc1_videoram_write);
|
||||
ZetSetOutHandler(tiamc1_write_port);
|
||||
ZetSetInHandler(tiamc1_read_port);
|
||||
ZetClose();
|
||||
|
||||
ppi8255_init(1);
|
||||
ppi8255_set_read_ports(0, ppi_port_A_read, ppi_port_B_read, ppi_port_C_read);
|
||||
// write C = coin counter
|
||||
|
||||
tiamc1_sound_init();
|
||||
|
||||
GenericTilesInit();
|
||||
GenericTilemapInit(0, TILEMAP_SCAN_ROWS, bg_map_callback, 8, 8, 32, 32);
|
||||
GenericTilesSetGfx(0, DrvCharRAMExp, 4, 8, 8, 0x004000, 0x10, 0x0f);
|
||||
GenericTilesSetGfx(1, DrvSprROM, 4, 16, 16, 0x010000, 0x00, 0x0f);
|
||||
GenericTilemapSetOffsets(0, 4, 0);
|
||||
|
||||
button_config = 0x0a0000;
|
||||
|
||||
DrvDoReset();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static INT32 KotInit()
|
||||
{
|
||||
BurnAllocMemIndex();
|
||||
|
||||
{
|
||||
INT32 k = 0;
|
||||
if (BurnLoadRom(DrvI8080ROM + 0x00000, k++, 1)) return 1;
|
||||
if (BurnLoadRom(DrvI8080ROM + 0x02000, k++, 1)) return 1;
|
||||
if (BurnLoadRom(DrvI8080ROM + 0x04000, k++, 1)) return 1;
|
||||
|
||||
if (BurnLoadRom(DrvSprROM + 0x00000, k++, 1)) return 1;
|
||||
if (BurnLoadRom(DrvSprROM + 0x02000, k++, 1)) return 1;
|
||||
if (BurnLoadRom(DrvSprROM + 0x04000, k++, 1)) return 1;
|
||||
if (BurnLoadRom(DrvSprROM + 0x06000, k++, 1)) return 1;
|
||||
|
||||
if (BurnLoadRom(DrvTileROM + 0x00000, k++, 1)) return 1;
|
||||
if (BurnLoadRom(DrvTileROM + 0x02000, k++, 1)) return 1;
|
||||
if (BurnLoadRom(DrvTileROM + 0x04000, k++, 1)) return 1;
|
||||
if (BurnLoadRom(DrvTileROM + 0x06000, k++, 1)) return 1;
|
||||
|
||||
DrvGfxDecode();
|
||||
DrvPaletteInit();
|
||||
}
|
||||
|
||||
ZetInit(0); // i8080
|
||||
ZetOpen(0);
|
||||
ZetMapMemory(DrvI8080ROM, 0x0000, 0xbfff, MAP_ROM);
|
||||
ZetMapMemory(DrvI8080RAM, 0xc000, 0xcfff, MAP_RAM);
|
||||
ZetSetWriteHandler(tiamc1_videoram_write);
|
||||
ZetSetOutHandler(kot_write_port);
|
||||
ZetSetInHandler(kot_read_port);
|
||||
ZetClose();
|
||||
|
||||
ppi8255_init(1);
|
||||
ppi8255_set_read_ports(0, ppi_port_A_read, ppi_port_B_read, ppi_port_C_read);
|
||||
// write C = coin counter
|
||||
|
||||
tiamc1_sound_init_kot();
|
||||
|
||||
GenericTilesInit();
|
||||
GenericTilemapInit(0, TILEMAP_SCAN_ROWS, bg_map_callback, 8, 8, 32, 32);
|
||||
GenericTilesSetGfx(0, DrvTileROM, 4, 8, 8, 0x010000, 0x10, 0x0f);
|
||||
GenericTilesSetGfx(1, DrvSprROM, 4, 16, 16, 0x010000, 0x00, 0x0f);
|
||||
GenericTilemapSetOffsets(0, 4, 0);
|
||||
|
||||
button_config = 0x6affff;
|
||||
|
||||
DrvDoReset();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static INT32 DrvExit()
|
||||
{
|
||||
GenericTilesExit();
|
||||
|
||||
ZetExit();
|
||||
ppi8255_exit();
|
||||
|
||||
tiamc1_sound_exit();
|
||||
|
||||
BurnFreeMemIndex();
|
||||
|
||||
is_gorodki = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void DrvCharDecode()
|
||||
{
|
||||
INT32 Planes[4] = { STEP4(0x4000*3,-0x4000) };
|
||||
INT32 XOffs[8] = { STEP8(0,1) };
|
||||
INT32 YOffs[8] = { STEP8(0,8) };
|
||||
|
||||
GfxDecode(0x0100, 4, 8, 8, Planes, XOffs, YOffs, 0x40, DrvCharRAM, DrvCharRAMExp);
|
||||
}
|
||||
|
||||
static void DrawSprites()
|
||||
{
|
||||
for (INT32 offs = 0; offs < 16; offs++)
|
||||
{
|
||||
if (DrvSprRAM[offs | 0x30] & 1)
|
||||
{
|
||||
INT32 sy = DrvSprRAM[offs | 0x00];
|
||||
INT32 sx = DrvSprRAM[offs | 0x10];
|
||||
INT32 code = DrvSprRAM[offs | 0x20];
|
||||
INT32 flipx = DrvSprRAM[offs | 0x30] & 0x08;
|
||||
INT32 flipy = DrvSprRAM[offs | 0x30] & 0x02;
|
||||
|
||||
DrawGfxMaskTile(0, 1, code, sx, sy, flipx, flipy, 0, 0xf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static INT32 DrvDraw()
|
||||
{
|
||||
if (update_colors || BurnRecalc) {
|
||||
for (INT32 i = 0; i < 16; i++) {
|
||||
UINT32 p = DrvPalette[BurnPalRAM[i]];
|
||||
UINT32 b = DrvPalette[BurnPalRAM[i | bg_color]];
|
||||
BurnPalette[i + 0x00] = BurnHighCol(p >> 16, (p >> 8) & 0xff, p & 0xff, 0);
|
||||
BurnPalette[i + 0x10] = BurnHighCol(b >> 16, (b >> 8) & 0xff, b & 0xff, 0);
|
||||
}
|
||||
update_colors = BurnRecalc = 0;
|
||||
}
|
||||
|
||||
if (update_characters) {
|
||||
DrvCharDecode();
|
||||
update_characters = 0;
|
||||
}
|
||||
|
||||
GenericTilemapSetScrollX(0, scrollx);
|
||||
GenericTilemapSetScrollY(0, scrolly);
|
||||
|
||||
GenericTilemapDraw(0, pTransDraw, 0);
|
||||
|
||||
DrawSprites();
|
||||
|
||||
BurnTransferCopy(BurnPalette);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static INT32 DrvFrame()
|
||||
{
|
||||
if (DrvReset) {
|
||||
DrvDoReset();
|
||||
}
|
||||
|
||||
ZetNewFrame();
|
||||
|
||||
{
|
||||
for (INT32 i = 0; i < 3; i++) {
|
||||
DrvInputs[i] = button_config >> (i * 8);
|
||||
}
|
||||
|
||||
for (INT32 i = 0; i < 8; i++) {
|
||||
DrvInputs[0] ^= (DrvJoy1[i] & 1) << i;
|
||||
DrvInputs[1] ^= (DrvJoy2[i] & 1) << i;
|
||||
DrvInputs[2] ^= (DrvJoy3[i] & 1) << i;
|
||||
}
|
||||
|
||||
if (is_gorodki) {
|
||||
DrvInputs[0] = ProcessAnalog(Analog[0], 1, 1, 0x60, 0xd0);
|
||||
}
|
||||
}
|
||||
|
||||
INT32 nInterleave = 312;
|
||||
INT32 nCyclesTotal[1] = { 1750000 / 60 };
|
||||
INT32 nCyclesDone[1] = { nExtraCycles };
|
||||
|
||||
vblank = 1;
|
||||
|
||||
for (INT32 i = 0; i < nInterleave; i++)
|
||||
{
|
||||
ZetOpen(0);
|
||||
CPU_RUN(0, Zet);
|
||||
ZetClose();
|
||||
|
||||
if (i == 56) vblank = 0;
|
||||
}
|
||||
|
||||
nExtraCycles = nCyclesDone[0] - nCyclesTotal[0];
|
||||
|
||||
if (pBurnSoundOut) {
|
||||
tiamc1_sound_update(pBurnSoundOut, nBurnSoundLen);
|
||||
}
|
||||
|
||||
if (pBurnDraw) {
|
||||
BurnDrvRedraw();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static INT32 DrvScan(INT32 nAction, INT32 *pnMin)
|
||||
{
|
||||
struct BurnArea ba;
|
||||
|
||||
if (pnMin) {
|
||||
*pnMin = 0x029702;
|
||||
}
|
||||
|
||||
if (nAction & ACB_VOLATILE) {
|
||||
memset(&ba, 0, sizeof(ba));
|
||||
|
||||
ba.Data = AllRam;
|
||||
ba.nLen = RamEnd - AllRam;
|
||||
ba.szName = "All Ram";
|
||||
BurnAcb(&ba);
|
||||
|
||||
ZetScan(nAction);
|
||||
|
||||
ppi8255_scan();
|
||||
|
||||
tiamc1_sound_scan(nAction, pnMin);
|
||||
|
||||
SCAN_VAR(layer_control);
|
||||
SCAN_VAR(character_bank);
|
||||
SCAN_VAR(scrollx);
|
||||
SCAN_VAR(scrolly);
|
||||
SCAN_VAR(bg_color);
|
||||
SCAN_VAR(update_characters);
|
||||
SCAN_VAR(update_colors);
|
||||
|
||||
SCAN_VAR(nExtraCycles);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// Konek-Gorbunok
|
||||
|
||||
static struct BurnRomInfo konekRomDesc[] = {
|
||||
{ "g1.d17", 0x2000, 0xf41d82c9, 1 | BRF_PRG | BRF_ESS }, // 0 i8080 Code
|
||||
{ "g2.d17", 0x2000, 0xb44e7491, 1 | BRF_PRG | BRF_ESS }, // 1
|
||||
{ "g3.d17", 0x2000, 0x91301282, 1 | BRF_PRG | BRF_ESS }, // 2
|
||||
{ "g4.d17", 0x2000, 0x3ff0c20b, 1 | BRF_PRG | BRF_ESS }, // 3
|
||||
{ "g5.d17", 0x2000, 0xe3196d30, 1 | BRF_PRG | BRF_ESS }, // 4
|
||||
{ "g7.d17", 0x2000, 0xfe4e9fdd, 1 | BRF_PRG | BRF_ESS }, // 5
|
||||
|
||||
{ "a2.b07", 0x2000, 0x9eed06ee, 2 | BRF_GRA }, // 6 Sprites
|
||||
{ "a3.g07", 0x2000, 0xeeff9b77, 2 | BRF_GRA }, // 7
|
||||
{ "a5.l07", 0x2000, 0xfff9e089, 2 | BRF_GRA }, // 8
|
||||
{ "a6.r07", 0x2000, 0x092e8ee2, 2 | BRF_GRA }, // 9
|
||||
|
||||
{ "prom100.e10", 0x0100, 0x00000000, 3 | BRF_NODUMP | BRF_GRA }, // 10 PROMs
|
||||
{ "prom101.a01", 0x0100, 0x00000000, 3 | BRF_NODUMP | BRF_GRA }, // 11
|
||||
{ "prom102.b03", 0x0080, 0x00000000, 3 | BRF_NODUMP | BRF_GRA }, // 12
|
||||
{ "prom102.b06", 0x0080, 0x00000000, 3 | BRF_NODUMP | BRF_GRA }, // 13
|
||||
{ "prom102.b05", 0x0100, 0x00000000, 3 | BRF_NODUMP | BRF_GRA }, // 14
|
||||
};
|
||||
|
||||
STD_ROM_PICK(konek)
|
||||
STD_ROM_FN(konek)
|
||||
|
||||
static INT32 KonekInit()
|
||||
{
|
||||
return DrvInit(6);
|
||||
}
|
||||
|
||||
struct BurnDriver BurnDrvKonek = {
|
||||
"konek", NULL, NULL, NULL, "198?",
|
||||
"Konek-Gorbunok\0", NULL, "Terminal", "TIA-MC1",
|
||||
NULL, NULL, NULL, NULL,
|
||||
BDF_GAME_WORKING, 2, HARDWARE_MISC_PRE90S, GBF_PLATFORM, 0,
|
||||
NULL, konekRomInfo, konekRomName, NULL, NULL, NULL, NULL, DrvInputInfo, NULL,
|
||||
KonekInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &BurnRecalc, 0x20,
|
||||
256, 256, 4, 3
|
||||
};
|
||||
|
||||
|
||||
// S.O.S.
|
||||
|
||||
static struct BurnRomInfo sostermRomDesc[] = {
|
||||
{ "04.1g", 0x2000, 0xd588081e, 1 | BRF_PRG | BRF_ESS }, // 0 i8080 Code
|
||||
{ "05.2g", 0x2000, 0xb44e7491, 1 | BRF_PRG | BRF_ESS }, // 1
|
||||
{ "06.3g", 0x2000, 0x34dacde6, 1 | BRF_PRG | BRF_ESS }, // 2
|
||||
{ "07.4g", 0x2000, 0x9f6f8cdd, 1 | BRF_PRG | BRF_ESS }, // 3
|
||||
{ "08.5g", 0x2000, 0x25e70da4, 1 | BRF_PRG | BRF_ESS }, // 4
|
||||
{ "10.7g", 0x2000, 0x22bc9997, 1 | BRF_PRG | BRF_ESS }, // 5
|
||||
|
||||
{ "00.2a", 0x2000, 0xa1c7f07a, 2 | BRF_GRA }, // 6 Sprites
|
||||
{ "01.3a", 0x2000, 0x788b4036, 2 | BRF_GRA }, // 7
|
||||
{ "02.5a", 0x2000, 0x9506cf9b, 2 | BRF_GRA }, // 8
|
||||
{ "03.6a", 0x2000, 0x5a0c14e1, 2 | BRF_GRA }, // 9
|
||||
|
||||
{ "prom100.e10", 0x0100, 0x00000000, 3 | BRF_NODUMP | BRF_GRA }, // 10 PROMs
|
||||
{ "prom101.a01", 0x0100, 0x00000000, 3 | BRF_NODUMP | BRF_GRA }, // 11
|
||||
{ "prom102.b03", 0x0080, 0x00000000, 3 | BRF_NODUMP | BRF_GRA }, // 12
|
||||
{ "prom102.b06", 0x0080, 0x00000000, 3 | BRF_NODUMP | BRF_GRA }, // 13
|
||||
{ "prom102.b05", 0x0100, 0x00000000, 3 | BRF_NODUMP | BRF_GRA }, // 14
|
||||
};
|
||||
|
||||
STD_ROM_PICK(sosterm)
|
||||
STD_ROM_FN(sosterm)
|
||||
|
||||
struct BurnDriver BurnDrvSosterm = {
|
||||
"sosterm", NULL, NULL, NULL, "198?",
|
||||
"S.O.S.\0", NULL, "Terminal", "TIA-MC1",
|
||||
NULL, NULL, NULL, NULL,
|
||||
BDF_GAME_WORKING, 2, HARDWARE_MISC_PRE90S, GBF_MISC, 0,
|
||||
NULL, sostermRomInfo, sostermRomName, NULL, NULL, NULL, NULL, DrvInputInfo, NULL,
|
||||
KonekInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &BurnRecalc, 0x20,
|
||||
256, 256, 4, 3
|
||||
};
|
||||
|
||||
|
||||
// Snezhnaja Koroleva
|
||||
|
||||
static struct BurnRomInfo korolevaRomDesc[] = {
|
||||
{ "04.1g", 0x2000, 0xc3701225, 1 | BRF_PRG | BRF_ESS }, // 0 i8080 Code
|
||||
{ "05.2g", 0x2000, 0x1b3742ce, 1 | BRF_PRG | BRF_ESS }, // 1
|
||||
{ "06.3g", 0x2000, 0x48074786, 1 | BRF_PRG | BRF_ESS }, // 2
|
||||
{ "07.4g", 0x2000, 0x41a4adb5, 1 | BRF_PRG | BRF_ESS }, // 3
|
||||
{ "08.5g", 0x2000, 0x8f379d95, 1 | BRF_PRG | BRF_ESS }, // 4
|
||||
{ "10.7g", 0x2000, 0x397f41f8, 1 | BRF_PRG | BRF_ESS }, // 5
|
||||
|
||||
{ "00.2a", 0x2000, 0x6f39f8be, 2 | BRF_GRA }, // 6 Sprites
|
||||
{ "01.3a", 0x2000, 0x7bdfdd19, 2 | BRF_GRA }, // 7
|
||||
{ "02.5a", 0x2000, 0x97770b0f, 2 | BRF_GRA }, // 8
|
||||
{ "03.6a", 0x2000, 0x9b0a686a, 2 | BRF_GRA }, // 9
|
||||
|
||||
{ "prom100.e10", 0x0100, 0x00000000, 3 | BRF_NODUMP | BRF_GRA }, // 10 PROMs
|
||||
{ "prom101.a01", 0x0100, 0x00000000, 3 | BRF_NODUMP | BRF_GRA }, // 11
|
||||
{ "prom102.b03", 0x0080, 0x00000000, 3 | BRF_NODUMP | BRF_GRA }, // 12
|
||||
{ "prom102.b06", 0x0080, 0x00000000, 3 | BRF_NODUMP | BRF_GRA }, // 13
|
||||
{ "prom102.b05", 0x0100, 0x00000000, 3 | BRF_NODUMP | BRF_GRA }, // 14
|
||||
};
|
||||
|
||||
STD_ROM_PICK(koroleva)
|
||||
STD_ROM_FN(koroleva)
|
||||
|
||||
struct BurnDriver BurnDrvKoroleva = {
|
||||
"koroleva", NULL, NULL, NULL, "198?",
|
||||
"Snezhnaja Koroleva\0", NULL, "Terminal", "TIA-MC1",
|
||||
NULL, NULL, NULL, NULL,
|
||||
BDF_GAME_WORKING, 2, HARDWARE_MISC_PRE90S, GBF_MAZE, 0,
|
||||
NULL, korolevaRomInfo, korolevaRomName, NULL, NULL, NULL, NULL, DrvInputInfo, NULL,
|
||||
KonekInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &BurnRecalc, 0x20,
|
||||
256, 256, 4, 3
|
||||
};
|
||||
|
||||
|
||||
// Billiard
|
||||
|
||||
static struct BurnRomInfo bilyardRomDesc[] = {
|
||||
{ "04.1g", 0x2000, 0xa44f913d, 1 | BRF_PRG | BRF_ESS }, // 0 i8080 Code
|
||||
{ "05.2g", 0x2000, 0x6e41219f, 1 | BRF_PRG | BRF_ESS }, // 1
|
||||
{ "10.7g", 0x2000, 0x173adb85, 1 | BRF_PRG | BRF_ESS }, // 2
|
||||
|
||||
{ "00.2a", 0x2000, 0x6f72e043, 2 | BRF_GRA }, // 3 Sprites
|
||||
{ "01.3a", 0x2000, 0xdaddbbb5, 2 | BRF_GRA }, // 4
|
||||
{ "02.5a", 0x2000, 0x3d744d33, 2 | BRF_GRA }, // 5
|
||||
{ "03.6a", 0x2000, 0x8bfc0b15, 2 | BRF_GRA }, // 6
|
||||
|
||||
{ "prom100.e10", 0x0100, 0x00000000, 3 | BRF_NODUMP | BRF_GRA }, // 7 PROMs
|
||||
{ "prom101.a01", 0x0100, 0x00000000, 3 | BRF_NODUMP | BRF_GRA }, // 8
|
||||
{ "prom102.b03", 0x0080, 0x00000000, 3 | BRF_NODUMP | BRF_GRA }, // 9
|
||||
{ "prom102.b06", 0x0080, 0x00000000, 3 | BRF_NODUMP | BRF_GRA }, // 10
|
||||
{ "prom102.b05", 0x0100, 0x00000000, 3 | BRF_NODUMP | BRF_GRA }, // 11
|
||||
};
|
||||
|
||||
STD_ROM_PICK(bilyard)
|
||||
STD_ROM_FN(bilyard)
|
||||
|
||||
static INT32 BilyardInit()
|
||||
{
|
||||
return DrvInit(3);
|
||||
}
|
||||
|
||||
struct BurnDriver BurnDrvBilyard = {
|
||||
"bilyard", NULL, NULL, NULL, "198?",
|
||||
"Billiard\0", NULL, "Terminal", "TIA-MC1",
|
||||
NULL, NULL, NULL, NULL,
|
||||
BDF_GAME_WORKING, 2, HARDWARE_MISC_PRE90S, GBF_SPORTSMISC, 0,
|
||||
NULL, bilyardRomInfo, bilyardRomName, NULL, NULL, NULL, NULL, DrvInputInfo, NULL,
|
||||
BilyardInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &BurnRecalc, 0x20,
|
||||
256, 256, 4, 3
|
||||
};
|
||||
|
||||
|
||||
// Gorodki
|
||||
|
||||
static struct BurnRomInfo gorodkiRomDesc[] = {
|
||||
{ "70.1g", 0x2000, 0xbd3eb624, 1 | BRF_PRG | BRF_ESS }, // 0 i8080 Code
|
||||
{ "71.2g", 0x2000, 0x5a9ebd8d, 1 | BRF_PRG | BRF_ESS }, // 1
|
||||
{ "72.3g", 0x2000, 0xedcc5c13, 1 | BRF_PRG | BRF_ESS }, // 2
|
||||
{ "73.4g", 0x2000, 0xae69b9f3, 1 | BRF_PRG | BRF_ESS }, // 3
|
||||
|
||||
{ "66.2a", 0x2000, 0xb3dd4dec, 2 | BRF_GRA }, // 4 Sprites
|
||||
{ "67.3a", 0x2000, 0xc94f5579, 2 | BRF_GRA }, // 5
|
||||
{ "68.5a", 0x2000, 0x0d64708d, 2 | BRF_GRA }, // 6
|
||||
{ "69.6a", 0x2000, 0x57c8ae81, 2 | BRF_GRA }, // 7
|
||||
|
||||
{ "prom100.e10", 0x0100, 0x00000000, 3 | BRF_NODUMP | BRF_GRA }, // 8 PROMs
|
||||
{ "prom101.a01", 0x0100, 0x00000000, 3 | BRF_NODUMP | BRF_GRA }, // 9
|
||||
{ "prom102.b03", 0x0080, 0x00000000, 3 | BRF_NODUMP | BRF_GRA }, // 10
|
||||
{ "prom102.b06", 0x0080, 0x00000000, 3 | BRF_NODUMP | BRF_GRA }, // 11
|
||||
{ "prom102.b05", 0x0100, 0x00000000, 3 | BRF_NODUMP | BRF_GRA }, // 12
|
||||
};
|
||||
|
||||
STD_ROM_PICK(gorodki)
|
||||
STD_ROM_FN(gorodki)
|
||||
|
||||
static INT32 GorodkiInit()
|
||||
{
|
||||
is_gorodki = 1;
|
||||
|
||||
return DrvInit(4);
|
||||
}
|
||||
|
||||
struct BurnDriver BurnDrvGorodki = {
|
||||
"gorodki", NULL, NULL, NULL, "198?",
|
||||
"Gorodki\0", NULL, "Terminal", "TIA-MC1",
|
||||
NULL, NULL, NULL, NULL,
|
||||
BDF_GAME_WORKING, 2, HARDWARE_MISC_PRE90S, GBF_MISC, 0,
|
||||
NULL, gorodkiRomInfo, gorodkiRomName, NULL, NULL, NULL, NULL, GorodkiInputInfo, NULL, // wrong input!
|
||||
GorodkiInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &BurnRecalc, 0x20,
|
||||
256, 256, 4, 3
|
||||
};
|
||||
|
||||
|
||||
// Kot-Rybolov (Terminal)
|
||||
|
||||
static struct BurnRomInfo kotRomDesc[] = {
|
||||
{ "854.6", 0x2000, 0x44e5e8fc, 1 | BRF_PRG | BRF_ESS }, // 0 i8080 Code
|
||||
{ "855.7", 0x2000, 0x0bb2e4b2, 1 | BRF_PRG | BRF_ESS }, // 1
|
||||
{ "856.8", 0x2000, 0x9180c98f, 1 | BRF_PRG | BRF_ESS }, // 2
|
||||
|
||||
{ "850.5", 0x2000, 0x5dc3a102, 2 | BRF_GRA }, // 3 Sprites
|
||||
{ "851.6", 0x2000, 0x7db239a0, 2 | BRF_GRA }, // 4
|
||||
{ "852.7", 0x2000, 0xc7700f88, 2 | BRF_GRA }, // 5
|
||||
{ "853.8", 0x2000, 0xb94bf1af, 2 | BRF_GRA }, // 6
|
||||
|
||||
{ "846.1", 0x2000, 0x42447f4a, 3 | BRF_GRA }, // 7 Tiles
|
||||
{ "847.2", 0x2000, 0x99ada5e8, 3 | BRF_GRA }, // 8
|
||||
{ "848.3", 0x2000, 0xa124cff4, 3 | BRF_GRA }, // 9
|
||||
{ "849.4", 0x2000, 0x5d27fda6, 3 | BRF_GRA }, // 10
|
||||
};
|
||||
|
||||
STD_ROM_PICK(kot)
|
||||
STD_ROM_FN(kot)
|
||||
|
||||
struct BurnDriver BurnDrvKot = {
|
||||
"kot", NULL, NULL, NULL, "198?",
|
||||
"Kot-Rybolov (Terminal)\0", NULL, "Terminal", "TIA-MC1",
|
||||
NULL, NULL, NULL, NULL,
|
||||
BDF_GAME_WORKING, 1, HARDWARE_MISC_PRE90S, GBF_VSFIGHT, 0,
|
||||
NULL, kotRomInfo, kotRomName, NULL, NULL, NULL, NULL, DrvInputInfo, NULL,
|
||||
KotInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &BurnRecalc, 0x20,
|
||||
256, 256, 4, 3
|
||||
};
|
384
src/burn/snd/tiamc1_snd.cpp
Normal file
384
src/burn/snd/tiamc1_snd.cpp
Normal file
@ -0,0 +1,384 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Eugene Sandulenko
|
||||
/***************************************************************************
|
||||
|
||||
TIA-MC1 sound hardware
|
||||
|
||||
driver by Eugene Sandulenko
|
||||
special thanks to Shiru for his standalone emulator and documentation
|
||||
|
||||
timer1 timer0
|
||||
|--------| |--------|
|
||||
| 8253 | | 8253 | |---|
|
||||
in0 | | | | | 1 | |---|
|
||||
----+ g0 o0 +---+ g0 o0 +---+ | | & |
|
||||
in1 | | | | | o---+ | out
|
||||
----+ g1 o1 +---+ g1 o1 +---+ | | +-----
|
||||
in2 | | | | |---| | |
|
||||
----+ g2 o2 +---+ g2 o2 +-----------+ |
|
||||
clk1| | | | |---|
|
||||
----+ clk | +-+ clk |
|
||||
| | | | |
|
||||
|--------| | |--------|
|
||||
clk0 |
|
||||
---------------+
|
||||
|
||||
in0-in2 comes from port #da
|
||||
clk0 comes from 8224 and equals to 1777777Hz, i.e. processor clock
|
||||
clk1 comes from divider 16000000/4/16/16/2 = 7812Hz
|
||||
|
||||
********************
|
||||
|
||||
TODO: use machine/pit8253.c
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include "burnint.h"
|
||||
#include "tiamc1_snd.h"
|
||||
#include "stream.h"
|
||||
|
||||
#define CLOCK_DIVIDER 16
|
||||
#define BUF_LEN 100000
|
||||
|
||||
#define T8253_CHAN0 0
|
||||
#define T8253_CHAN1 1
|
||||
#define T8253_CHAN2 2
|
||||
#define T8253_CWORD 3
|
||||
|
||||
#if 0
|
||||
// device type definition
|
||||
DEFINE_DEVICE_TYPE(TIAMC1, tiamc1_sound_device, "tiamc1_sound", "TIA-MC1 Custom Sound")
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// LIVE DEVICE
|
||||
//**************************************************************************
|
||||
|
||||
//-------------------------------------------------
|
||||
// tiamc1_sound_device - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
tiamc1_sound_device::tiamc1_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: device_t(mconfig, TIAMC1, tag, owner, clock),
|
||||
device_sound_interface(mconfig, *this),
|
||||
m_channel(nullptr),
|
||||
m_timer1_divider(0)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
struct timer8253chan
|
||||
{
|
||||
UINT16 count;
|
||||
UINT16 cnval;
|
||||
UINT8 bcdMode;
|
||||
UINT8 cntMode;
|
||||
UINT8 valMode;
|
||||
UINT8 gate;
|
||||
UINT8 output;
|
||||
UINT8 loadCnt;
|
||||
UINT8 enable;
|
||||
};
|
||||
|
||||
struct timer8253struct
|
||||
{
|
||||
struct timer8253chan channel[3];
|
||||
};
|
||||
|
||||
|
||||
static void timer8253_reset(struct timer8253struct *t);
|
||||
static void timer8253_tick(struct timer8253struct *t,int chn);
|
||||
static void timer8253_wr(struct timer8253struct *t, int reg, UINT8 val);
|
||||
static char timer8253_get_output(struct timer8253struct *t, int chn);
|
||||
static void timer8253_set_gate(struct timer8253struct *t, int chn, UINT8 gate);
|
||||
|
||||
static Stream stream;
|
||||
static int m_timer1_divider;
|
||||
|
||||
static timer8253struct m_timer0;
|
||||
static timer8253struct m_timer1;
|
||||
|
||||
static INT32 kot_mode;
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_start - device-specific startup
|
||||
//-------------------------------------------------
|
||||
static void sound_stream_update(INT16 **streams, INT32 length);
|
||||
|
||||
void tiamc1_sound_reset()
|
||||
{
|
||||
timer8253_reset(&m_timer0);
|
||||
timer8253_reset(&m_timer1);
|
||||
|
||||
m_timer1_divider = 0;
|
||||
}
|
||||
|
||||
void tiamc1_sound_init()
|
||||
{
|
||||
stream.init(15750000/9 / CLOCK_DIVIDER, nBurnSoundRate, 1, 0, sound_stream_update);
|
||||
|
||||
tiamc1_sound_reset();
|
||||
|
||||
kot_mode = 0;
|
||||
}
|
||||
|
||||
void tiamc1_sound_init_kot()
|
||||
{
|
||||
tiamc1_sound_init();
|
||||
|
||||
kot_mode = 1;
|
||||
}
|
||||
|
||||
void tiamc1_sound_exit()
|
||||
{
|
||||
stream.exit();
|
||||
}
|
||||
|
||||
void tiamc1_sound_update(INT16 *output, INT32 samples_len)
|
||||
{
|
||||
if (samples_len != nBurnSoundLen) {
|
||||
bprintf(0, _T("tiamc1_sound_update(): once per frame, please!\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
stream.render(output, samples_len);
|
||||
}
|
||||
|
||||
void tiamc1_sound_scan(INT32 nAction, INT32 *pnMin)
|
||||
{
|
||||
if (nAction & ACB_DRIVER_DATA) {
|
||||
SCAN_VAR(m_timer0);
|
||||
SCAN_VAR(m_timer1);
|
||||
SCAN_VAR(m_timer1_divider);
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// sound_stream_update - handle a stream update
|
||||
//-------------------------------------------------
|
||||
|
||||
static void sound_stream_update(INT16 **streams, INT32 length)
|
||||
{
|
||||
int count, o0, o1, o2, len, orval = 0;
|
||||
|
||||
len = length * CLOCK_DIVIDER;
|
||||
|
||||
for (count = 0; count < len; count++)
|
||||
{
|
||||
m_timer1_divider++;
|
||||
if (m_timer1_divider == 228)
|
||||
{
|
||||
m_timer1_divider = 0;
|
||||
timer8253_tick(&m_timer1, 0);
|
||||
timer8253_tick(&m_timer1, 1);
|
||||
timer8253_tick(&m_timer1, 2);
|
||||
|
||||
timer8253_set_gate(&m_timer0, 0, timer8253_get_output(&m_timer1, 0));
|
||||
timer8253_set_gate(&m_timer0, 1, timer8253_get_output(&m_timer1, 1));
|
||||
timer8253_set_gate(&m_timer0, 2, timer8253_get_output(&m_timer1, 2));
|
||||
}
|
||||
|
||||
if (kot_mode) // myow!
|
||||
{
|
||||
timer8253_set_gate(&m_timer0, 2, 1);
|
||||
}
|
||||
|
||||
timer8253_tick(&m_timer0, 0);
|
||||
timer8253_tick(&m_timer0, 1);
|
||||
timer8253_tick(&m_timer0, 2);
|
||||
|
||||
o0 = timer8253_get_output(&m_timer0, 0) ? 1 : 0;
|
||||
o1 = timer8253_get_output(&m_timer0, 1) ? 1 : 0;
|
||||
o2 = timer8253_get_output(&m_timer0, 2) ? 1 : 0;
|
||||
|
||||
orval = (orval << 1) | (((o0 | o1) ^ 0xff) & o2);
|
||||
|
||||
if ((count + 1) % CLOCK_DIVIDER == 0)
|
||||
{
|
||||
streams[0][count / CLOCK_DIVIDER] = orval ? 0x2828 : 0;
|
||||
orval = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void timer8253_reset(struct timer8253struct *t)
|
||||
{
|
||||
memset(t,0,sizeof(struct timer8253struct));
|
||||
}
|
||||
|
||||
|
||||
static void timer8253_tick(struct timer8253struct *t, int chn)
|
||||
{
|
||||
if (t->channel[chn].enable && t->channel[chn].gate)
|
||||
{
|
||||
switch (t->channel[chn].cntMode)
|
||||
{
|
||||
case 0:
|
||||
t->channel[chn].count--;
|
||||
if (t->channel[chn].count == 0xffff)
|
||||
t->channel[chn].output = 1;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
t->channel[chn].count--;
|
||||
|
||||
if (t->channel[chn].count < (t->channel[chn].cnval >> 1))
|
||||
t->channel[chn].output = 0;
|
||||
else
|
||||
t->channel[chn].output = 1;
|
||||
|
||||
if (t->channel[chn].count == 0xffff)
|
||||
t->channel[chn].count = t->channel[chn].cnval;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
t->channel[chn].count--;
|
||||
if(t->channel[chn].count==0)
|
||||
t->channel[chn].output = 1;
|
||||
|
||||
if(t->channel[chn].count == 0xffff)
|
||||
{
|
||||
t->channel[chn].enable = 0;
|
||||
t->channel[chn].output = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void timer8253_wr(struct timer8253struct *t, int reg, UINT8 val)
|
||||
{
|
||||
int chn;
|
||||
|
||||
switch (reg)
|
||||
{
|
||||
case T8253_CWORD:
|
||||
chn = val >> 6;
|
||||
if (chn < 3)
|
||||
{
|
||||
t->channel[chn].bcdMode = (val & 1) ? 1 : 0;
|
||||
t->channel[chn].cntMode = (val >> 1) & 0x07;
|
||||
t->channel[chn].valMode = (val >> 4) & 0x03;
|
||||
|
||||
switch (t->channel[chn].valMode)
|
||||
{
|
||||
case 1:
|
||||
case 2:
|
||||
t->channel[chn].loadCnt = 1;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
t->channel[chn].loadCnt = 2;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (t->channel[chn].cntMode)
|
||||
{
|
||||
case 0:
|
||||
t->channel[chn].output = 0;
|
||||
t->channel[chn].enable = 0;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
t->channel[chn].output = 1;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
t->channel[chn].output = 1;
|
||||
t->channel[chn].enable = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
chn = reg;
|
||||
|
||||
switch (t->channel[chn].valMode)
|
||||
{
|
||||
case 1:
|
||||
t->channel[chn].cnval = (t->channel[chn].cnval & 0xff00) | val;
|
||||
break;
|
||||
case 2:
|
||||
t->channel[chn].cnval = (t->channel[chn].cnval & 0x00ff) | (val << 8);
|
||||
break;
|
||||
case 3:
|
||||
t->channel[chn].cnval = (t->channel[chn].cnval >> 8) | (val << 8);
|
||||
break;
|
||||
}
|
||||
|
||||
if (t->channel[chn].cntMode==0)
|
||||
{
|
||||
t->channel[chn].enable = 0;
|
||||
}
|
||||
|
||||
t->channel[chn].loadCnt--;
|
||||
|
||||
if (t->channel[chn].loadCnt == 0)
|
||||
{
|
||||
switch (t->channel[chn].valMode)
|
||||
{
|
||||
case 1:
|
||||
case 2:
|
||||
t->channel[chn].loadCnt = 1;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
t->channel[chn].loadCnt = 2;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (t->channel[chn].cntMode)
|
||||
{
|
||||
case 3:
|
||||
t->channel[chn].count = t->channel[chn].cnval;
|
||||
t->channel[chn].enable = 1;
|
||||
break;
|
||||
|
||||
case 0:
|
||||
case 4:
|
||||
t->channel[chn].count = t->channel[chn].cnval;
|
||||
t->channel[chn].enable = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void timer8253_set_gate(struct timer8253struct *t, int chn, UINT8 gate)
|
||||
{
|
||||
t->channel[chn].gate = gate;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static char timer8253_get_output(struct timer8253struct *t, int chn)
|
||||
{
|
||||
return t->channel[chn].output;
|
||||
}
|
||||
|
||||
void tiamc1_sound_timer0_write(INT32 offset, UINT8 data)
|
||||
{
|
||||
stream.update();
|
||||
|
||||
timer8253_wr(&m_timer0, offset, data);
|
||||
}
|
||||
|
||||
void tiamc1_sound_timer1_write(INT32 offset, UINT8 data)
|
||||
{
|
||||
stream.update();
|
||||
|
||||
timer8253_wr(&m_timer1, offset, data);
|
||||
}
|
||||
|
||||
void tiamc1_sound_gate_write(UINT8 data)
|
||||
{
|
||||
stream.update();
|
||||
|
||||
timer8253_set_gate(&m_timer1, 0, (data & 1) ? 1 : 0);
|
||||
timer8253_set_gate(&m_timer1, 1, (data & 2) ? 1 : 0);
|
||||
timer8253_set_gate(&m_timer1, 2, (data & 4) ? 1 : 0);
|
||||
}
|
12
src/burn/snd/tiamc1_snd.h
Normal file
12
src/burn/snd/tiamc1_snd.h
Normal file
@ -0,0 +1,12 @@
|
||||
// tia mc1 sound core
|
||||
void tiamc1_sound_init();
|
||||
void tiamc1_sound_init_kot();
|
||||
void tiamc1_sound_exit();
|
||||
void tiamc1_sound_update(INT16 *output, INT32 samples_len);
|
||||
void tiamc1_sound_scan(INT32 nAction, INT32 *pnMin);
|
||||
void tiamc1_sound_reset();
|
||||
|
||||
void tiamc1_sound_timer0_write(INT32 offset, UINT8 data);
|
||||
void tiamc1_sound_timer1_write(INT32 offset, UINT8 data);
|
||||
void tiamc1_sound_gate_write(UINT8 data);
|
||||
|
Loading…
Reference in New Issue
Block a user