image a bit more stable

pull/31/head
AlinTigaeru 2023-03-01 18:32:08 +00:00
rodzic a2553293f9
commit 5397743cbb
5 zmienionych plików z 59 dodań i 61 usunięć

Wyświetl plik

@ -115,55 +115,59 @@ void cpc_Start(char* filename)
*/ */
void cpc_Step(void) void cpc_Step(void)
{ {
//for(;!is_hsync_active();)
//{
// if not (z80 wait and ga wait) then tick, otherwise stall. // 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. // or rather the tick will be a stall if both waits are asserted, i think that's better.
bool interrupt_acknowledged = false; 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); const uint16_t addr = Z80_GET_ADDR(pins);
if (pins & Z80_MREQ) if (pins & Z80_RD)
{ {
const uint16_t addr = Z80_GET_ADDR(pins); uint8_t data = read_z80(addr);
if (pins & Z80_RD) Z80_SET_DATA(pins, data);
{
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);
}
} }
else if (pins & Z80_IORQ) else if (pins & Z80_WR)
{ {
const uint16_t port = Z80_GET_ADDR(pins); uint8_t data = Z80_GET_DATA(pins);
if (pins & Z80_M1) write_z80(addr, data);
{ }
// an interrupt acknowledge cycle, depending on the emulated system, }
// put either an instruction byte, or an interrupt vector on the data bus else if (pins & Z80_IORQ)
Z80_SET_DATA(pins, 0x0038); {
interrupt_acknowledged = true; const uint16_t port = Z80_GET_ADDR(pins);
} if (pins & Z80_M1)
else if (pins & Z80_RD) {
{ // an interrupt acknowledge cycle, depending on the emulated system,
// handle IO input request at port // put either an instruction byte, or an interrupt vector on the data bus
in_z80(port); Z80_SET_DATA(pins, 0x0038);
} interrupt_acknowledged = true;
else if (pins & Z80_WR) }
{ else if (pins & Z80_RD)
// handle IO output request at port {
uint8_t data = Z80_GET_DATA(pins); // handle IO input request at port
out_z80(port, data); 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(); crtc_step();
interrupt_generated = ga_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) if(interrupt_generated)
{ {
// To request an interrupt, or inject a wait state just set the respective pin // 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 // request an interrupt from the CPU
// TODO how to set the Z80_INT pin? // TODO how to set the Z80_INT pin?
pins = pins | Z80_INT;
} }
if(interrupt_acknowledged) if(interrupt_acknowledged)
{ {
pins = pins & ~Z80_INT;
ga_config.interrupt_counter &= 0x1f; 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; sline = (sline + 1) % NBLINES;
emu_DrawLine8(bitstream, WIDTH, HEIGHT, sline); 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) void cpc_Input(int bClick)

Wyświetl plik

@ -9,6 +9,7 @@
extern uint8_t RAM[0x10000]; extern uint8_t RAM[0x10000];
extern unsigned char* bitstream; extern unsigned char* bitstream;
extern struct GAConfig ga_config; extern struct GAConfig ga_config;
extern bool vsync_wait;
extern void draw_vsync(); extern void draw_vsync();
extern void cpc_Init(void); extern void cpc_Init(void);

Wyświetl plik

@ -8,6 +8,7 @@
#include "cpc.h" #include "cpc.h"
struct GAConfig ga_config; struct GAConfig ga_config;
bool vsync_wait = true;
uint8_t microsecond_count_ga = 0; 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() 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 // When HSYNC is active Gate-Array outputs the palette colour black
if(ga_config.hsync_active) if(ga_config.hsync_active)
{ {
@ -218,7 +224,7 @@ void address_to_pixels()
bool ga_step() bool ga_step()
{ {
ga_config.wait_signal = microsecond_count_ga == 2; ga_config.wait_signal = microsecond_count_ga == 1;
if(microsecond_count_ga == 3) if(microsecond_count_ga == 3)
{ {
@ -261,7 +267,6 @@ void select_pen_colour(uint8_t value)
void rom_and_screen_mgmt(uint8_t value) void rom_and_screen_mgmt(uint8_t value)
{ {
if(!ga_config.hsync_active && is_hsync_active()) if(!ga_config.hsync_active && is_hsync_active())
{ {
// Screen mode config, dictated by the least significant 2 bits. // Screen mode config, dictated by the least significant 2 bits.

Wyświetl plik

@ -30,7 +30,7 @@ struct GAConfig {
bool hsync_active = false; bool hsync_active = false;
bool vsync_active = false; bool vsync_active = false;
uint8_t ram_banking = 0; // unused in CPC 464 uint8_t ram_banking = 0; // unused in CPC 464
bool wait_signal = true; bool wait_signal = false;
}; };
extern struct RGB firmware_palette[27]; extern struct RGB firmware_palette[27];

Wyświetl plik

@ -99,7 +99,7 @@ void emu_DrawVsync(void)
volatile bool vb=vbl; volatile bool vb=vbl;
while (vbl==vb) {}; while (vbl==vb) {};
#ifdef USE_VGA #ifdef USE_VGA
tft.waitSync(); // tft.waitSync();
#else #else
// volatile bool vb=vbl; // volatile bool vb=vbl;
// while (vbl==vb) {}; // while (vbl==vb) {};