kopia lustrzana https://github.com/Jean-MarcHarvengt/MCUME
Instructions in NOPs + still timing issue
rodzic
fc4591d2e7
commit
5f43090cb7
|
@ -5,19 +5,21 @@
|
|||
#include "cpc.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <stdlib.h>
|
||||
|
||||
extern "C" {
|
||||
#include "emuapi.h"
|
||||
#include "platform_config.h"
|
||||
}
|
||||
#include "processor/Z80.h"
|
||||
#include "processor/Tables.h"
|
||||
#include "crtc.h"
|
||||
#include "ga.h"
|
||||
#include "roms/rom464.h"
|
||||
|
||||
#define WIDTH 320
|
||||
#define HEIGHT 200
|
||||
#define CYCLES_PER_FRAME 19968 //79872
|
||||
#define WIDTH 320
|
||||
#define HEIGHT 200
|
||||
#define CYCLES_PER_FRAME 79872 //79872 //19968
|
||||
#define NBLINES 312
|
||||
#define CYCLES_PER_SCANLINE CYCLES_PER_FRAME/NBLINES
|
||||
#define LOWER_ROM_END 0x4000
|
||||
|
@ -29,6 +31,7 @@ uint8_t RAM[0x10000]; // 64k
|
|||
unsigned char* bitstream = 0; // 16k video ram to be used by PIO.
|
||||
static Z80 CPU;
|
||||
bool interrupt_generated = false;
|
||||
int sline = 0;
|
||||
|
||||
// Implementations of system-specific emuapi Init, Step etc. functions.
|
||||
|
||||
|
@ -42,9 +45,9 @@ void cpc_Init(void)
|
|||
{
|
||||
emu_SetPaletteEntry(palette[i].R, palette[i].G, palette[i].B, i);
|
||||
}
|
||||
if (bitstream == 0) bitstream = (unsigned char *)emu_Malloc(WIDTH*HEIGHT);
|
||||
if (bitstream == 0) bitstream = (unsigned char *)emu_Malloc(WIDTH); //*HEIGHT
|
||||
|
||||
ResetZ80(&CPU, CYCLES_PER_FRAME);
|
||||
//ResetZ80(&CPU, CYCLES_PER_FRAME);
|
||||
memset(RAM, 0, sizeof(RAM));
|
||||
}
|
||||
|
||||
|
@ -54,6 +57,7 @@ void cpc_Init(void)
|
|||
void cpc_Start(char* filename)
|
||||
{
|
||||
CPU.PC.W = 0x0000;
|
||||
CPU.IFF = IFF_IM1;
|
||||
ga_config.lower_rom_enable = true;
|
||||
ga_config.upper_rom_enable = false;
|
||||
ga_config.interrupt_counter = 0;
|
||||
|
@ -65,37 +69,40 @@ void cpc_Start(char* filename)
|
|||
*/
|
||||
void cpc_Step(void)
|
||||
{
|
||||
int total_cycles = 0;
|
||||
int cycles_left = 0;
|
||||
int cycles_taken = 0;
|
||||
int cycles_total = 0;
|
||||
while(cycles_total < CYCLES_PER_FRAME)
|
||||
{
|
||||
cycles_taken = Cycles[RdZ80(CPU.PC.W)];
|
||||
ExecZ80(&CPU);
|
||||
cycles_total += cycles_taken;
|
||||
|
||||
for(int i = 0; i < NBLINES; i++)
|
||||
{ // TODO find a way to call crtc and ga step after each instruction, not after
|
||||
// executing everything in the scanline (not guaranteed to be 80000 cycles anyway).
|
||||
|
||||
cycles_left = ExecZ80(&CPU, 1);
|
||||
cycles_taken += 1;
|
||||
while(cycles_left < 0)
|
||||
{
|
||||
cycles_left -= ExecZ80(&CPU, 1);
|
||||
cycles_taken += 1;
|
||||
}
|
||||
|
||||
for(int j = 0; j < cycles_taken; j++)
|
||||
for(int i = 0; i < cycles_taken / 4; i++)
|
||||
{
|
||||
crtc_step();
|
||||
interrupt_generated = ga_step();
|
||||
|
||||
if(interrupt_generated)
|
||||
{
|
||||
//printf("Interrupting! Jumping to \n");
|
||||
printf("Interrupting!\n");
|
||||
|
||||
IntZ80(&CPU, INT_IRQ);
|
||||
ga_config.interrupt_counter &= 0x1F;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
emu_DrawLine8(bitstream, WIDTH, HEIGHT, i);
|
||||
cycles_taken = 0;
|
||||
emu_DrawLine8(bitstream, WIDTH, HEIGHT, sline);
|
||||
if(is_hsync_active())
|
||||
{
|
||||
//printf("HSYNC at scanline %d \n", sline);
|
||||
sline = (sline + 1) % NBLINES;
|
||||
}
|
||||
}
|
||||
// printf("HSYNC at scanline %d \n", sline);
|
||||
|
||||
|
||||
|
||||
//}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -32,7 +32,6 @@ uint16_t memory_start_addr = 0;
|
|||
|
||||
void crtc_step()
|
||||
{
|
||||
// printf("Horizontal count: %d \n", horizontal_count);
|
||||
horizontal_count++;
|
||||
|
||||
if(horizontal_count > registers[0])
|
||||
|
@ -40,7 +39,6 @@ void crtc_step()
|
|||
// horizontal counter is equal to the Horizontal Total Register.
|
||||
horizontal_count = 0;
|
||||
scanline_count++;
|
||||
// printf("Resetting horizontal counter!\n");
|
||||
}
|
||||
|
||||
if(scanline_count > registers[9])
|
||||
|
@ -50,7 +48,6 @@ void crtc_step()
|
|||
|
||||
scanline_count = 0;
|
||||
char_line_count++;
|
||||
//printf("char_line_count: %d \n", char_line_count);
|
||||
|
||||
}
|
||||
|
||||
|
@ -65,13 +62,6 @@ void crtc_step()
|
|||
memory_start_addr = ((uint16_t) registers[12] << 8) | registers[13];
|
||||
}
|
||||
|
||||
// if(is_within_display() && (memory_start_addr & 0b0011100000000000 == scanline_count))
|
||||
// {
|
||||
// memory_start_addr += 2;
|
||||
// }
|
||||
|
||||
// printf("Scanline count: %d \n", scanline_count);
|
||||
|
||||
}
|
||||
|
||||
uint16_t crtc_generate_addr()
|
||||
|
@ -98,17 +88,17 @@ bool is_within_display()
|
|||
bool is_hsync_active()
|
||||
{
|
||||
// HSYNC is active if the horizontal counter is in the
|
||||
// "horizontal_and_vertical_sync_widths"-defined width starting from the horizontal_total register.
|
||||
return horizontal_count >= registers[0]
|
||||
&& horizontal_count < registers[0] + (registers[3] & 0b1111);
|
||||
// "horizontal_and_vertical_sync_widths"-defined width starting from the horizontal_sync_position register.
|
||||
return horizontal_count >= registers[2] &&
|
||||
horizontal_count <= registers[2] + (registers[3] & 0b1111);
|
||||
}
|
||||
|
||||
bool is_vsync_active()
|
||||
{
|
||||
int8_t char_height = (int8_t) registers[9] + 1;
|
||||
int8_t char_lines_counted = (int8_t) char_line_count - registers[7];
|
||||
return char_height * char_line_count + (int8_t) scanline_count >= 0 &&
|
||||
char_height * char_line_count + (int8_t) scanline_count <= 16;
|
||||
return char_height * char_lines_counted + (int8_t) scanline_count >= 0 &&
|
||||
char_height * char_lines_counted + (int8_t) scanline_count <= 16*8;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -15,8 +15,7 @@
|
|||
|
||||
#define PALETTE_SIZE 32
|
||||
#define VID_FRAME_SKIP 0x0
|
||||
#define TFT_VBUFFER_YCROP 0
|
||||
#define TFT_VUBFFER_YCROP 0
|
||||
#define TFT_VBUFFER_YCROP 0
|
||||
|
||||
#define ACTION_NONE 0
|
||||
#define ACTION_MAXKBDVAL 225
|
||||
|
@ -66,6 +65,7 @@ extern unsigned int emu_FileSize(const char* filepath);
|
|||
extern unsigned int emu_LoadFile(const char* filepath, void* buf, int size);
|
||||
|
||||
extern void emu_SetPaletteEntry(unsigned char r, unsigned char g, unsigned char b, int index);
|
||||
extern void emu_DrawPixel(unsigned char * VBuf, int x, int y);
|
||||
extern void emu_DrawScreen(unsigned char* VBuf, int width, int height, int stride);
|
||||
extern void emu_DrawLine(unsigned char* VBuf, int width, int height, int line);
|
||||
extern void emu_DrawLine8(unsigned char* VBuf, int width, int height, int line);
|
||||
|
|
|
@ -51,15 +51,16 @@ struct RGB palette[32] = {
|
|||
bool update_interrupts()
|
||||
{
|
||||
bool interrupt_generated = false;
|
||||
|
||||
if(ga_config.hsync_active && !is_hsync_active())
|
||||
{
|
||||
// falling edge of CRTC hsync signal.
|
||||
ga_config.interrupt_counter++;
|
||||
ga_config.vsync_delay_count++;
|
||||
|
||||
|
||||
if(ga_config.interrupt_counter == 52)
|
||||
{
|
||||
//printf("Interrupt generated! \n");
|
||||
ga_config.interrupt_counter = 0;
|
||||
interrupt_generated = true;
|
||||
}
|
||||
|
@ -78,6 +79,7 @@ bool update_interrupts()
|
|||
{
|
||||
if(ga_config.interrupt_counter >= 32)
|
||||
{
|
||||
//printf("Interrupt generated! \n");
|
||||
interrupt_generated = true;
|
||||
}
|
||||
ga_config.interrupt_counter = 0;
|
||||
|
@ -94,30 +96,22 @@ 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)
|
||||
{
|
||||
// for(int j = 0; j < registers[3] & 0b1111; j++)
|
||||
// {
|
||||
// *bitstream = ga_rgb_to_vga(ga_config.pen_colours[19].R,
|
||||
// ga_config.pen_colours[19].G,
|
||||
// ga_config.pen_colours[19].B);
|
||||
// *bitstream++;
|
||||
// }
|
||||
return;
|
||||
}
|
||||
// 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;
|
||||
// }
|
||||
|
||||
// border
|
||||
if(ga_config.vsync_active || ga_config.hsync_active)
|
||||
{
|
||||
// for(int j = 0; j < 16; j++)
|
||||
// {
|
||||
// *bitstream = ga_rgb_to_vga(ga_config.pen_colours[0x10].R,
|
||||
// ga_config.pen_colours[0x10].G,
|
||||
// ga_config.pen_colours[0x10].B);
|
||||
// *bitstream++;
|
||||
// }
|
||||
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;
|
||||
// }
|
||||
|
||||
for(int i = 0; i < 2; i++)
|
||||
{
|
||||
|
@ -126,73 +120,79 @@ void address_to_pixels()
|
|||
uint8_t encodedByte = RAM[address];
|
||||
uint8_t pixel0, pixel1, pixel2, pixel3;
|
||||
uint8_t* pixels = (uint8_t*) calloc(4, 8*sizeof(uint8_t));
|
||||
|
||||
switch(ga_config.screen_mode)
|
||||
if(address >= 0xC000)
|
||||
{
|
||||
case 0:
|
||||
pixel0 = (encodedByte & 0x80) >> 7 |
|
||||
(encodedByte & 0x08) >> 2 |
|
||||
(encodedByte & 0x20) >> 3 |
|
||||
(encodedByte & 0x02) << 2;
|
||||
pixel1 = (encodedByte & 0x40) >> 6 |
|
||||
(encodedByte & 0x04) >> 1 |
|
||||
(encodedByte & 0x10) >> 2 |
|
||||
(encodedByte & 0x01) << 3;
|
||||
pixels[0] = pixel0;
|
||||
pixels[1] = pixel1;
|
||||
for(int pixelIdx = 0; pixelIdx < 2; pixelIdx++)
|
||||
{
|
||||
for(int color = 0; color < 4; color++)
|
||||
switch(ga_config.screen_mode)
|
||||
{
|
||||
case 0:
|
||||
pixel0 = (encodedByte & 0x80) >> 7 |
|
||||
(encodedByte & 0x08) >> 2 |
|
||||
(encodedByte & 0x20) >> 3 |
|
||||
(encodedByte & 0x02) << 2;
|
||||
pixel1 = (encodedByte & 0x40) >> 6 |
|
||||
(encodedByte & 0x04) >> 1 |
|
||||
(encodedByte & 0x10) >> 2 |
|
||||
(encodedByte & 0x01) << 3;
|
||||
pixels[0] = pixel0;
|
||||
pixels[1] = pixel1;
|
||||
for(int pixelIdx = 0; pixelIdx < 2; pixelIdx++)
|
||||
{
|
||||
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);
|
||||
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:
|
||||
pixel0 = (encodedByte & 0x80) >> 7 |
|
||||
(encodedByte & 0x08) >> 2;
|
||||
pixel1 = (encodedByte & 0x40) >> 6 |
|
||||
(encodedByte & 0x04) >> 1;
|
||||
pixel2 = (encodedByte & 0x02) |
|
||||
(encodedByte & 0x20) >> 5;
|
||||
pixel3 = (encodedByte & 0x10) >> 4 |
|
||||
(encodedByte & 0x01) << 1;
|
||||
pixels[0] = pixel0;
|
||||
pixels[1] = pixel1;
|
||||
pixels[2] = pixel2;
|
||||
pixels[3] = pixel3;
|
||||
break;
|
||||
case 1:
|
||||
pixel0 = (encodedByte & 0x80) >> 7 |
|
||||
(encodedByte & 0x08) >> 2;
|
||||
pixel1 = (encodedByte & 0x40) >> 6 |
|
||||
(encodedByte & 0x04) >> 1;
|
||||
pixel2 = (encodedByte & 0x02) |
|
||||
(encodedByte & 0x20) >> 5;
|
||||
pixel3 = (encodedByte & 0x10) >> 4 |
|
||||
(encodedByte & 0x01) << 1;
|
||||
pixels[0] = pixel0;
|
||||
pixels[1] = pixel1;
|
||||
pixels[2] = pixel2;
|
||||
pixels[3] = pixel3;
|
||||
|
||||
for(int pixelIdx = 0; pixelIdx < 4; pixelIdx++)
|
||||
{
|
||||
for(int color = 0; color < 2; color++)
|
||||
for(int pixelIdx = 0; pixelIdx < 4; pixelIdx++)
|
||||
{
|
||||
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);
|
||||
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:
|
||||
uint8_t pixel;
|
||||
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);
|
||||
}
|
||||
break;
|
||||
break;
|
||||
case 2:
|
||||
uint8_t pixel;
|
||||
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);
|
||||
}
|
||||
break;
|
||||
}
|
||||
free(pixels);
|
||||
}
|
||||
free(pixels);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
bool ga_step()
|
||||
{
|
||||
bool interrupt_generated = update_interrupts();
|
||||
address_to_pixels();
|
||||
//if(is_within_display())
|
||||
//{
|
||||
address_to_pixels();
|
||||
//}
|
||||
|
||||
ga_config.hsync_active = is_hsync_active();
|
||||
ga_config.vsync_active = is_vsync_active();
|
||||
|
@ -247,7 +247,6 @@ void rom_and_screen_mgmt(uint8_t value)
|
|||
// mode 3, unused.
|
||||
break;
|
||||
}
|
||||
printf("Updated screen mode to mode %d", ga_config.screen_mode);
|
||||
}
|
||||
|
||||
// ROM enable flags.
|
||||
|
|
|
@ -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 4 // Mode 0 has 16 pens, mode 1 has 4 pens and mode 2 has 2 pens.
|
||||
#define PEN_NUMBER 16 // 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 {
|
||||
|
|
|
@ -71,7 +71,7 @@ int main(void) {
|
|||
}
|
||||
else {
|
||||
emu_Step();
|
||||
//tft.waitSync();
|
||||
tft.waitSync();
|
||||
}
|
||||
//int c = getchar_timeout_us(0);
|
||||
//switch (c) {
|
||||
|
@ -107,10 +107,10 @@ void emu_DrawVsync(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
// void emu_DrawPixel(unsigned char * VBuf, int x, int y)
|
||||
// {
|
||||
// tft.drawPixel(x, y, (uint8_t) VBuf++);
|
||||
// }
|
||||
void emu_DrawPixel(unsigned char * VBuf, int x, int y)
|
||||
{
|
||||
tft.drawPixel(x, y, (uint8_t) *VBuf++);
|
||||
}
|
||||
|
||||
|
||||
void emu_DrawLine(unsigned char * VBuf, int width, int height, int line)
|
||||
|
|
|
@ -13,44 +13,44 @@
|
|||
/** changes to this file. **/
|
||||
/*************************************************************/
|
||||
|
||||
static const byte Cycles[256] =
|
||||
{
|
||||
4,10, 7, 6, 4, 4, 7, 4, 4,11, 7, 6, 4, 4, 7, 4,
|
||||
8,10, 7, 6, 4, 4, 7, 4,12,11, 7, 6, 4, 4, 7, 4,
|
||||
7,10,16, 6, 4, 4, 7, 4, 7,11,16, 6, 4, 4, 7, 4,
|
||||
7,10,13, 6,11,11,10, 4, 7,11,13, 6, 4, 4, 7, 4,
|
||||
4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4,
|
||||
4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4,
|
||||
4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4,
|
||||
7, 7, 7, 7, 7, 7, 4, 7, 4, 4, 4, 4, 4, 4, 7, 4,
|
||||
4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4,
|
||||
4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4,
|
||||
4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4,
|
||||
4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4,
|
||||
5,10,10,10,10,11, 7,11, 5,10,10, 0,10,17, 7,11,
|
||||
5,10,10,11,10,11, 7,11, 5, 4,10,11,10, 0, 7,11,
|
||||
5,10,10,19,10,11, 7,11, 5, 4,10, 4,10, 0, 7,11,
|
||||
5,10,10, 4,10,11, 7,11, 5, 6,10, 4,10, 0, 7,11
|
||||
};
|
||||
static const byte Cycles[256] =
|
||||
{
|
||||
4,12, 8, 8, 4, 4, 8, 4, 4,12, 8, 8, 4, 4, 8, 4,
|
||||
8,12, 8, 8, 4, 4, 8, 4,12,12, 8, 8, 4, 4, 8, 4,
|
||||
8,12,16, 8, 4, 4, 8, 4, 8,12,16, 8, 4, 4, 8, 4,
|
||||
8,12,16, 8,12,12,12, 4, 8,12,16, 8, 4, 4, 8, 4,
|
||||
4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4,
|
||||
4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4,
|
||||
4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4,
|
||||
8, 8, 8, 8, 8, 8, 4, 8, 4, 4, 4, 4, 4, 4, 8, 4,
|
||||
4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4,
|
||||
4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4,
|
||||
4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4,
|
||||
4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4,
|
||||
8,12,12,12,12,12, 8,12, 8,12,12, 0,12,20, 8,12,
|
||||
8,12,12,12,12,12, 8,12, 8, 4,12,12,12, 0, 8,12,
|
||||
8,12,12,20,12,12, 8,12, 8, 4,12, 4,12, 0, 8,12,
|
||||
8,12,12, 4,12,12, 8,12, 8, 8,12, 4,12, 0, 8,12
|
||||
};
|
||||
|
||||
static const byte CyclesCB[256] =
|
||||
{
|
||||
8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
|
||||
8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
|
||||
8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
|
||||
8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
|
||||
8, 8, 8, 8, 8, 8,16, 8, 8, 8, 8, 8, 8, 8,16, 8,
|
||||
8, 8, 8, 8, 8, 8,16, 8, 8, 8, 8, 8, 8, 8,16, 8,
|
||||
8, 8, 8, 8, 8, 8,16, 8, 8, 8, 8, 8, 8, 8,16, 8,
|
||||
8, 8, 8, 8, 8, 8,16, 8, 8, 8, 8, 8, 8, 8,16, 8,
|
||||
8, 8, 8, 8, 8, 8,12, 8, 8, 8, 8, 8, 8, 8,12, 8,
|
||||
8, 8, 8, 8, 8, 8,12, 8, 8, 8, 8, 8, 8, 8,12, 8,
|
||||
8, 8, 8, 8, 8, 8,12, 8, 8, 8, 8, 8, 8, 8,12, 8,
|
||||
8, 8, 8, 8, 8, 8,12, 8, 8, 8, 8, 8, 8, 8,12, 8,
|
||||
8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
|
||||
8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
|
||||
8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
|
||||
8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
|
||||
8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
|
||||
8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
|
||||
8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
|
||||
8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8
|
||||
8, 8, 8, 8, 8, 8,16, 8, 8, 8, 8, 8, 8, 8,16, 8,
|
||||
8, 8, 8, 8, 8, 8,16, 8, 8, 8, 8, 8, 8, 8,16, 8,
|
||||
8, 8, 8, 8, 8, 8,16, 8, 8, 8, 8, 8, 8, 8,16, 8,
|
||||
8, 8, 8, 8, 8, 8,16, 8, 8, 8, 8, 8, 8, 8,16, 8,
|
||||
8, 8, 8, 8, 8, 8,16, 8, 8, 8, 8, 8, 8, 8,16, 8,
|
||||
8, 8, 8, 8, 8, 8,16, 8, 8, 8, 8, 8, 8, 8,16, 8,
|
||||
8, 8, 8, 8, 8, 8,16, 8, 8, 8, 8, 8, 8, 8,16, 8,
|
||||
8, 8, 8, 8, 8, 8,16, 8, 8, 8, 8, 8, 8, 8,16, 8
|
||||
};
|
||||
|
||||
static const byte CyclesED[256] =
|
||||
|
@ -59,10 +59,10 @@ static const byte CyclesED[256] =
|
|||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
12,12,15,20, 8,14, 8, 9,12,12,15,20, 0,14, 0, 9,
|
||||
12,12,15,20, 0, 0, 8, 9,12,12,15,20, 0, 0, 8, 9,
|
||||
12,12,15,20, 0, 0, 0,18,12,12,15,20, 0, 0, 0,18,
|
||||
12, 0,15,20, 0, 0, 0, 0,12,12,15,20, 0, 0, 0, 0,
|
||||
12,12,16,20, 8,16, 8, 12,12,12,16,20, 0,16, 0, 12,
|
||||
12,12,16,20, 0, 0, 8, 12,12,12,16,20, 0, 0, 8, 12,
|
||||
12,12,16,20, 0, 0, 0,20,12,12,16,20, 0, 0, 0,20,
|
||||
12, 0,16,20, 0, 0, 0, 0,12,12,16,20, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
16,16,16,16, 0, 0, 0, 0,16,16,16,16, 0, 0, 0, 0,
|
||||
|
@ -75,42 +75,42 @@ static const byte CyclesED[256] =
|
|||
|
||||
static const byte CyclesXX[256] =
|
||||
{
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0,15, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0,15, 0, 0, 0, 0, 0, 0,
|
||||
0,14,20,10, 9, 9, 9, 0, 0,15,20,10, 9, 9, 9, 0,
|
||||
0, 0, 0, 0,23,23,19, 0, 0,15, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 9, 9,19, 0, 0, 0, 0, 0, 9, 9,19, 0,
|
||||
0, 0, 0, 0, 9, 9,19, 0, 0, 0, 0, 0, 9, 9,19, 0,
|
||||
9, 9, 9, 9, 9, 9,19, 9, 9, 9, 9, 9, 9, 9,19, 9,
|
||||
19,19,19,19,19,19,19,19, 0, 0, 0, 0, 9, 9,19, 0,
|
||||
0, 0, 0, 0, 9, 9,19, 0, 0, 0, 0, 0, 9, 9,19, 0,
|
||||
0, 0, 0, 0, 9, 9,19, 0, 0, 0, 0, 0, 9, 9,19, 0,
|
||||
0, 0, 0, 0, 9, 9,19, 0, 0, 0, 0, 0, 9, 9,19, 0,
|
||||
0, 0, 0, 0, 9, 9,19, 0, 0, 0, 0, 0, 9, 9,19, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0,16, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0,16, 0, 0, 0, 0, 0, 0,
|
||||
0,16,20,12, 12, 12, 12, 0, 0,16,20,12, 12, 12, 12, 0,
|
||||
0, 0, 0, 0,24,24,20, 0, 0,16, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 12, 12,20, 0, 0, 0, 0, 0, 12, 12,20, 0,
|
||||
0, 0, 0, 0, 12, 12,20, 0, 0, 0, 0, 0, 12, 12,20, 0,
|
||||
12, 12, 12, 12, 12, 12,20, 12, 12, 12, 12, 12, 12, 12,20, 12,
|
||||
20,20,20,20,20,20,20,20, 0, 0, 0, 0, 12, 12,20, 0,
|
||||
0, 0, 0, 0, 12, 12,20, 0, 0, 0, 0, 0, 12, 12,20, 0,
|
||||
0, 0, 0, 0, 12, 12,20, 0, 0, 0, 0, 0, 12, 12,20, 0,
|
||||
0, 0, 0, 0, 12, 12,20, 0, 0, 0, 0, 0, 12, 12,20, 0,
|
||||
0, 0, 0, 0, 12, 12,20, 0, 0, 0, 0, 0, 12, 12,20, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0,14, 0,23, 0,15, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0,10, 0, 0, 0, 0, 0, 0
|
||||
0,16, 0,24, 0,16, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0,12, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
static const byte CyclesXXCB[256] =
|
||||
{
|
||||
0, 0, 0, 0, 0, 0,23, 0, 0, 0, 0, 0, 0, 0,23, 0,
|
||||
0, 0, 0, 0, 0, 0,23, 0, 0, 0, 0, 0, 0, 0,23, 0,
|
||||
0, 0, 0, 0, 0, 0,23, 0, 0, 0, 0, 0, 0, 0,23, 0,
|
||||
0, 0, 0, 0, 0, 0,23, 0, 0, 0, 0, 0, 0, 0,23, 0,
|
||||
0, 0, 0, 0, 0, 0,24, 0, 0, 0, 0, 0, 0, 0,24, 0,
|
||||
0, 0, 0, 0, 0, 0,24, 0, 0, 0, 0, 0, 0, 0,24, 0,
|
||||
0, 0, 0, 0, 0, 0,24, 0, 0, 0, 0, 0, 0, 0,24, 0,
|
||||
0, 0, 0, 0, 0, 0,24, 0, 0, 0, 0, 0, 0, 0,24, 0,
|
||||
20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
|
||||
20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
|
||||
20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
|
||||
20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
|
||||
0, 0, 0, 0, 0, 0,23, 0, 0, 0, 0, 0, 0, 0,23, 0,
|
||||
0, 0, 0, 0, 0, 0,23, 0, 0, 0, 0, 0, 0, 0,23, 0,
|
||||
0, 0, 0, 0, 0, 0,23, 0, 0, 0, 0, 0, 0, 0,23, 0,
|
||||
0, 0, 0, 0, 0, 0,23, 0, 0, 0, 0, 0, 0, 0,23, 0,
|
||||
0, 0, 0, 0, 0, 0,23, 0, 0, 0, 0, 0, 0, 0,23, 0,
|
||||
0, 0, 0, 0, 0, 0,23, 0, 0, 0, 0, 0, 0, 0,23, 0,
|
||||
0, 0, 0, 0, 0, 0,23, 0, 0, 0, 0, 0, 0, 0,23, 0,
|
||||
0, 0, 0, 0, 0, 0,23, 0, 0, 0, 0, 0, 0, 0,23, 0
|
||||
0, 0, 0, 0, 0, 0,24, 0, 0, 0, 0, 0, 0, 0,24, 0,
|
||||
0, 0, 0, 0, 0, 0,24, 0, 0, 0, 0, 0, 0, 0,24, 0,
|
||||
0, 0, 0, 0, 0, 0,24, 0, 0, 0, 0, 0, 0, 0,24, 0,
|
||||
0, 0, 0, 0, 0, 0,24, 0, 0, 0, 0, 0, 0, 0,24, 0,
|
||||
0, 0, 0, 0, 0, 0,24, 0, 0, 0, 0, 0, 0, 0,24, 0,
|
||||
0, 0, 0, 0, 0, 0,24, 0, 0, 0, 0, 0, 0, 0,24, 0,
|
||||
0, 0, 0, 0, 0, 0,24, 0, 0, 0, 0, 0, 0, 0,24, 0,
|
||||
0, 0, 0, 0, 0, 0,24, 0, 0, 0, 0, 0, 0, 0,24, 0
|
||||
};
|
||||
|
||||
static const byte ZSTable[256] =
|
||||
|
|
|
@ -505,15 +505,15 @@ void ResetZ80(Z80 *R, register int Cycles)
|
|||
/** negative, and current register values in R. **/
|
||||
/*************************************************************/
|
||||
#ifdef EXECZ80
|
||||
int ExecZ80(register Z80 *R,register int RunCycles)
|
||||
int ExecZ80(register Z80 *R) // , register int RunCycles
|
||||
{
|
||||
register byte I;
|
||||
register pair J;
|
||||
|
||||
for(R->ICount=RunCycles;;)
|
||||
{
|
||||
while(R->ICount>0)
|
||||
{
|
||||
// for(R->ICount=RunCycles;;)
|
||||
// {
|
||||
// while(R->ICount>0)
|
||||
// {
|
||||
#ifdef DEBUG
|
||||
/* Turn tracing on when reached trap address */
|
||||
if(R->PC.W==R->Trap) R->Trace=1;
|
||||
|
@ -526,68 +526,6 @@ int ExecZ80(register Z80 *R,register int RunCycles)
|
|||
I=OpZ80(R->PC.W++);
|
||||
/* Count cycles */
|
||||
R->ICount-=Cycles[I];
|
||||
|
||||
for (int l=0; l< Cycles[I] ;l++) {
|
||||
asm volatile("nop");
|
||||
asm volatile("nop");
|
||||
asm volatile("nop");
|
||||
asm volatile("nop");
|
||||
asm volatile("nop");
|
||||
asm volatile("nop");
|
||||
asm volatile("nop");
|
||||
asm volatile("nop");
|
||||
asm volatile("nop");
|
||||
asm volatile("nop");
|
||||
asm volatile("nop");
|
||||
asm volatile("nop");
|
||||
asm volatile("nop");
|
||||
asm volatile("nop");
|
||||
asm volatile("nop");
|
||||
asm volatile("nop");
|
||||
asm volatile("nop");
|
||||
asm volatile("nop");
|
||||
asm volatile("nop");
|
||||
asm volatile("nop");
|
||||
asm volatile("nop");
|
||||
asm volatile("nop");
|
||||
asm volatile("nop");
|
||||
asm volatile("nop");
|
||||
asm volatile("nop");
|
||||
asm volatile("nop");
|
||||
asm volatile("nop");
|
||||
asm volatile("nop");
|
||||
asm volatile("nop");
|
||||
asm volatile("nop");
|
||||
asm volatile("nop");
|
||||
asm volatile("nop");
|
||||
asm volatile("nop");
|
||||
asm volatile("nop");
|
||||
asm volatile("nop");
|
||||
asm volatile("nop");
|
||||
asm volatile("nop");
|
||||
asm volatile("nop");
|
||||
asm volatile("nop");
|
||||
asm volatile("nop");
|
||||
|
||||
#ifndef USE_VGA
|
||||
asm volatile("nop");
|
||||
asm volatile("nop");
|
||||
asm volatile("nop");
|
||||
asm volatile("nop");
|
||||
asm volatile("nop");
|
||||
|
||||
asm volatile("nop");
|
||||
asm volatile("nop");
|
||||
asm volatile("nop");
|
||||
asm volatile("nop");
|
||||
asm volatile("nop");
|
||||
asm volatile("nop");
|
||||
asm volatile("nop");
|
||||
asm volatile("nop");
|
||||
asm volatile("nop");
|
||||
asm volatile("nop");
|
||||
#endif
|
||||
}
|
||||
/* Interpret opcode */
|
||||
switch(I)
|
||||
{
|
||||
|
@ -597,7 +535,6 @@ 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);
|
||||
|
@ -609,8 +546,9 @@ int ExecZ80(register Z80 *R,register int RunCycles)
|
|||
R->ICount+=R->IBackup-1;
|
||||
/* Interrupt CPU if needed */
|
||||
if((R->IRequest!=INT_NONE)&&(R->IRequest!=INT_QUIT)) IntZ80(R,R->IRequest);
|
||||
}
|
||||
}
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
#endif /* EXECZ80 */
|
||||
|
||||
|
@ -673,7 +611,7 @@ void IntZ80(Z80 *R,word Vector)
|
|||
case INT_RST20: R->PC.W=0x0020;JumpZ80(0x0020);break;
|
||||
case INT_RST28: R->PC.W=0x0028;JumpZ80(0x0028);break;
|
||||
case INT_RST30: R->PC.W=0x0030;JumpZ80(0x0030);break;
|
||||
case INT_RST38: R->PC.W=0x0038;JumpZ80(0x0038);break;
|
||||
case INT_RST38: R->PC.W=0x0038;JumpZ80(0x0038);break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -116,7 +116,7 @@ void ResetZ80(register Z80 *R, register int Cycles);
|
|||
/** negative, and current register values in R. **/
|
||||
/*************************************************************/
|
||||
#ifdef EXECZ80
|
||||
int ExecZ80(register Z80 *R,register int RunCycles);
|
||||
int ExecZ80(register Z80 *R); // ,register int RunCycles
|
||||
#endif
|
||||
|
||||
/** IntZ80() *************************************************/
|
||||
|
|
Ładowanie…
Reference in New Issue