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)
|
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)
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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];
|
||||||
|
|
|
@ -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) {};
|
||||||
|
|
Ładowanie…
Reference in New Issue