Establish display processing
This commit is contained in:
parent
c91eb0785f
commit
448658430c
|
@ -1692,10 +1692,8 @@ static int cpuEmulate(VB *sim, uint32_t clocks) {
|
|||
}
|
||||
|
||||
/* Advance forward the CPU's number of clocks */
|
||||
if (sim->cpu.clocks != 0) {
|
||||
clocks -= sim->cpu.clocks;
|
||||
sim->cpu.clocks = 0;
|
||||
}
|
||||
|
||||
/* Processing by operation ID */
|
||||
switch (sim->cpu.operation) {
|
||||
|
|
60
core/vb.c
60
core/vb.c
|
@ -96,8 +96,10 @@ struct VB {
|
|||
uint8_t cta_r; /* Right column table index */
|
||||
} cta;
|
||||
|
||||
/* Display control */
|
||||
/* Display processor */
|
||||
struct {
|
||||
|
||||
/* Hardware state */
|
||||
uint8_t disp; /* Display enabled */
|
||||
uint8_t fclk; /* Frame clock signal high */
|
||||
uint8_t l0bsy; /* Displaying left frame buffer 0 */
|
||||
|
@ -108,9 +110,20 @@ struct VB {
|
|||
uint8_t re; /* Memory refresh enabled */
|
||||
uint8_t scanrdy; /* Mirrors are stable */
|
||||
uint8_t synce; /* Servo enabled */
|
||||
} dpctrl;
|
||||
|
||||
/* Drawing control */
|
||||
/* Simulation state */
|
||||
uint8_t brt[4]; /* Precomputed brightness */
|
||||
int buffer; /* Index of frame buffer to display */
|
||||
uint32_t clocks; /* Master clocks to wait */
|
||||
int column; /* Index of column to display */
|
||||
uint32_t cta; /* Column table pointer in memory */
|
||||
uint32_t fbDest; /* Output frame pixel address */
|
||||
uint32_t fbSrc; /* Source frame buffer address */
|
||||
int32_t repeat; /* Current column table repeat value */
|
||||
int step; /* Processing phase */
|
||||
} dp;
|
||||
|
||||
/* Pixel processor */
|
||||
struct {
|
||||
uint8_t f0bsy; /* Drawing into frame buffer 0 */
|
||||
uint8_t f1bsy; /* Drawing into frame buffer 1 */
|
||||
|
@ -119,7 +132,7 @@ struct VB {
|
|||
uint8_t sbcount; /* Current vertical output position */
|
||||
uint8_t sbout; /* Drawing specified vertical output position */
|
||||
uint8_t xpen; /* Drawing enabled */
|
||||
} xpctrl;
|
||||
} xp;
|
||||
|
||||
/* Control state */
|
||||
uint8_t bkcol; /* Backdrop color */
|
||||
|
@ -131,8 +144,11 @@ struct VB {
|
|||
uint8_t jplt[4][4]; /* Object palettes */
|
||||
uint16_t spt[4]; /* Object control */
|
||||
|
||||
/* Output frame buffers [buffer index][0=left, 1=right][pixel index] */
|
||||
uint8_t frames[2][2][384 * 224];
|
||||
|
||||
/* Other state */
|
||||
uint8_t vram[0x40000]; /* Video memory */
|
||||
uint8_t ram[0x40000]; /* Video memory */
|
||||
} vip;
|
||||
|
||||
/* Other state */
|
||||
|
@ -142,6 +158,7 @@ struct VB {
|
|||
vbOnException onException; /* CPU exception */
|
||||
vbOnExecute onExecute; /* CPU instruction execute */
|
||||
vbOnFetch onFetch; /* CPU instruction fetch */
|
||||
vbOnFrame onFrame; /* VIP frame ready */
|
||||
vbOnRead onRead; /* CPU instruction read */
|
||||
vbOnWrite onWrite; /* CPU instruction write */
|
||||
void *tag; /* User data */
|
||||
|
@ -242,21 +259,26 @@ VBAPI void* vbGetCartROM(VB *sim, uint32_t *size) {
|
|||
return sim->cart.rom;
|
||||
}
|
||||
|
||||
/* Retrieve the exception callback handle */
|
||||
/* Retrieve the exception callback handler */
|
||||
VBAPI vbOnException vbGetExceptionCallback(VB *sim) {
|
||||
return sim->onException;
|
||||
}
|
||||
|
||||
/* Retrieve the execute callback handle */
|
||||
/* Retrieve the execute callback handler */
|
||||
VBAPI vbOnExecute vbGetExecuteCallback(VB *sim) {
|
||||
return sim->onExecute;
|
||||
}
|
||||
|
||||
/* Retrieve the fetch callback handle */
|
||||
/* Retrieve the fetch callback handler */
|
||||
VBAPI vbOnFetch vbGetFetchCallback(VB *sim) {
|
||||
return sim->onFetch;
|
||||
}
|
||||
|
||||
/* Retrieve the frame callback handler */
|
||||
VBAPI vbOnFrame vbGetFrameCallback(VB *sim) {
|
||||
return sim->onFrame;
|
||||
}
|
||||
|
||||
/* Retrieve the value of the program counter */
|
||||
VBAPI uint32_t vbGetProgramCounter(VB *sim) {
|
||||
return sim->cpu.pc;
|
||||
|
@ -267,7 +289,7 @@ VBAPI int32_t vbGetProgramRegister(VB *sim, int index) {
|
|||
return index < 1 || index > 31 ? 0 : sim->cpu.program[index];
|
||||
}
|
||||
|
||||
/* Retrieve the read callback handle */
|
||||
/* Retrieve the read callback handler */
|
||||
VBAPI vbOnRead vbGetReadCallback(VB *sim) {
|
||||
return sim->onRead;
|
||||
}
|
||||
|
@ -282,7 +304,7 @@ VBAPI void* vbGetUserData(VB *sim) {
|
|||
return sim->tag;
|
||||
}
|
||||
|
||||
/* Retrieve the write callback handle */
|
||||
/* Retrieve the write callback handler */
|
||||
VBAPI vbOnWrite vbGetWriteCallback(VB *sim) {
|
||||
return sim->onWrite;
|
||||
}
|
||||
|
@ -293,6 +315,7 @@ VBAPI VB* vbInit(VB *sim) {
|
|||
sim->cart.rom = NULL;
|
||||
sim->onExecute = NULL;
|
||||
sim->onFetch = NULL;
|
||||
sim->onFrame = NULL;
|
||||
sim->onRead = NULL;
|
||||
sim->onWrite = NULL;
|
||||
vbReset(sim);
|
||||
|
@ -344,27 +367,34 @@ VBAPI int vbSetCartROM(VB *sim, void *rom, uint32_t size) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Specify a new exception callback handle */
|
||||
/* Specify a new exception callback handler */
|
||||
VBAPI vbOnException vbSetExceptionCallback(VB *sim, vbOnException callback) {
|
||||
vbOnException prev = sim->onException;
|
||||
sim->onException = callback;
|
||||
return prev;
|
||||
}
|
||||
|
||||
/* Specify a new execute callback handle */
|
||||
/* Specify a new execute callback handler */
|
||||
VBAPI vbOnExecute vbSetExecuteCallback(VB *sim, vbOnExecute callback) {
|
||||
vbOnExecute prev = sim->onExecute;
|
||||
sim->onExecute = callback;
|
||||
return prev;
|
||||
}
|
||||
|
||||
/* Specify a new fetch callback handle */
|
||||
/* Specify a new fetch callback handler */
|
||||
VBAPI vbOnFetch vbSetFetchCallback(VB *sim, vbOnFetch callback) {
|
||||
vbOnFetch prev = sim->onFetch;
|
||||
sim->onFetch = callback;
|
||||
return prev;
|
||||
}
|
||||
|
||||
/* Specify a new frame callback handler */
|
||||
VBAPI vbOnFrame vbSetFrameCallback(VB *sim, vbOnFrame callback) {
|
||||
vbOnFrame prev = sim->onFrame;
|
||||
sim->onFrame = callback;
|
||||
return prev;
|
||||
}
|
||||
|
||||
/* Specify a new value for the program counter */
|
||||
VBAPI uint32_t vbSetProgramCounter(VB *sim, uint32_t value) {
|
||||
sim->cpu.operation = CPU_FETCH;
|
||||
|
@ -378,7 +408,7 @@ VBAPI int32_t vbSetProgramRegister(VB *sim, int index, int32_t value) {
|
|||
return index < 1 || index > 31 ? 0 : (sim->cpu.program[index] = value);
|
||||
}
|
||||
|
||||
/* Specify a new read callback handle */
|
||||
/* Specify a new read callback handler */
|
||||
VBAPI vbOnRead vbSetReadCallback(VB *sim, vbOnRead callback) {
|
||||
vbOnRead prev = sim->onRead;
|
||||
sim->onRead = callback;
|
||||
|
@ -391,7 +421,7 @@ VBAPI uint32_t vbSetSystemRegister(VB *sim, int index, uint32_t value) {
|
|||
cpuSetSystemRegister(sim, index, value, 1);
|
||||
}
|
||||
|
||||
/* Specify a new write callback handle */
|
||||
/* Specify a new write callback handler */
|
||||
VBAPI vbOnWrite vbSetWriteCallback(VB *sim, vbOnWrite callback) {
|
||||
vbOnWrite prev = sim->onWrite;
|
||||
sim->onWrite = callback;
|
||||
|
|
12
core/vb.h
12
core/vb.h
|
@ -21,6 +21,7 @@ extern "C" {
|
|||
VB_DIRECT_EXCEPTION
|
||||
VB_DIRECT_EXECUTE
|
||||
VB_DIRECT_FETCH
|
||||
VB_DIRECT_FRAME
|
||||
VB_DIRECT_READ
|
||||
VB_DIRECT_WRITE
|
||||
|
||||
|
@ -58,14 +59,6 @@ extern "C" {
|
|||
|
||||
/********************************* Constants *********************************/
|
||||
|
||||
/* Callback IDs */
|
||||
#define VB_EXCEPTION 0
|
||||
#define VB_EXECUTE 1
|
||||
#define VB_FETCH 2
|
||||
#define VB_FRAME 3
|
||||
#define VB_READ 4
|
||||
#define VB_WRITE 5
|
||||
|
||||
/* System registers */
|
||||
#define VB_ADTRE 25
|
||||
#define VB_CHCW 24
|
||||
|
@ -96,6 +89,7 @@ typedef struct VB VB;
|
|||
typedef int (*vbOnException)(VB *sim, uint16_t *cause);
|
||||
typedef int (*vbOnExecute )(VB *sim, uint32_t address, const uint16_t *code, int length);
|
||||
typedef int (*vbOnFetch )(VB *sim, int fetch, uint32_t address, int32_t *value, uint32_t *cycles);
|
||||
typedef int (*vbOnFrame )(VB *sim);
|
||||
typedef int (*vbOnRead )(VB *sim, uint32_t address, int type, int32_t *value, uint32_t *cycles);
|
||||
typedef int (*vbOnWrite )(VB *sim, uint32_t address, int type, int32_t *value, uint32_t *cycles, int *cancel);
|
||||
|
||||
|
@ -112,6 +106,7 @@ VBAPI void* vbGetCartROM (VB *sim, uint32_t *size);
|
|||
VBAPI vbOnException vbGetExceptionCallback(VB *sim);
|
||||
VBAPI vbOnExecute vbGetExecuteCallback (VB *sim);
|
||||
VBAPI vbOnFetch vbGetFetchCallback (VB *sim);
|
||||
VBAPI vbOnFrame vbGetFrameCallback (VB *sim);
|
||||
VBAPI uint32_t vbGetProgramCounter (VB *sim);
|
||||
VBAPI int32_t vbGetProgramRegister (VB *sim, int index);
|
||||
VBAPI vbOnRead vbGetReadCallback (VB *sim);
|
||||
|
@ -126,6 +121,7 @@ VBAPI int vbSetCartROM (VB *sim, void *rom, uint32_t size);
|
|||
VBAPI vbOnException vbSetExceptionCallback(VB *sim, vbOnException callback);
|
||||
VBAPI vbOnExecute vbSetExecuteCallback (VB *sim, vbOnExecute callback);
|
||||
VBAPI vbOnFetch vbSetFetchCallback (VB *sim, vbOnFetch callback);
|
||||
VBAPI vbOnFrame vbSetFrameCallback (VB *sim, vbOnFrame callback);
|
||||
VBAPI uint32_t vbSetProgramCounter (VB *sim, uint32_t value);
|
||||
VBAPI int32_t vbSetProgramRegister (VB *sim, int index, int32_t value);
|
||||
VBAPI vbOnRead vbSetReadCallback (VB *sim, vbOnRead callback);
|
||||
|
|
295
core/vip.c
295
core/vip.c
|
@ -3,13 +3,68 @@
|
|||
|
||||
|
||||
|
||||
/********************************** Macros ***********************************/
|
||||
|
||||
/* Compute how many clocks are in some number of milliseconds */
|
||||
#define vipClocksMs(x) x * 20000
|
||||
|
||||
|
||||
|
||||
/***************************** Module Functions ******************************/
|
||||
|
||||
/* Precompute brightness values for image output */
|
||||
static void vipComputeBrightness(VB *sim) {
|
||||
int32_t brt[4]; /* Working output */
|
||||
int32_t repeat; /* Multiplier from column table */
|
||||
int x; /* Iterator */
|
||||
|
||||
/* Compute brightness from hardware state */
|
||||
repeat = (int32_t) sim->vip.ram[sim->vip.dp.cta + 1] + 1;
|
||||
brt[1] = repeat * sim->vip.brtRest[0];
|
||||
brt[2] = repeat * sim->vip.brtRest[1];
|
||||
brt[3] = repeat * sim->vip.brtRest[2] + brt[2] + brt[1];
|
||||
|
||||
/* Scale brightness values to 0..255 */
|
||||
for (x = 1; x < 4; x++)
|
||||
sim->vip.dp.brt[x] = ((brt[x] > 127 ? 127 : brt[x]) * 510 + 127) / 254;
|
||||
}
|
||||
|
||||
/* Read a palette */
|
||||
static int32_t vipReadPalette(uint8_t *entries) {
|
||||
return entries[3] << 6 | entries[2] << 4 | entries[1] << 2;
|
||||
}
|
||||
|
||||
/* Raise an interrupt request */
|
||||
static void vipThrow(VB *sim, uint16_t cause) {
|
||||
if (!(sim->vip.intenb & cause))
|
||||
return;
|
||||
sim->vip.intpnd |= cause;
|
||||
sim->cpu.irq |= 0x0010;
|
||||
}
|
||||
|
||||
/* Transfer one column of frame buffer pixels to output */
|
||||
static void vipTransferColumn(VB *sim, int32_t eye) {
|
||||
int32_t bits; /* Pixel bits from frame buffer */
|
||||
int y, z; /* Iterators */
|
||||
|
||||
/* Select source and destination addresses in host memory */
|
||||
uint8_t *dest = &sim->vip.frames
|
||||
[sim->vip.dp.buffer][eye][sim->vip.dp.column];
|
||||
uint8_t *src = &sim->vip.ram[
|
||||
eye << 16 |
|
||||
sim->vip.dp.buffer << 15 |
|
||||
sim->vip.dp.column << 6
|
||||
];
|
||||
|
||||
/* Transfer all rows as words */
|
||||
for (y = 0; y < 224; y += 4) {
|
||||
bits = busReadBuffer(src, VB_S32);
|
||||
for (z = 0; z < 1536; z += 384, bits >>= 2)
|
||||
dest[z] = sim->vip.dp.brt[bits & 3];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Write a palette */
|
||||
static void vipWritePalette(uint8_t *entries, int32_t mask, int32_t value) {
|
||||
if (mask & 0x00FF)
|
||||
|
@ -21,7 +76,7 @@ static void vipWritePalette(uint8_t *entries, int32_t mask, int32_t value) {
|
|||
|
||||
/* Read a typed value from an I/O register */
|
||||
static int32_t vipReadIO(VB *sim, uint32_t address, int type) {
|
||||
int mask; /* Byte access mask */
|
||||
int32_t mask; /* Byte access mask */
|
||||
int32_t value; /* Return value */
|
||||
|
||||
/* Adjustments by type */
|
||||
|
@ -53,16 +108,16 @@ static int32_t vipReadIO(VB *sim, uint32_t address, int type) {
|
|||
|
||||
case 0x5F820>>1: /* DPSTTS */
|
||||
value =
|
||||
(int32_t) sim->vip.dpctrl.lock << 10 |
|
||||
(int32_t) sim->vip.dpctrl.synce << 9 |
|
||||
(int32_t) sim->vip.dpctrl.re << 8 |
|
||||
(int32_t) sim->vip.dpctrl.fclk << 7 |
|
||||
(int32_t) sim->vip.dpctrl.scanrdy << 6 |
|
||||
(int32_t) sim->vip.dpctrl.r1bsy << 5 |
|
||||
(int32_t) sim->vip.dpctrl.l1bsy << 4 |
|
||||
(int32_t) sim->vip.dpctrl.r0bsy << 3 |
|
||||
(int32_t) sim->vip.dpctrl.l0bsy << 2 |
|
||||
(int32_t) sim->vip.dpctrl.disp << 1
|
||||
(int32_t) sim->vip.dp.lock << 10 |
|
||||
(int32_t) sim->vip.dp.synce << 9 |
|
||||
(int32_t) sim->vip.dp.re << 8 |
|
||||
(int32_t) sim->vip.dp.fclk << 7 |
|
||||
(int32_t) sim->vip.dp.scanrdy << 6 |
|
||||
(int32_t) sim->vip.dp.r1bsy << 5 |
|
||||
(int32_t) sim->vip.dp.l1bsy << 4 |
|
||||
(int32_t) sim->vip.dp.r0bsy << 3 |
|
||||
(int32_t) sim->vip.dp.l0bsy << 2 |
|
||||
(int32_t) sim->vip.dp.disp << 1
|
||||
;
|
||||
break;
|
||||
|
||||
|
@ -89,12 +144,12 @@ static int32_t vipReadIO(VB *sim, uint32_t address, int type) {
|
|||
|
||||
case 0x5F840>>1: /* XPSTTS */
|
||||
value =
|
||||
(int32_t) sim->vip.xpctrl.sbout << 15 |
|
||||
(int32_t) sim->vip.xpctrl.sbcount << 8 |
|
||||
(int32_t) sim->vip.xpctrl.overtime << 4 |
|
||||
(int32_t) sim->vip.xpctrl.f1bsy << 3 |
|
||||
(int32_t) sim->vip.xpctrl.f0bsy << 2 |
|
||||
(int32_t) sim->vip.xpctrl.xpen << 1
|
||||
(int32_t) sim->vip.xp.sbout << 15 |
|
||||
(int32_t) sim->vip.xp.sbcount << 8 |
|
||||
(int32_t) sim->vip.xp.overtime << 4 |
|
||||
(int32_t) sim->vip.xp.f1bsy << 3 |
|
||||
(int32_t) sim->vip.xp.f0bsy << 2 |
|
||||
(int32_t) sim->vip.xp.xpen << 1
|
||||
;
|
||||
break;
|
||||
|
||||
|
@ -158,7 +213,7 @@ static int32_t vipReadIO(VB *sim, uint32_t address, int type) {
|
|||
/* Write a typed value to an I/O register */
|
||||
static void vipWriteIO(
|
||||
VB *sim, uint32_t address, int type, int32_t value, int debug) {
|
||||
int mask; /* Byte access mask */
|
||||
int32_t mask; /* Byte access mask */
|
||||
|
||||
/* Adjustments by type */
|
||||
switch (type) {
|
||||
|
@ -202,12 +257,12 @@ static void vipWriteIO(
|
|||
|
||||
case 0x5F822>>1: /* DPCTRL */
|
||||
if ((mask & 0xFF00) == 0) {
|
||||
sim->vip.dpctrl.lock = value >> 10 & 1;
|
||||
sim->vip.dpctrl.synce = value >> 9 & 1;
|
||||
sim->vip.dpctrl.re = value >> 8 & 1;
|
||||
sim->vip.dp.lock = value >> 10 & 1;
|
||||
sim->vip.dp.synce = value >> 9 & 1;
|
||||
sim->vip.dp.re = value >> 8 & 1;
|
||||
}
|
||||
if ((mask & 0x00FF) == 0) {
|
||||
sim->vip.dpctrl.disp = value >> 1 & 1;
|
||||
sim->vip.dp.disp = value >> 1 & 1;
|
||||
/* if (value & 1) {} TODO: DPRST */
|
||||
}
|
||||
break;
|
||||
|
@ -238,9 +293,9 @@ static void vipWriteIO(
|
|||
|
||||
case 0x5F842>>1: /* XPCTRL */
|
||||
if ((mask & 0xFF00) == 0)
|
||||
sim->vip.xpctrl.sbcmp = value >> 8 & 31;
|
||||
sim->vip.xp.sbcmp = value >> 8 & 31;
|
||||
if ((mask & 0x00FF) == 0) {
|
||||
sim->vip.xpctrl.xpen = value >> 1 & 1;
|
||||
sim->vip.xp.xpen = value >> 1 & 1;
|
||||
/* if (value & 1) TODO: XPRST */
|
||||
}
|
||||
break;
|
||||
|
@ -292,13 +347,138 @@ static void vipWriteIO(
|
|||
|
||||
|
||||
|
||||
/***************************** Callback Handlers *****************************/
|
||||
|
||||
/* Prepare to handle an exception */
|
||||
#ifndef VB_DIRECT_FRAME
|
||||
#define VB_ON_FRAME sim->onFrame
|
||||
#else
|
||||
extern int VB_DIRECT_FRAME(VB *);
|
||||
#define VB_ON_FRAME VB_DIRECT_FRAME
|
||||
#endif
|
||||
static int vipOnFrame(VB *sim) {
|
||||
return sim->onFrame != NULL && VB_ON_FRAME(sim);
|
||||
}
|
||||
#undef VB_ON_FRAME
|
||||
|
||||
|
||||
|
||||
/***************************** Library Functions *****************************/
|
||||
|
||||
/* Display processor */
|
||||
static int vipEmulateDisplay(VB *sim, uint32_t clocks) {
|
||||
|
||||
/* Process all clocks */
|
||||
while (clocks != 0) {
|
||||
|
||||
/* The next event is after the time remaining */
|
||||
if (sim->vip.dp.clocks > clocks) {
|
||||
sim->vip.dp.clocks -= clocks;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Advance forward the component's number of clocks */
|
||||
clocks -= sim->vip.dp.clocks;
|
||||
sim->vip.dp.clocks = 0;
|
||||
|
||||
/* Processing by operation phase */
|
||||
switch (sim->vip.dp.step) {
|
||||
|
||||
case 0: /* 0ms - FCLK rising edge */
|
||||
sim->vip.dp.clocks = vipClocksMs(3);
|
||||
sim->vip.dp.fclk = 1;
|
||||
sim->vip.dp.step = 1;
|
||||
vipThrow(sim, 0x0010); /* FRAMESTART */
|
||||
/* TODO: Initiate drawing, throw GAMESTART */
|
||||
/* ELSE: Set OVERTIME, throw TIMEERR */
|
||||
break;
|
||||
|
||||
/* 0ms-3ms - Idle */
|
||||
|
||||
case 1: /* 3ms - L*BSY rising edge */
|
||||
if (sim->vip.dp.buffer == 0)
|
||||
sim->vip.dp.l0bsy = 1;
|
||||
else sim->vip.dp.l1bsy = 1;
|
||||
sim->vip.dp.column = 0;
|
||||
sim->vip.dp.cta = 0x3DC00 | (uint32_t)sim->vip.cta.cta_l<<1;
|
||||
sim->vip.dp.step = 2;
|
||||
vipComputeBrightness(sim);
|
||||
|
||||
/* Fallthrough */
|
||||
case 2: /* 3ms-8ms - Display left frame buffer */
|
||||
if ((sim->vip.dp.column & 3) == 0)
|
||||
vipComputeBrightness(sim);
|
||||
vipTransferColumn(sim, 0);
|
||||
sim->vip.dp.clocks =
|
||||
260 + (0xA94 >> sim->vip.dp.column % 12 & 1);
|
||||
sim->vip.dp.column++;
|
||||
if ((sim->vip.dp.column & 3) == 0)
|
||||
sim->vip.dp.cta -= 2;
|
||||
if (sim->vip.dp.column == 384)
|
||||
sim->vip.dp.step = 3;
|
||||
break;
|
||||
|
||||
case 3: /* 8ms - L*BSY falling edge */
|
||||
if (sim->vip.dp.buffer == 0)
|
||||
sim->vip.dp.l0bsy = 0;
|
||||
else sim->vip.dp.l1bsy = 0;
|
||||
sim->vip.dp.clocks = vipClocksMs(2);
|
||||
sim->vip.dp.step = 4;
|
||||
vipThrow(sim, 0x0002); /* LFBEND */
|
||||
break;
|
||||
|
||||
/* 8ms-10ms - Idle */
|
||||
|
||||
case 4: /* 10ms - FCLK falling edge */
|
||||
sim->vip.dp.clocks = vipClocksMs(3);
|
||||
sim->vip.dp.fclk = 0;
|
||||
sim->vip.dp.step = 5;
|
||||
break;
|
||||
|
||||
/* 10ms-13ms - Idle */
|
||||
|
||||
case 5: /* 13ms - R*BSY rising edge */
|
||||
if (sim->vip.dp.buffer == 0)
|
||||
sim->vip.dp.r0bsy = 1;
|
||||
else sim->vip.dp.r1bsy = 1;
|
||||
sim->vip.dp.column = 0;
|
||||
sim->vip.dp.cta = 0x3DE00 | (uint32_t)sim->vip.cta.cta_r<<1;
|
||||
sim->vip.dp.step = 6;
|
||||
|
||||
/* Fallthrough */
|
||||
case 6: /* 13ms-18ms - Display right frame buffer */
|
||||
vipTransferColumn(sim, 1);
|
||||
sim->vip.dp.clocks =
|
||||
260 + (0xA94 >> sim->vip.dp.column % 12 & 1);
|
||||
sim->vip.dp.column++;
|
||||
if (sim->vip.dp.column == 384)
|
||||
sim->vip.dp.step = 7;
|
||||
break;
|
||||
|
||||
case 7: /* 18ms - R*BSY falling edge */
|
||||
if (sim->vip.dp.buffer == 0)
|
||||
sim->vip.dp.r0bsy = 0;
|
||||
else sim->vip.dp.r1bsy = 0;
|
||||
sim->vip.dp.clocks = vipClocksMs(2);
|
||||
sim->vip.dp.step = 0;
|
||||
vipThrow(sim, 0x0004); /* RFBEND */
|
||||
if (vipOnFrame(sim))
|
||||
return 1;
|
||||
break;
|
||||
|
||||
/* 18ms-20ms - Idle */
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Process component */
|
||||
static int vipEmulate(VB *sim, uint32_t clocks) {
|
||||
(void) sim;
|
||||
(void) clocks;
|
||||
return 0;
|
||||
int brk = vipEmulateDisplay(sim, clocks);
|
||||
/*vipEmulateDrawing(sim, clocks);*/
|
||||
return brk;
|
||||
}
|
||||
|
||||
/* Read a typed value from the VIP bus */
|
||||
|
@ -307,10 +487,9 @@ static void vipRead(VB *sim, uint32_t address, int type, int32_t *value) {
|
|||
/* Working variables */
|
||||
address &= 0x0007FFFF;
|
||||
|
||||
/* VRAM */
|
||||
if (address < 0x40000) {
|
||||
*value = busReadBuffer(&sim->vip.vram[address], type);
|
||||
}
|
||||
/* RAM */
|
||||
if (address < 0x40000)
|
||||
*value = busReadBuffer(&sim->vip.ram[address], type);
|
||||
|
||||
/* Unmapped */
|
||||
else if (address < 0x5E000)
|
||||
|
@ -327,7 +506,7 @@ static void vipRead(VB *sim, uint32_t address, int type, int32_t *value) {
|
|||
/* Mirrors of character memory */
|
||||
else {
|
||||
address = 0x06000 | (address << 2 & 0x18000) | (address & 0x01FFF);
|
||||
*value = busReadBuffer(&sim->vip.vram[address], type);
|
||||
*value = busReadBuffer(&sim->vip.ram[address], type);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -337,31 +516,33 @@ static void vipReset(VB *sim) {
|
|||
int x, y; /* Iterators */
|
||||
|
||||
/* Normal */
|
||||
sim->vip.dpctrl.disp = 0;
|
||||
sim->vip.dpctrl.re = 0;
|
||||
sim->vip.dpctrl.synce = 0;
|
||||
sim->vip.dp.disp = 0;
|
||||
sim->vip.dp.re = 0;
|
||||
sim->vip.dp.synce = 0;
|
||||
sim->vip.intenb = 0x0000;
|
||||
sim->vip.xpctrl.xpen = 0;
|
||||
sim->vip.xp.xpen = 0;
|
||||
|
||||
/* Extra (the hardware does not do this) */
|
||||
for (x = 0; x < 0x80000; x++)
|
||||
sim->vip.ram[x] = 0;
|
||||
sim->vip.bkcol = 0;
|
||||
sim->vip.cta.cta_l = 0;
|
||||
sim->vip.cta.cta_r = 0;
|
||||
sim->vip.cta.cta_l = 0xFA;
|
||||
sim->vip.cta.cta_r = 0xFA;
|
||||
sim->vip.frmcyc = 0;
|
||||
sim->vip.intpnd = 0x0000;
|
||||
sim->vip.dpctrl.fclk = 0;
|
||||
sim->vip.dpctrl.l0bsy = 0;
|
||||
sim->vip.dpctrl.l1bsy = 0;
|
||||
sim->vip.dpctrl.lock = 0;
|
||||
sim->vip.dpctrl.r0bsy = 0;
|
||||
sim->vip.dpctrl.r1bsy = 0;
|
||||
sim->vip.dpctrl.scanrdy = 0;
|
||||
sim->vip.xpctrl.f0bsy = 0;
|
||||
sim->vip.xpctrl.f1bsy = 0;
|
||||
sim->vip.xpctrl.overtime = 0;
|
||||
sim->vip.xpctrl.sbcmp = 0;
|
||||
sim->vip.xpctrl.sbcount = 0;
|
||||
sim->vip.xpctrl.sbout = 0;
|
||||
sim->vip.dp.fclk = 0;
|
||||
sim->vip.dp.l0bsy = 0;
|
||||
sim->vip.dp.l1bsy = 0;
|
||||
sim->vip.dp.lock = 0;
|
||||
sim->vip.dp.r0bsy = 0;
|
||||
sim->vip.dp.r1bsy = 0;
|
||||
sim->vip.dp.scanrdy = 0;
|
||||
sim->vip.xp.f0bsy = 0;
|
||||
sim->vip.xp.f1bsy = 0;
|
||||
sim->vip.xp.overtime = 0;
|
||||
sim->vip.xp.sbcmp = 0;
|
||||
sim->vip.xp.sbcount = 0;
|
||||
sim->vip.xp.sbout = 0;
|
||||
for (x = 0; x < 4; x++) {
|
||||
sim->vip.brtRest[x] = 0;
|
||||
sim->vip.spt [x] = 0;
|
||||
|
@ -371,24 +552,28 @@ static void vipReset(VB *sim) {
|
|||
}
|
||||
}
|
||||
|
||||
/* Other */
|
||||
sim->vip.dp.brt[0] = 0;
|
||||
sim->vip.dp.clocks = 0;
|
||||
sim->vip.dp.step = 0;
|
||||
}
|
||||
|
||||
/* Determine how many clocks are guaranteed to process */
|
||||
static uint32_t vipUntil(VB *sim, uint32_t clocks) {
|
||||
(void) sim;
|
||||
/* Don't allow clocks to exceed interrupt conditions, even if disabled */
|
||||
return clocks;
|
||||
}
|
||||
|
||||
/* Write a typed value to the VIP bus */
|
||||
static void vipWrite(VB*sim,uint32_t address,int type,int32_t value,int debug){
|
||||
(void) debug;
|
||||
|
||||
/* Working variables */
|
||||
address &= 0x0007FFFF;
|
||||
|
||||
/* VRAM */
|
||||
/* RAM */
|
||||
if (address < 0x40000)
|
||||
busWriteBuffer(&sim->vip.vram[address], type, value);
|
||||
busWriteBuffer(&sim->vip.ram[address], type, value);
|
||||
|
||||
/* Unmapped */
|
||||
else if (address < 0x5E000)
|
||||
|
@ -405,7 +590,7 @@ static void vipWrite(VB*sim,uint32_t address,int type,int32_t value,int debug){
|
|||
/* Mirrors of character memory */
|
||||
else {
|
||||
address = 0x06000 | (address << 2 & 0x18000) | (address & 0x01FFF);
|
||||
busWriteBuffer(&sim->vip.vram[address], type, value);
|
||||
busWriteBuffer(&sim->vip.ram[address], type, value);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue