kopia lustrzana https://github.com/Jean-MarcHarvengt/MCUME
fix weird white lines
rodzic
972fb619bf
commit
88ef857bca
|
@ -34,6 +34,7 @@ static Z80 CPU;
|
|||
bool interrupt_generated = false;
|
||||
int sline = 0;
|
||||
int cycles_left = 0;
|
||||
bool test_flag = false;
|
||||
|
||||
// Implementations of system-specific emuapi Init, Step etc. functions.
|
||||
|
||||
|
@ -45,7 +46,7 @@ void cpc_Init(void)
|
|||
|
||||
for(int i = 0; i < PALETTE_SIZE; i++)
|
||||
{
|
||||
emu_SetPaletteEntry(palette[i].R, palette[i].G, palette[i].B, i);
|
||||
emu_SetPaletteEntry(firmware_palette[i].R, firmware_palette[i].G, firmware_palette[i].B, i);
|
||||
}
|
||||
if (bitstream == 0) bitstream = (unsigned char *)emu_Malloc(WIDTH*HEIGHT); //*HEIGHT
|
||||
bitstream_init_pos = bitstream;
|
||||
|
@ -72,26 +73,41 @@ void cpc_Start(char* filename)
|
|||
*/
|
||||
void cpc_Step(void)
|
||||
{
|
||||
cycles_left = ExecZ80(&CPU, 24); // execute for the duration of 6 NOPs (maximum instruction length)
|
||||
//printf("Executing %d times.\n", cycles_left/4);
|
||||
for(int k = 0; k < (24 - cycles_left) / 4; k++)
|
||||
for(;!is_hsync_active();)
|
||||
{
|
||||
cycles_left = ExecZ80(&CPU, 24); // execute for the duration of 6 NOPs (maximum instruction length)
|
||||
for(int k = 0; k < (24 - cycles_left) / 4; k++)
|
||||
{
|
||||
crtc_step();
|
||||
interrupt_generated = ga_step();
|
||||
if(interrupt_generated)
|
||||
{
|
||||
// printf("Interrupting!\n");
|
||||
IntZ80(&CPU, INT_RST38);
|
||||
ga_config.interrupt_counter &= 0x1f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
emu_DrawLine8(bitstream, WIDTH, HEIGHT, sline);
|
||||
sline = (sline + 1) % NBLINES;
|
||||
|
||||
if(is_vsync_active())
|
||||
{
|
||||
emu_DrawVsync();
|
||||
}
|
||||
|
||||
while(is_hsync_active())
|
||||
{
|
||||
|
||||
crtc_step();
|
||||
interrupt_generated = ga_step();
|
||||
if(interrupt_generated)
|
||||
{
|
||||
// printf("Interrupting!\n");
|
||||
IntZ80(&CPU, INT_RST38);
|
||||
ga_config.interrupt_counter &= 0x1f;
|
||||
}
|
||||
if(is_hsync_active())
|
||||
{
|
||||
sline = (sline + 1) % NBLINES;
|
||||
}
|
||||
emu_DrawLine8(bitstream, WIDTH, HEIGHT, sline);
|
||||
}
|
||||
|
||||
ga_step();
|
||||
}
|
||||
|
||||
while(is_vsync_active())
|
||||
{
|
||||
crtc_step();
|
||||
ga_step();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -102,6 +118,10 @@ void cpc_Input(int bClick)
|
|||
|
||||
}
|
||||
|
||||
void draw_vsync()
|
||||
{
|
||||
emu_DrawVsync();
|
||||
}
|
||||
|
||||
// System-specific implementations of the Z80 instructions required by the portable Z80 emulator.
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ extern uint8_t RAM[0x10000];
|
|||
extern unsigned char* bitstream;
|
||||
extern struct GAConfig ga_config;
|
||||
|
||||
extern void draw_vsync();
|
||||
extern void cpc_Init(void);
|
||||
extern void cpc_Step(void);
|
||||
extern void cpc_Start(char* filename);
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
#define emu_Step(x) {cpc_Step();}
|
||||
#define emu_Input(x) {cpc_Input(x);}
|
||||
|
||||
#define PALETTE_SIZE 32
|
||||
#define PALETTE_SIZE 27
|
||||
#define VID_FRAME_SKIP 0x0
|
||||
#define TFT_VBUFFER_YCROP 0
|
||||
|
||||
|
|
|
@ -13,39 +13,69 @@ struct GAConfig ga_config;
|
|||
* Some of the colours are duplicates, because select_pen_colour() uses the least significant
|
||||
* 5 bits to index into this array, so the duplicates prevent out-of-bounds read.
|
||||
*/
|
||||
struct RGB palette[32] = {
|
||||
{128, 128, 128}, // White
|
||||
{128, 128, 128}, // White
|
||||
{0, 255, 128}, // Sea Green
|
||||
{255, 255, 128}, // Pastel Yellow
|
||||
{0, 0, 128}, // Blue
|
||||
{255, 0, 128}, // Purple
|
||||
{0, 128, 128}, // Cyan
|
||||
{255, 128, 128}, // Pink
|
||||
{255, 0, 128}, // Purple
|
||||
{255, 255, 128}, // Pastel Yellow
|
||||
{255, 255, 0}, // Bright Yellow
|
||||
{255, 255, 255}, // Bright White
|
||||
{255, 0, 0}, // Bright Red
|
||||
{255, 0, 255}, // Bright Magenta
|
||||
{255, 128, 0}, // Orange
|
||||
{255, 128, 255}, // Pastel Magenta
|
||||
{0, 0, 128}, // Blue
|
||||
{0, 255, 128}, // Sea Green
|
||||
{0, 255, 0}, // Bright Green
|
||||
{0, 255, 255}, // Bright Cyan
|
||||
{0, 0, 0}, // Black
|
||||
{0, 0, 255}, // Bright Blue
|
||||
{0, 128, 0}, // Green
|
||||
{0, 128, 255}, // Sky Blue
|
||||
{128, 0, 128}, // Magenta
|
||||
{128, 255, 128}, // Pastel Green
|
||||
{128, 255, 0}, // Lime
|
||||
{128, 255, 255}, // Pastel Cyan
|
||||
{128, 0, 0}, // Red
|
||||
{128, 0, 255}, // Mauve
|
||||
{128, 128, 0}, // Yellow
|
||||
{128, 128, 255} // Pastel Blue
|
||||
uint8_t hardware_colours[32] = {
|
||||
13,
|
||||
13,
|
||||
19,
|
||||
25,
|
||||
1,
|
||||
7,
|
||||
10,
|
||||
16,
|
||||
7,
|
||||
25,
|
||||
24,
|
||||
26,
|
||||
6,
|
||||
8,
|
||||
15,
|
||||
17,
|
||||
1,
|
||||
19,
|
||||
18,
|
||||
20,
|
||||
0,
|
||||
2,
|
||||
9,
|
||||
11,
|
||||
4,
|
||||
22,
|
||||
21,
|
||||
23,
|
||||
3,
|
||||
5,
|
||||
12,
|
||||
14
|
||||
};
|
||||
|
||||
struct RGB firmware_palette[27] = {
|
||||
{0, 0, 0},
|
||||
{0, 0, 128},
|
||||
{0, 0, 255},
|
||||
{128, 0, 0},
|
||||
{128, 0, 128},
|
||||
{128, 0, 255},
|
||||
{255, 0, 0},
|
||||
{255, 0, 128},
|
||||
{255, 0, 255},
|
||||
{0, 128, 0},
|
||||
{0, 128, 128},
|
||||
{0, 128, 255},
|
||||
{128, 128, 0},
|
||||
{128, 128, 128},
|
||||
{128, 128, 255},
|
||||
{255, 128, 0},
|
||||
{255, 128, 128},
|
||||
{255, 128, 255},
|
||||
{0, 255, 0},
|
||||
{0, 255, 128},
|
||||
{0, 255, 255},
|
||||
{128, 255, 0},
|
||||
{128, 255, 128},
|
||||
{128, 255, 255},
|
||||
{255, 255, 0},
|
||||
{255, 255, 128},
|
||||
{255, 255, 255}
|
||||
};
|
||||
|
||||
bool update_interrupts()
|
||||
|
@ -96,22 +126,16 @@ char ga_rgb_to_vga(uint8_t r, uint8_t g, uint8_t b)
|
|||
void address_to_pixels()
|
||||
{
|
||||
// When HSYNC is active Gate-Array outputs the palette colour black
|
||||
// if(ga_config.hsync_active)
|
||||
// {
|
||||
// *(bitstream) = ga_rgb_to_vga(ga_config.pen_colours[19].R,
|
||||
// ga_config.pen_colours[19].G,
|
||||
// ga_config.pen_colours[19].B);
|
||||
// return;
|
||||
// }
|
||||
if(ga_config.hsync_active)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// // border
|
||||
// if(ga_config.vsync_active || ga_config.hsync_active)
|
||||
// {
|
||||
// *(bitstream) = ga_rgb_to_vga(ga_config.pen_colours[0x10].R,
|
||||
// ga_config.pen_colours[0x10].G,
|
||||
// ga_config.pen_colours[0x10].B);
|
||||
// return;
|
||||
// }
|
||||
// border
|
||||
if(ga_config.vsync_active || ga_config.hsync_active)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for(int i = 0; i < 2; i++)
|
||||
{
|
||||
|
@ -135,14 +159,18 @@ void address_to_pixels()
|
|||
(encodedByte & 0x01) << 3;
|
||||
pixels[0] = pixel0;
|
||||
pixels[1] = pixel1;
|
||||
|
||||
for(int pixelIdx = 0; pixelIdx < 2; pixelIdx++)
|
||||
{
|
||||
for(int color = 0; color < 4; color++)
|
||||
{
|
||||
bitstream[address + color - 0xC000] = ga_rgb_to_vga(ga_config.pen_colours[pixels[pixelIdx]].R,
|
||||
ga_config.pen_colours[pixels[pixelIdx]].G,
|
||||
ga_config.pen_colours[pixels[pixelIdx]].B);
|
||||
}
|
||||
bitstream[address + pixelIdx - 0xC000] = ga_rgb_to_vga(firmware_palette[hardware_colours[ga_config.pen_colours[pixels[pixelIdx]]]].R,
|
||||
firmware_palette[hardware_colours[ga_config.pen_colours[pixels[pixelIdx]]]].G,
|
||||
firmware_palette[hardware_colours[ga_config.pen_colours[pixels[pixelIdx]]]].B);
|
||||
// for(int color = 0; color < 4; color++)
|
||||
// {
|
||||
// bitstream[address + color - 0xC000] = ga_rgb_to_vga(ga_config.pen_colours[pixels[pixelIdx]].R,
|
||||
// ga_config.pen_colours[pixels[pixelIdx]].G,
|
||||
// ga_config.pen_colours[pixels[pixelIdx]].B);
|
||||
// }
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
|
@ -161,12 +189,15 @@ void address_to_pixels()
|
|||
|
||||
for(int pixelIdx = 0; pixelIdx < 4; pixelIdx++)
|
||||
{
|
||||
for(int color = 0; color < 2; color++)
|
||||
{
|
||||
bitstream[address + color - 0xC000] = ga_rgb_to_vga(ga_config.pen_colours[pixels[pixelIdx]].R,
|
||||
ga_config.pen_colours[pixels[pixelIdx]].G,
|
||||
ga_config.pen_colours[pixels[pixelIdx]].B);
|
||||
}
|
||||
bitstream[address + pixelIdx - 0xC000] = ga_rgb_to_vga(firmware_palette[hardware_colours[ga_config.pen_colours[pixels[pixelIdx]]]].R,
|
||||
firmware_palette[hardware_colours[ga_config.pen_colours[pixels[pixelIdx]]]].G,
|
||||
firmware_palette[hardware_colours[ga_config.pen_colours[pixels[pixelIdx]]]].B);
|
||||
// for(int color = 0; color < 2; color++)
|
||||
// {
|
||||
// bitstream[address + color - 0xC000] = ga_rgb_to_vga(ga_config.pen_colours[pixels[pixelIdx]].R,
|
||||
// ga_config.pen_colours[pixels[pixelIdx]].G,
|
||||
// ga_config.pen_colours[pixels[pixelIdx]].B);
|
||||
// }
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
|
@ -174,9 +205,9 @@ void address_to_pixels()
|
|||
for (int color = 0; color < 8; color++)
|
||||
{
|
||||
pixel = (encodedByte >> 7 - color) & 1;
|
||||
bitstream[address + color - 0xC000] = ga_rgb_to_vga(ga_config.pen_colours[pixel].R,
|
||||
ga_config.pen_colours[pixel].G,
|
||||
ga_config.pen_colours[pixel].B);
|
||||
bitstream[address + color - 0xC000] = ga_rgb_to_vga(firmware_palette[hardware_colours[ga_config.pen_colours[pixel]]].R,
|
||||
firmware_palette[hardware_colours[ga_config.pen_colours[pixel]]].G,
|
||||
firmware_palette[hardware_colours[ga_config.pen_colours[pixel]]].B);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -191,7 +222,7 @@ bool ga_step()
|
|||
bool interrupt_generated = update_interrupts();
|
||||
//if(is_within_display())
|
||||
//{
|
||||
address_to_pixels();
|
||||
address_to_pixels();
|
||||
//}
|
||||
|
||||
ga_config.hsync_active = is_hsync_active();
|
||||
|
@ -219,7 +250,7 @@ void select_pen_colour(uint8_t value)
|
|||
{
|
||||
// Bits 0-4 of "value" specify the hardware colour number from the hardware colour palette.
|
||||
// (i.e. which index into the Palette array of structs.)
|
||||
ga_config.pen_colours[ga_config.pen_selected] = palette[value & 31];
|
||||
ga_config.pen_colours[ga_config.pen_selected] = value & 31;
|
||||
}
|
||||
|
||||
void rom_and_screen_mgmt(uint8_t value)
|
||||
|
|
|
@ -12,7 +12,7 @@ void select_pen(uint8_t value);
|
|||
void select_pen_colour(uint8_t value);
|
||||
void rom_and_screen_mgmt(uint8_t value);
|
||||
|
||||
#define PEN_NUMBER 16 // Mode 0 has 16 pens, mode 1 has 4 pens and mode 2 has 2 pens.
|
||||
#define PEN_NUMBER 17 // Mode 0 has 16 pens, mode 1 has 4 pens and mode 2 has 2 pens.
|
||||
#define VGA_RGB(r,g,b) ( (((r>>5)&0x07)<<5) | (((g>>5)&0x07)<<2) | (((b>>6)&0x3)<<0) )
|
||||
|
||||
struct RGB {
|
||||
|
@ -21,7 +21,7 @@ struct RGB {
|
|||
|
||||
struct GAConfig {
|
||||
uint8_t pen_selected = 0;
|
||||
RGB pen_colours[PEN_NUMBER];
|
||||
uint8_t pen_colours[PEN_NUMBER];
|
||||
uint8_t screen_mode = 1; // 0 -> 160x200 16c; 1 -> 320x200 4c; 2 -> 640x200 2c; 3 (undocumented) -> 160x200 4c.
|
||||
bool upper_rom_enable = true;
|
||||
bool lower_rom_enable = true;
|
||||
|
@ -32,6 +32,7 @@ struct GAConfig {
|
|||
uint8_t ram_banking = 0; // unused in CPC 464
|
||||
};
|
||||
|
||||
extern struct RGB palette[32];
|
||||
extern struct RGB firmware_palette[27];
|
||||
extern uint8_t hardware_colours[32];
|
||||
|
||||
#endif
|
||||
|
|
|
@ -71,7 +71,6 @@ int main(void) {
|
|||
}
|
||||
else {
|
||||
emu_Step();
|
||||
// tft.waitSync();
|
||||
}
|
||||
//int c = getchar_timeout_us(0);
|
||||
//switch (c) {
|
||||
|
@ -100,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) {};
|
||||
|
|
|
@ -535,7 +535,7 @@ int ExecZ80(register Z80 *R, register int RunCycles) //
|
|||
case PFX_FD: CodesFD(R);break;
|
||||
case PFX_DD: CodesDD(R);break;
|
||||
}
|
||||
|
||||
|
||||
/* Unless we have come here after EI, exit */
|
||||
if(!(R->IFF&IFF_EI)) return(R->ICount);
|
||||
else
|
||||
|
|
Ładowanie…
Reference in New Issue