Vectrex: 6522 work

This commit is contained in:
alyosha-tas 2019-05-26 09:16:53 -04:00
parent 05b770fcff
commit cd1ab99f54
8 changed files with 181 additions and 55 deletions

View File

@ -633,24 +633,24 @@ namespace BizHawk.Emulation.Common.Components.MC6809
{
ser.BeginSection("MC6809");
ser.Sync("IN_SYNC", ref IN_SYNC);
ser.Sync("NMIPending", ref NMIPending);
ser.Sync("FIRQPending", ref FIRQPending);
ser.Sync("IRQPending", ref IRQPending);
ser.Sync(nameof(IN_SYNC), ref IN_SYNC);
ser.Sync(nameof(NMIPending), ref NMIPending);
ser.Sync(nameof(FIRQPending), ref FIRQPending);
ser.Sync(nameof(IRQPending), ref IRQPending);
ser.Sync("indexed_op", ref indexed_op);
ser.Sync("indexed_reg", ref indexed_reg);
ser.Sync("indexed_op_reg", ref indexed_op_reg);
ser.Sync("temp", ref temp);
ser.Sync(nameof(indexed_op), ref indexed_op);
ser.Sync(nameof(indexed_reg), ref indexed_reg);
ser.Sync(nameof(indexed_op_reg), ref indexed_op_reg);
ser.Sync(nameof(temp), ref temp);
ser.Sync("instr_pntr", ref instr_pntr);
ser.Sync("cur_instr", ref cur_instr, false);
ser.Sync("opcode_see", ref opcode_see);
ser.Sync("IRQS", ref IRQS);
ser.Sync("irq_pntr", ref irq_pntr);
ser.Sync(nameof(instr_pntr), ref instr_pntr);
ser.Sync(nameof(cur_instr), ref cur_instr, false);
ser.Sync(nameof(opcode_see), ref opcode_see);
ser.Sync(nameof(IRQS), ref IRQS);
ser.Sync(nameof(irq_pntr), ref irq_pntr);
ser.Sync("Regs", ref Regs, false);
ser.Sync("TotalExecutedCycles", ref TotalExecutedCycles);
ser.Sync(nameof(Regs), ref Regs, false);
ser.Sync(nameof(TotalExecutedCycles), ref TotalExecutedCycles);
ser.EndSection();
}

View File

@ -57,21 +57,21 @@ namespace BizHawk.Emulation.Cores.Consoles.Vectrex
{
ser.BeginSection("PSG");
ser.Sync("Register", ref Register, false);
ser.Sync(nameof(Register), ref Register, false);
ser.Sync("psg_clock", ref psg_clock);
ser.Sync("clock_A", ref clock_A);
ser.Sync("clock_B", ref clock_B);
ser.Sync("clock_C", ref clock_C);
ser.Sync("noise_clock", ref noise_clock);
ser.Sync("env_clock", ref env_clock);
ser.Sync("A_up", ref A_up);
ser.Sync("B_up", ref B_up);
ser.Sync("C_up", ref C_up);
ser.Sync("noise", ref noise);
ser.Sync("env_E", ref env_E);
ser.Sync("E_up_down", ref E_up_down);
ser.Sync("port_sel", ref port_sel);
ser.Sync(nameof(psg_clock), ref psg_clock);
ser.Sync(nameof(clock_A), ref clock_A);
ser.Sync(nameof(clock_B), ref clock_B);
ser.Sync(nameof(clock_C), ref clock_C);
ser.Sync(nameof(noise_clock), ref noise_clock);
ser.Sync(nameof(env_clock), ref env_clock);
ser.Sync(nameof(A_up), ref A_up);
ser.Sync(nameof(B_up), ref B_up);
ser.Sync(nameof(C_up), ref C_up);
ser.Sync(nameof(noise), ref noise);
ser.Sync(nameof(env_E), ref env_E);
ser.Sync(nameof(E_up_down), ref E_up_down);
ser.Sync(nameof(port_sel), ref port_sel);
sync_psg_state();

View File

@ -6,19 +6,27 @@ using BizHawk.Common;
namespace BizHawk.Emulation.Cores.Consoles.Vectrex
{
// MOS6522 Interface
/* Port B writes to both the PSG and the DAC simultaneously
* The trick here is that bits 3 and 4 both zero represent PSG disabled
* So it's easy to not interfere with the PSG
* However, the DAC will always receive some input, controlled by the multiplexer and selector bits
* BIOS functions keep everything in order
*/
public partial class VectrexHawk
{
public byte dir_dac, dir_ctrl;
public byte portB_ret, portA_ret;
public byte t1_low, t1_high;
public int t1_counter;
public bool t1_on, t1_shot_done;
public bool PB7;
public byte int_en, int_fl, aux_ctrl;
public byte Read_Registers(int addr)
{
byte ret = 0;
@ -27,9 +35,15 @@ namespace BizHawk.Emulation.Cores.Consoles.Vectrex
{
case 0x0:
ret = portB_ret;
int_fl &= 0xE7;
update_int_fl();
break;
case 0x1:
ret = portA_ret;
int_fl &= 0xFC;
update_int_fl();
break;
case 0x2:
ret = dir_ctrl;
@ -38,26 +52,38 @@ namespace BizHawk.Emulation.Cores.Consoles.Vectrex
ret = dir_dac;
break;
case 0x4:
ret = (byte)(t1_counter & 0xFF);
int_fl &= 0xBF;
update_int_fl();
break;
case 0x5:
ret = (byte)((t1_counter >> 8) & 0xFF);
break;
case 0x6:
ret = t1_low;
break;
case 0x7:
ret = t1_high;
break;
case 0x8:
break;
case 0x9:
break;
case 0xA:
int_fl &= 0xFB;
update_int_fl();
break;
case 0xB:
ret = aux_ctrl;
break;
case 0xC:
break;
case 0xD:
ret = int_fl;
break;
case 0xE:
ret = int_en;
break;
case 0xF:
break;
@ -73,9 +99,15 @@ namespace BizHawk.Emulation.Cores.Consoles.Vectrex
{
case 0x0:
wrt_val = (byte)(value & dir_ctrl);
int_fl &= 0xE7;
update_int_fl();
break;
case 0x1:
wrt_val = (byte)(value & dir_dac);
int_fl &= 0xFC;
update_int_fl();
break;
case 0x2:
dir_ctrl = value;
@ -84,26 +116,56 @@ namespace BizHawk.Emulation.Cores.Consoles.Vectrex
dir_dac = value;
break;
case 0x4:
t1_low = value;
break;
case 0x5:
t1_high = value;
t1_counter = (t1_high << 8) | t1_low;
t1_on = true;
t1_shot_done = false;
if (aux_ctrl.Bit(7)) { PB7 = true; }
int_fl &= 0xBF;
update_int_fl();
break;
case 0x6:
t1_low = value;
break;
case 0x7:
t1_high = value;
int_fl &= 0xBF;
update_int_fl();
break;
case 0x8:
break;
case 0x9:
break;
case 0xA:
int_fl &= 0xFB;
update_int_fl();
break;
case 0xB:
aux_ctrl = value;
break;
case 0xC:
break;
case 0xD:
// writing to flags does not clear bit 7 directly
int_fl &= (byte)~(value & 0x7F);
update_int_fl();
break;
case 0xE:
// bit 7 is always 0
if (value.Bit(7))
{
int_en |= (byte)(value & 0x7F);
}
else
{
int_en &= (byte)((~value) & 0x7F);
}
break;
case 0xF:
break;
@ -114,5 +176,56 @@ namespace BizHawk.Emulation.Cores.Consoles.Vectrex
{
}
public void timer_1_tick()
{
if (t1_on)
{
t1_counter--;
if (t1_counter == 0)
{
if (aux_ctrl.Bit(6))
{
t1_counter = (t1_high << 8) | t1_low;
int_fl |= 0x40;
//if (int_en.Bit(6)) { cpu.IRQPending = true; }
if (aux_ctrl.Bit(7)) { PB7 = !PB7; }
}
else
{
t1_counter = 0xFFFF;
if (!t1_shot_done)
{
int_fl |= 0x40;
//if (int_en.Bit(6)) { cpu.IRQPending = true; }
if (aux_ctrl.Bit(7)) { PB7 = false; }
}
t1_shot_done = true;
}
}
}
}
public void timer_2_tick()
{
}
public void update_int_fl()
{
// bit 7 is (IF.bit(X) & IE.bit(X)) OR'ed together for each bit
bool test = false;
for (int i = 0; i < 7; i++)
{
test |= int_en.Bit(i) & int_fl.Bit(i);
}
int_fl |= (byte)(test ? 0x80 : 0);
}
}
}

View File

@ -17,7 +17,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Vectrex
public override byte ReadMemory(ushort addr)
{
return 0xFF;
return Core._rom[addr];
}
public override byte PeekMemory(ushort addr)

View File

@ -5,10 +5,13 @@ using BizHawk.Emulation.Common;
/*
Fill in the memory map in this space for easy reference
ex:
0x0000 - 0x0FFF RAM
etc
0x0000 - 0x7FFF ROM
0x8000 - 0xC7FF Unmapped
0xC800 - 0xCFFF RAM (and shadows)
0xD000 - 0XD7FF 6522 (and shadows)
0xD800 - 0xDFFF 6522 + RAM
0xE000 - 0xEFFF Minestorm
0xF000 - 0xFFFF BIOS
*/
namespace BizHawk.Emulation.Cores.Consoles.Vectrex
@ -21,7 +24,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Vectrex
if (addr < 0x8000)
{
return 0xFF;
return mapper.ReadMemory(addr);
}
else if (addr < 0xC800)
{

View File

@ -44,9 +44,11 @@ namespace BizHawk.Emulation.Cores.Consoles.Vectrex
public void do_frame()
{
for (int i = 0; i < 4500; i++)
for (int i = 0; i < 45000; i++)
{
cpu.ExecuteOne();
timer_1_tick();
timer_2_tick();
cpu.ExecuteOne();
}
}

View File

@ -38,14 +38,6 @@ namespace BizHawk.Emulation.Cores.Consoles.Vectrex
return ms.ToArray();
}
// here is where all your savestated stuff will be called
// make sure every variable you make is savestated
// also all the components with their own savestate functions need to be called form here
// for normal single variables the format is:
// ser.Sync("var_name", ref var_name);
// for arrays, use:
// ser.Sync("var_name", ref var_name, false);
private void SyncState(Serializer ser)
{
byte[] core = null;
@ -61,14 +53,35 @@ namespace BizHawk.Emulation.Cores.Consoles.Vectrex
serialport.SyncState(ser);
audio.SyncState(ser);
ser.BeginSection("VIC20");
ser.BeginSection("VECTREX");
ser.Sync("RAM", ref RAM, false);
ser.Sync(nameof(RAM), ref RAM, false);
ser.Sync(nameof(dir_dac), ref dir_dac);
ser.Sync(nameof(dir_ctrl), ref dir_ctrl);
ser.Sync(nameof(portB_ret), ref portB_ret);
ser.Sync(nameof(portA_ret), ref portA_ret);
ser.Sync(nameof(t1_low), ref t1_low);
ser.Sync(nameof(t1_high), ref t1_high);
ser.Sync(nameof(t1_counter), ref t1_counter);
ser.Sync(nameof(t1_on), ref t1_on);
ser.Sync(nameof(t1_shot_done), ref t1_shot_done);
ser.Sync(nameof(PB7), ref PB7);
ser.Sync(nameof(int_en), ref int_en);
ser.Sync(nameof(int_fl), ref int_fl);
ser.Sync(nameof(aux_ctrl), ref aux_ctrl);
ser.Sync(nameof(_frame), ref _frame);
ser.Sync(nameof(_lagcount), ref _lagcount);
ser.Sync(nameof(_islag), ref _islag);
// probably a better way to do this
if (cart_RAM != null)
{
ser.Sync("cart_RAM", ref cart_RAM, false);
ser.Sync(nameof(cart_RAM), ref cart_RAM, false);
}
ser.EndSection();

View File

@ -23,8 +23,6 @@ namespace BizHawk.Emulation.Cores.Consoles.Vectrex
public byte[] _bios;
public readonly byte[] _rom;
public readonly byte[] header = new byte[0x50];
public byte[] cart_RAM;
public bool has_bat;
@ -67,10 +65,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Vectrex
Bios = comm.CoreFileProvider.GetFirmware("Vectrex", "Bios", true, "BIOS Not Found, Cannot Load");
_bios = Bios;
Buffer.BlockCopy(rom, 0x100, header, 0, 0x50);
string hash_md5 = null;
hash_md5 = "md5:" + rom.HashMD5(0, rom.Length);
Console.WriteLine(hash_md5);
Console.WriteLine("SHA1:" + rom.HashSHA1(0, rom.Length));
_rom = rom;
Setup_Mapper();