Vectrex: 6522 work
This commit is contained in:
parent
05b770fcff
commit
cd1ab99f54
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue