kopia lustrzana https://github.com/Jean-MarcHarvengt/MCUME
image a bit more stable
rodzic
a2553293f9
commit
5397743cbb
|
@ -115,55 +115,59 @@ void cpc_Start(char* filename)
|
|||
*/
|
||||
void cpc_Step(void)
|
||||
{
|
||||
//for(;!is_hsync_active();)
|
||||
//{
|
||||
|
||||
// if not (z80 wait and ga wait) then tick, otherwise stall.
|
||||
// or rather the tick will be a stall if both waits are asserted, i think that's better.
|
||||
bool interrupt_acknowledged = false;
|
||||
if(!(pins&Z80_WAIT && ga_config.wait_signal))
|
||||
pins = z80_tick(&CPU, pins);
|
||||
|
||||
if (pins & Z80_MREQ)
|
||||
{
|
||||
pins = z80_tick(&CPU, pins);
|
||||
if (pins & Z80_MREQ)
|
||||
const uint16_t addr = Z80_GET_ADDR(pins);
|
||||
if (pins & Z80_RD)
|
||||
{
|
||||
const uint16_t addr = Z80_GET_ADDR(pins);
|
||||
if (pins & Z80_RD)
|
||||
{
|
||||
uint8_t data = read_z80(addr);
|
||||
Z80_SET_DATA(pins, data);
|
||||
}
|
||||
else if (pins & Z80_WR)
|
||||
{
|
||||
uint8_t data = Z80_GET_DATA(pins);
|
||||
write_z80(addr, data);
|
||||
}
|
||||
uint8_t data = read_z80(addr);
|
||||
Z80_SET_DATA(pins, data);
|
||||
}
|
||||
else if (pins & Z80_IORQ)
|
||||
else if (pins & Z80_WR)
|
||||
{
|
||||
const uint16_t port = Z80_GET_ADDR(pins);
|
||||
if (pins & Z80_M1)
|
||||
{
|
||||
// an interrupt acknowledge cycle, depending on the emulated system,
|
||||
// put either an instruction byte, or an interrupt vector on the data bus
|
||||
Z80_SET_DATA(pins, 0x0038);
|
||||
interrupt_acknowledged = true;
|
||||
}
|
||||
else if (pins & Z80_RD)
|
||||
{
|
||||
// handle IO input request at port
|
||||
in_z80(port);
|
||||
}
|
||||
else if (pins & Z80_WR)
|
||||
{
|
||||
// handle IO output request at port
|
||||
uint8_t data = Z80_GET_DATA(pins);
|
||||
out_z80(port, data);
|
||||
}
|
||||
uint8_t data = Z80_GET_DATA(pins);
|
||||
write_z80(addr, data);
|
||||
}
|
||||
}
|
||||
else if (pins & Z80_IORQ)
|
||||
{
|
||||
const uint16_t port = Z80_GET_ADDR(pins);
|
||||
if (pins & Z80_M1)
|
||||
{
|
||||
// an interrupt acknowledge cycle, depending on the emulated system,
|
||||
// put either an instruction byte, or an interrupt vector on the data bus
|
||||
Z80_SET_DATA(pins, 0x0038);
|
||||
interrupt_acknowledged = true;
|
||||
}
|
||||
else if (pins & Z80_RD)
|
||||
{
|
||||
// handle IO input request at port
|
||||
in_z80(port);
|
||||
}
|
||||
else if (pins & Z80_WR)
|
||||
{
|
||||
// handle IO output request at port
|
||||
uint8_t data = Z80_GET_DATA(pins);
|
||||
out_z80(port, data);
|
||||
}
|
||||
}
|
||||
|
||||
crtc_step();
|
||||
interrupt_generated = ga_step();
|
||||
if(ga_config.wait_signal)
|
||||
{
|
||||
// printf("Waiting in the next cycle.\n");
|
||||
pins = pins | Z80_WAIT;
|
||||
} else
|
||||
{
|
||||
// printf("Not waiting in the next cycle.\n");
|
||||
pins = pins & ~Z80_WAIT;
|
||||
}
|
||||
if(interrupt_generated)
|
||||
{
|
||||
// To request an interrupt, or inject a wait state just set the respective pin
|
||||
|
@ -173,37 +177,25 @@ void cpc_Step(void)
|
|||
|
||||
// request an interrupt from the CPU
|
||||
// TODO how to set the Z80_INT pin?
|
||||
|
||||
pins = pins | Z80_INT;
|
||||
}
|
||||
|
||||
if(interrupt_acknowledged)
|
||||
{
|
||||
pins = pins & ~Z80_INT;
|
||||
ga_config.interrupt_counter &= 0x1f;
|
||||
}
|
||||
|
||||
if(is_hsync_active())
|
||||
if(is_hsync_active() && !vsync_wait)
|
||||
{
|
||||
if(sline + 1 == NBLINES)
|
||||
{
|
||||
emu_DrawVsync();
|
||||
vsync_wait = true;
|
||||
}
|
||||
sline = (sline + 1) % NBLINES;
|
||||
emu_DrawLine8(bitstream, WIDTH, HEIGHT, sline);
|
||||
}
|
||||
|
||||
if(is_vsync_active())
|
||||
{
|
||||
emu_DrawVsync();
|
||||
}
|
||||
|
||||
while(is_hsync_active())
|
||||
{
|
||||
crtc_step();
|
||||
ga_step();
|
||||
}
|
||||
|
||||
while(is_vsync_active())
|
||||
{
|
||||
crtc_step();
|
||||
ga_step();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void cpc_Input(int bClick)
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
extern uint8_t RAM[0x10000];
|
||||
extern unsigned char* bitstream;
|
||||
extern struct GAConfig ga_config;
|
||||
extern bool vsync_wait;
|
||||
|
||||
extern void draw_vsync();
|
||||
extern void cpc_Init(void);
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "cpc.h"
|
||||
|
||||
struct GAConfig ga_config;
|
||||
bool vsync_wait = true;
|
||||
uint8_t microsecond_count_ga = 0;
|
||||
|
||||
/**
|
||||
|
@ -125,6 +126,11 @@ char ga_rgb_to_vga(uint8_t r, uint8_t g, uint8_t b)
|
|||
|
||||
void address_to_pixels()
|
||||
{
|
||||
if(!ga_config.vsync_active && is_vsync_active())
|
||||
{
|
||||
vsync_wait = false;
|
||||
}
|
||||
|
||||
// When HSYNC is active Gate-Array outputs the palette colour black
|
||||
if(ga_config.hsync_active)
|
||||
{
|
||||
|
@ -218,7 +224,7 @@ void address_to_pixels()
|
|||
|
||||
bool ga_step()
|
||||
{
|
||||
ga_config.wait_signal = microsecond_count_ga == 2;
|
||||
ga_config.wait_signal = microsecond_count_ga == 1;
|
||||
|
||||
if(microsecond_count_ga == 3)
|
||||
{
|
||||
|
@ -261,7 +267,6 @@ void select_pen_colour(uint8_t value)
|
|||
|
||||
void rom_and_screen_mgmt(uint8_t value)
|
||||
{
|
||||
|
||||
if(!ga_config.hsync_active && is_hsync_active())
|
||||
{
|
||||
// Screen mode config, dictated by the least significant 2 bits.
|
||||
|
|
|
@ -30,7 +30,7 @@ struct GAConfig {
|
|||
bool hsync_active = false;
|
||||
bool vsync_active = false;
|
||||
uint8_t ram_banking = 0; // unused in CPC 464
|
||||
bool wait_signal = true;
|
||||
bool wait_signal = false;
|
||||
};
|
||||
|
||||
extern struct RGB firmware_palette[27];
|
||||
|
|
|
@ -99,7 +99,7 @@ void emu_DrawVsync(void)
|
|||
volatile bool vb=vbl;
|
||||
while (vbl==vb) {};
|
||||
#ifdef USE_VGA
|
||||
tft.waitSync();
|
||||
// tft.waitSync();
|
||||
#else
|
||||
// volatile bool vb=vbl;
|
||||
// while (vbl==vb) {};
|
||||
|
|
Ładowanie…
Reference in New Issue