mirror of
https://github.com/pruten/shoebill.git
synced 2024-06-01 19:41:42 +00:00
VIA Timers + 16/32-bit video support
- VIA timers should probably work now, although it turns out A/UX rarely uses them (only during startup to time a dbra loop and other stuff) - Updated video.c and the fake nubus video card driver to support "thousands" and "millions" of colors when 32-bit QuickDraw is available
This commit is contained in:
parent
a16a6700e4
commit
5c1fdf6b73
|
@ -60,6 +60,8 @@ void shoebill_stop()
|
|||
pthread_join(shoe.cpu_thread_pid, NULL);
|
||||
pthread_mutex_destroy(&shoe.cpu_thread_lock);
|
||||
|
||||
pthread_mutex_destroy(&shoe.via_cpu_lock);
|
||||
|
||||
shoe.running = 0;
|
||||
|
||||
// Close all the SCSI disk images
|
||||
|
@ -542,43 +544,72 @@ static void _do_clut_translation(shoebill_card_video_t *ctx)
|
|||
switch (ctx->depth) {
|
||||
case 1: {
|
||||
for (i=0; i < ctx->pixels/8; i++) {
|
||||
const uint8_t byte = ctx->indexed_buf[i];
|
||||
ctx->direct_buf[i * 8 + 0] = ctx->clut[(byte >> 7) & 1];
|
||||
ctx->direct_buf[i * 8 + 1] = ctx->clut[(byte >> 6) & 1];
|
||||
ctx->direct_buf[i * 8 + 2] = ctx->clut[(byte >> 5) & 1];
|
||||
ctx->direct_buf[i * 8 + 3] = ctx->clut[(byte >> 4) & 1];
|
||||
ctx->direct_buf[i * 8 + 4] = ctx->clut[(byte >> 3) & 1];
|
||||
ctx->direct_buf[i * 8 + 5] = ctx->clut[(byte >> 2) & 1];
|
||||
ctx->direct_buf[i * 8 + 6] = ctx->clut[(byte >> 1) & 1];
|
||||
ctx->direct_buf[i * 8 + 7] = ctx->clut[(byte >> 0) & 1];
|
||||
const uint8_t byte = ctx->direct_buf[i];
|
||||
ctx->temp_buf[i * 8 + 0] = ctx->clut[(byte >> 7) & 1];
|
||||
ctx->temp_buf[i * 8 + 1] = ctx->clut[(byte >> 6) & 1];
|
||||
ctx->temp_buf[i * 8 + 2] = ctx->clut[(byte >> 5) & 1];
|
||||
ctx->temp_buf[i * 8 + 3] = ctx->clut[(byte >> 4) & 1];
|
||||
ctx->temp_buf[i * 8 + 4] = ctx->clut[(byte >> 3) & 1];
|
||||
ctx->temp_buf[i * 8 + 5] = ctx->clut[(byte >> 2) & 1];
|
||||
ctx->temp_buf[i * 8 + 6] = ctx->clut[(byte >> 1) & 1];
|
||||
ctx->temp_buf[i * 8 + 7] = ctx->clut[(byte >> 0) & 1];
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
for (i=0; i < ctx->pixels/4; i++) {
|
||||
const uint8_t byte = ctx->indexed_buf[i];
|
||||
ctx->direct_buf[i * 4 + 0] = ctx->clut[(byte >> 6) & 3];
|
||||
ctx->direct_buf[i * 4 + 1] = ctx->clut[(byte >> 4) & 3];
|
||||
ctx->direct_buf[i * 4 + 2] = ctx->clut[(byte >> 2) & 3];
|
||||
ctx->direct_buf[i * 4 + 3] = ctx->clut[(byte >> 0) & 3];
|
||||
const uint8_t byte = ctx->direct_buf[i];
|
||||
ctx->temp_buf[i * 4 + 0] = ctx->clut[(byte >> 6) & 3];
|
||||
ctx->temp_buf[i * 4 + 1] = ctx->clut[(byte >> 4) & 3];
|
||||
ctx->temp_buf[i * 4 + 2] = ctx->clut[(byte >> 2) & 3];
|
||||
ctx->temp_buf[i * 4 + 3] = ctx->clut[(byte >> 0) & 3];
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 4: {
|
||||
for (i=0; i < ctx->pixels/2; i++) {
|
||||
const uint8_t byte = ctx->indexed_buf[i];
|
||||
ctx->direct_buf[i * 2 + 0] = ctx->clut[(byte >> 4) & 0xf];
|
||||
ctx->direct_buf[i * 2 + 1] = ctx->clut[(byte >> 0) & 0xf];
|
||||
const uint8_t byte = ctx->direct_buf[i];
|
||||
ctx->temp_buf[i * 2 + 0] = ctx->clut[(byte >> 4) & 0xf];
|
||||
ctx->temp_buf[i * 2 + 1] = ctx->clut[(byte >> 0) & 0xf];
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 8:
|
||||
case 8: {
|
||||
for (i=0; i < ctx->pixels; i++)
|
||||
ctx->direct_buf[i] = ctx->clut[ctx->indexed_buf[i]];
|
||||
ctx->temp_buf[i] = ctx->clut[ctx->direct_buf[i]];
|
||||
break;
|
||||
}
|
||||
case 16: {
|
||||
uint16_t *direct = (uint16_t*)ctx->direct_buf;
|
||||
for (i=0; i < ctx->pixels; i++) {
|
||||
const uint16_t p = ntohs(direct[i]);
|
||||
video_ctx_color_t tmp;
|
||||
tmp.r = ((p >> 10) & 31);
|
||||
tmp.g = (p >> 5) & 31;
|
||||
tmp.b = (p >> 0) & 31;
|
||||
|
||||
ctx->temp_buf[i].r = (tmp.r << 3) | (tmp.r >> 2);
|
||||
ctx->temp_buf[i].g = (tmp.g << 3) | (tmp.g >> 2);
|
||||
ctx->temp_buf[i].b = (tmp.b << 3) | (tmp.b >> 2);
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 32: {
|
||||
uint32_t *direct = (uint32_t*)ctx->direct_buf, *tmp = (uint32_t*)ctx->temp_buf;
|
||||
for (i=0; i < ctx->pixels; i++)
|
||||
tmp[i] = direct[i] >> 8;
|
||||
|
||||
|
||||
// OpenGL wants RGBA
|
||||
// Apple must be ARGB (which is BGRA, when dereferenced)
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
assert(!"unknown depth");
|
||||
assert(!"unsupported depth");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -604,14 +635,12 @@ shoebill_video_frame_info_t shoebill_get_video_frame(uint8_t slotnum,
|
|||
if (just_params)
|
||||
return result;
|
||||
|
||||
if (ctx->depth <= 8) {
|
||||
_do_clut_translation(ctx);
|
||||
result.buf = (uint8_t*)ctx->direct_buf;
|
||||
|
||||
return result;
|
||||
}
|
||||
_do_clut_translation(ctx);
|
||||
result.buf = (uint8_t*)ctx->temp_buf;
|
||||
|
||||
return result;
|
||||
|
||||
|
||||
assert(!"depth not supported");
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -729,6 +758,8 @@ uint32_t shoebill_initialize(shoebill_config_t *config)
|
|||
shoe.pc = pc;
|
||||
memcpy(shoe.scsi_devices, disks, 8 * sizeof(scsi_device_t));
|
||||
|
||||
pthread_mutex_init(&shoe.via_cpu_lock, NULL);
|
||||
|
||||
pthread_mutex_init(&shoe.via_clock_thread_lock, NULL);
|
||||
pthread_mutex_lock(&shoe.via_clock_thread_lock);
|
||||
pthread_create(&shoe.via_thread_pid, NULL, via_clock_thread, NULL);
|
||||
|
|
33
core/scsi.c
33
core/scsi.c
|
@ -102,6 +102,17 @@ const char *scsi_write_reg_str[8] = {
|
|||
"start_dma_initiator_receive"
|
||||
};
|
||||
|
||||
static void scsi_raise_irq() {via_raise_interrupt(2, IFR_CB2);}
|
||||
static void scsi_raise_drq() {via_raise_interrupt(2, IFR_CA2);}
|
||||
|
||||
static _Bool phase_match (void)
|
||||
{
|
||||
uint8_t phase_tmp = shoe.scsi.msg;
|
||||
phase_tmp = (phase_tmp << 1) | shoe.scsi.cd;
|
||||
phase_tmp = (phase_tmp << 1) | shoe.scsi.io;
|
||||
return (phase_tmp == (shoe.scsi.target_command & 7));
|
||||
}
|
||||
|
||||
static void switch_status_phase (uint8_t status_byte)
|
||||
{
|
||||
printf("scsi_reg_something: switching to STATUS phase\n");
|
||||
|
@ -115,7 +126,7 @@ static void switch_status_phase (uint8_t status_byte)
|
|||
shoe.scsi.bufi = 0;
|
||||
|
||||
// Phase mismatch (I think)
|
||||
via_raise_interrupt(2, 0);
|
||||
scsi_raise_drq();
|
||||
}
|
||||
|
||||
static void switch_command_phase (void)
|
||||
|
@ -130,7 +141,7 @@ static void switch_command_phase (void)
|
|||
shoe.scsi.bufi = 0;
|
||||
|
||||
// Phase mismatch, probably
|
||||
via_raise_interrupt(2, 0);
|
||||
scsi_raise_drq();
|
||||
}
|
||||
|
||||
static void switch_message_in_phase (uint8_t message_byte)
|
||||
|
@ -145,7 +156,7 @@ static void switch_message_in_phase (uint8_t message_byte)
|
|||
shoe.scsi.message_byte = message_byte; // only one-byte messages supported for now
|
||||
|
||||
// Phase mismatch, probably
|
||||
via_raise_interrupt(2, 0);
|
||||
scsi_raise_drq();
|
||||
}
|
||||
|
||||
static void switch_bus_free_phase (void)
|
||||
|
@ -176,7 +187,7 @@ static void switch_data_in_phase (void)
|
|||
shoe.scsi.io = 1;
|
||||
|
||||
// Phase mismatch, probably
|
||||
via_raise_interrupt(2, 0);
|
||||
scsi_raise_drq();
|
||||
}
|
||||
|
||||
static void switch_data_out_phase (void)
|
||||
|
@ -189,7 +200,7 @@ static void switch_data_out_phase (void)
|
|||
shoe.scsi.cd = 0;
|
||||
shoe.scsi.io = 0;
|
||||
|
||||
via_raise_interrupt(2, 0);
|
||||
scsi_raise_drq();
|
||||
}
|
||||
|
||||
struct inquiry_response_t {
|
||||
|
@ -471,13 +482,7 @@ void scsi_reg_read ()
|
|||
uint8_t tmp = 0;
|
||||
|
||||
// Compute phase match (IO, CD, MSG match the assertions in target_command register)
|
||||
uint8_t phase_tmp = 0;
|
||||
{
|
||||
phase_tmp = (phase_tmp << 1) | shoe.scsi.msg;
|
||||
phase_tmp = (phase_tmp << 1) | shoe.scsi.cd;
|
||||
phase_tmp = (phase_tmp << 1) | shoe.scsi.io;
|
||||
phase_tmp = (phase_tmp == (shoe.scsi.target_command & 7));
|
||||
}
|
||||
uint8_t phase_tmp = phase_match();
|
||||
|
||||
tmp |= (shoe.scsi.ack * BUS_STATUS_ACK);
|
||||
tmp |= (shoe.scsi.atn * BUS_STATUS_ATN);
|
||||
|
@ -615,14 +620,14 @@ void scsi_reg_write ()
|
|||
|
||||
case 5: // Start DMA send
|
||||
shoe.scsi.dma_send_written = 1;
|
||||
via_raise_interrupt(2, 0);
|
||||
scsi_raise_drq();
|
||||
break;
|
||||
|
||||
case 6: // Start DMA target receive
|
||||
break;
|
||||
|
||||
case 7: // Start DMA initiator receive
|
||||
via_raise_interrupt(2, 0);
|
||||
scsi_raise_drq();
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -390,11 +390,13 @@ typedef struct {
|
|||
|
||||
typedef struct {
|
||||
uint8_t ifr, ier, ddrb, ddra, sr, acr, pcr;
|
||||
// uint8_t rega, regb;
|
||||
uint16_t t1c, t2c, t1l;
|
||||
|
||||
uint8_t rega_input, regb_input;
|
||||
uint8_t rega_output, regb_output;
|
||||
|
||||
uint16_t t1c, t2c, t1l;
|
||||
long double t1_last_set, t2_last_set;
|
||||
_Bool /*t1_interrupt_enabled,*/ t2_interrupt_enabled; // whether the "one-shot" interrupt can fire
|
||||
} via_state_t;
|
||||
|
||||
#define PRAM_READ 1
|
||||
|
@ -540,9 +542,8 @@ typedef struct {
|
|||
} video_ctx_color_t;
|
||||
|
||||
typedef struct {
|
||||
video_ctx_color_t *direct_buf, *clut;
|
||||
uint8_t *indexed_buf, *rom;
|
||||
uint8_t *cur_buf;
|
||||
video_ctx_color_t *temp_buf, *clut;
|
||||
uint8_t *rom, *direct_buf;
|
||||
|
||||
uint32_t pixels;
|
||||
|
||||
|
@ -611,8 +612,9 @@ typedef struct {
|
|||
volatile uint32_t via_thread_notifications;
|
||||
|
||||
pthread_mutex_t cpu_thread_lock;
|
||||
pthread_mutex_t via_clock_thread_lock;
|
||||
pthread_mutex_t via_clock_thread_lock; // synchronizes shoebill_start() and the starting of via_clock_thread()
|
||||
pthread_mutex_t cpu_freeze_lock;
|
||||
pthread_mutex_t via_cpu_lock; // synchronizes reads/writes of VIA registers and via_clock_thread()
|
||||
|
||||
// -- Assorted CPU state variables --
|
||||
uint16_t op; // the first word of the instruction we're currently running
|
||||
|
@ -946,8 +948,8 @@ void *via_clock_thread(void *arg);
|
|||
#define IFR_SHIFT_REG 2
|
||||
#define IFR_CB2 3
|
||||
#define IFR_CB1 4
|
||||
#define IFR_TIMER1 5
|
||||
#define IFR_TIMER2 6
|
||||
#define IFR_TIMER2 5
|
||||
#define IFR_TIMER1 6
|
||||
#define IFR_IRQ 7
|
||||
|
||||
// adb / keyboard / mouse stuff
|
||||
|
|
81
core/via.c
81
core/via.c
|
@ -195,10 +195,10 @@ static long double _now (void)
|
|||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
|
||||
long double secs = tv.tv_sec;
|
||||
long double usecs = tv.tv_usec;
|
||||
|
||||
return secs + (usecs / 1000000.0);
|
||||
const long double secs = tv.tv_sec;
|
||||
const long double usecs = tv.tv_usec;
|
||||
const long double result = secs + (usecs / 1000000.0);
|
||||
return result;
|
||||
}
|
||||
|
||||
static void handle_pram_write_byte (void)
|
||||
|
@ -489,17 +489,22 @@ void init_via_state (uint8_t pram_data[256], shoebill_pram_callback_t callback,
|
|||
memcpy(pram->data, pram_data, 256);
|
||||
pram->callback = callback;
|
||||
pram->callback_param = callback_param;
|
||||
|
||||
/* -- Init clock stuff -- */
|
||||
const long double now = _now();
|
||||
shoe.via[0].t1_last_set = now;
|
||||
shoe.via[0].t2_last_set = now;
|
||||
shoe.via[1].t1_last_set = now;
|
||||
shoe.via[1].t2_last_set = now;
|
||||
}
|
||||
|
||||
#define E_CLOCK 783360
|
||||
#define HALF_E_CLOCK (E_CLOCK / 2)
|
||||
|
||||
#define _via_get_delta_counter(last_set) ({ \
|
||||
const long double delta_t = now - (last_set); \
|
||||
const long double delta_ticks = fmodl((delta_t * (long double)E_CLOCK), 0x10000); \
|
||||
const long double delta_ticks = fmodl((delta_t * (long double)E_CLOCK), 0x80000000); \
|
||||
/* The VIA timers decrement by 2 for every E_CLOCK tick */ \
|
||||
const uint16_t delta_counter = ((uint16_t)delta_ticks) << 1; \
|
||||
printf("_via_get_delta_counter: now = %Lf delta_t = %Lf delta_ticks = %Lf delta_counter = %u\n", now, delta_t, delta_ticks, delta_counter); \
|
||||
const uint32_t delta_counter = ((uint32_t)delta_ticks) << 1; \
|
||||
delta_counter; \
|
||||
})
|
||||
|
||||
|
@ -514,7 +519,7 @@ static uint8_t via_read_reg(const uint8_t vianum, const uint8_t reg, const long
|
|||
{
|
||||
via_state_t *via = &shoe.via[vianum - 1];
|
||||
|
||||
printf("via_reg_read: reading from via%u reg %s (%u)\n", vianum, via_reg_str[reg], reg);
|
||||
printf("via_reg_read: reading from via%u reg %s (%u) (shoe.pc = 0x%08x)\n", vianum, via_reg_str[reg], reg, shoe.pc);
|
||||
|
||||
switch (reg) {
|
||||
case VIA_ACR:
|
||||
|
@ -566,11 +571,11 @@ static uint8_t via_read_reg(const uint8_t vianum, const uint8_t reg, const long
|
|||
return via->ddra;
|
||||
|
||||
case VIA_T2C_HI: {
|
||||
const uint16_t counter = via->t2c - _via_get_delta_counter(via->t2_last_set);
|
||||
const uint16_t counter = via->t2c - (uint16_t)_via_get_delta_counter(via->t2_last_set);
|
||||
return counter >> 8;
|
||||
}
|
||||
case VIA_T2C_LO: {
|
||||
const uint16_t counter = via->t2c - _via_get_delta_counter(via->t2_last_set);
|
||||
const uint16_t counter = via->t2c - (uint16_t)_via_get_delta_counter(via->t2_last_set);
|
||||
via->ifr &= ~~VIA_IFR_T2; // Read from T2C_LOW clears TIMER 2 interrupt
|
||||
return (uint8_t)counter;
|
||||
}
|
||||
|
@ -595,7 +600,7 @@ static void via_write_reg(const uint8_t vianum, const uint8_t reg, const uint8_t
|
|||
{
|
||||
via_state_t *via = &shoe.via[vianum - 1];
|
||||
|
||||
printf("via_reg_write: writing 0x%02x to via%u reg %s (%u)\n", (uint8_t)shoe.physical_dat, vianum, via_reg_str[reg], reg);
|
||||
printf("via_reg_write: writing 0x%02x to via%u reg %s (%u) (pc=0x%08x)\n", data, vianum, via_reg_str[reg], reg, shoe.pc);
|
||||
|
||||
switch (reg) {
|
||||
case VIA_IER: {
|
||||
|
@ -670,6 +675,7 @@ static void via_write_reg(const uint8_t vianum, const uint8_t reg, const uint8_t
|
|||
case VIA_T2C_HI:
|
||||
via->ifr &= ~~VIA_IFR_T2; // Write to T2C_HI clears TIMER 2 interrupt
|
||||
via->t2_last_set = now;
|
||||
via->t2_interrupt_enabled = 1;
|
||||
break;
|
||||
|
||||
case VIA_T1C_LO:
|
||||
|
@ -692,6 +698,8 @@ void via_write_raw (void)
|
|||
const uint8_t vianum = ((shoe.physical_addr >> 13) & 1) + 1;
|
||||
const uint8_t reg = (shoe.physical_addr >> 9) & 15;
|
||||
|
||||
pthread_mutex_lock(&shoe.via_cpu_lock);
|
||||
|
||||
if (shoe.physical_size == 1) {
|
||||
const long double now = ((reg >= VIA_T1C_LO) && (reg <= VIA_T2C_HI)) ? _now() : 0.0;
|
||||
// Common case: writing to only one register
|
||||
|
@ -702,7 +710,7 @@ void via_write_raw (void)
|
|||
const long double now = ((reg >= VIA_T1C_LO) && ((reg+1) <= VIA_T2C_HI)) ? _now() : 0.0;
|
||||
// Uncommon case: writing to two registers simultaneously
|
||||
|
||||
printf("via_write_raw: writing to two registers simultaneously %u and %u\n", reg, reg+1);
|
||||
printf("via_write_raw: writing to two registers simultaneously %u and %u (0x%x)\n", reg, reg+1 , (uint32_t)shoe.physical_dat);
|
||||
|
||||
assert(reg != 15); // If A/UX is trying to write to two VIA chips simultanously, that's not cool
|
||||
|
||||
|
@ -712,6 +720,7 @@ void via_write_raw (void)
|
|||
else
|
||||
assert("Writing multiple bytes to the same VIA register!");
|
||||
|
||||
pthread_mutex_unlock(&shoe.via_cpu_lock);
|
||||
}
|
||||
|
||||
void via_read_raw (void)
|
||||
|
@ -719,6 +728,8 @@ void via_read_raw (void)
|
|||
const uint8_t vianum = ((shoe.physical_addr >> 13) & 1) + 1;
|
||||
const uint8_t reg = (shoe.physical_addr >> 9) & 15;
|
||||
|
||||
pthread_mutex_lock(&shoe.via_cpu_lock);
|
||||
|
||||
if (shoe.physical_size == 1) {
|
||||
const long double now = ((reg >= VIA_T1C_LO) && (reg <= VIA_T2C_HI)) ? _now() : 0.0;
|
||||
|
||||
|
@ -741,21 +752,28 @@ void via_read_raw (void)
|
|||
}
|
||||
else
|
||||
assert(!"Reading multiple bytes from the same VIA register!");
|
||||
|
||||
pthread_mutex_unlock(&shoe.via_cpu_lock);
|
||||
}
|
||||
|
||||
#define fire(s) ({assert((s) >= 0); if (earliest_next_timer > (s)) earliest_next_timer = (s);})
|
||||
void *via_clock_thread(void *arg)
|
||||
{
|
||||
pthread_mutex_lock(&shoe.via_clock_thread_lock);
|
||||
|
||||
const long double start_time = _now();
|
||||
// const long double multiplier = 1.0 / 60.0;
|
||||
const long double multiplier = 1.0;
|
||||
const long double start_time = multiplier * _now();
|
||||
uint64_t ca1_ticks = 0, ca2_ticks = 0;
|
||||
uint32_t i;
|
||||
|
||||
while (1) {
|
||||
const long double now = _now();
|
||||
pthread_mutex_lock(&shoe.via_cpu_lock);
|
||||
|
||||
const long double now = multiplier * _now();
|
||||
|
||||
long double earliest_next_timer = 1.0;
|
||||
const uint32_t via1_t2_delta = _via_get_delta_counter(shoe.via[0].t2_last_set);
|
||||
|
||||
|
||||
/*
|
||||
* Check whether the 60hz timer should fire (via1 CA1)
|
||||
|
@ -792,29 +810,18 @@ void *via_clock_thread(void *arg)
|
|||
via_raise_interrupt(2, IFR_TIMER2);*/
|
||||
}
|
||||
|
||||
/*
|
||||
// Check if any nubus cards have interrupt timers
|
||||
shoe.via[1].rega_input = 0b00111111;
|
||||
for (i=9; i<15; i++) {
|
||||
if (!shoe.slots[i].connected)
|
||||
continue;
|
||||
|
||||
if (now >= (shoe.slots[i].last_fired + (1.0L/shoe.slots[i].interrupt_rate))) {
|
||||
shoe.slots[i].last_fired = now;
|
||||
|
||||
fire(1.0L/shoe.slots[i].interrupt_rate);
|
||||
|
||||
if (shoe.slots[i].interrupts_enabled) {
|
||||
// shoe.via[1].rega = 0b00111111 & ~~(1<<(i-9));
|
||||
shoe.via[1].rega_input &= 0b00111111 & ~~(1<<(i-9));
|
||||
via_raise_interrupt(2, IFR_CA1);
|
||||
// printf("Fired nubus interrupt %u\n", i);
|
||||
}
|
||||
// I'm only checking VIA1 T2, since the time manager only seems to use/care about that timer
|
||||
if (shoe.via[0].t2_interrupt_enabled) {
|
||||
if (via1_t2_delta >= shoe.via[0].t2c) {
|
||||
shoe.via[0].t2_interrupt_enabled = 0;
|
||||
via_raise_interrupt(1, IFR_TIMER2);
|
||||
}
|
||||
else {
|
||||
fire((long double)(shoe.via[0].t2c - via1_t2_delta) / (E_CLOCK / 2.0));
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
|
||||
pthread_mutex_unlock(&shoe.via_cpu_lock);
|
||||
|
||||
usleep((useconds_t)(earliest_next_timer * 1000000.0L));
|
||||
|
||||
|
|
32
core/video.c
32
core/video.c
|
@ -78,10 +78,6 @@ uint32_t compute_nubus_crc(uint8_t *rom, uint32_t len)
|
|||
static void _switch_depth(shoebill_card_video_t *ctx, uint32_t depth)
|
||||
{
|
||||
ctx->depth = depth;
|
||||
if (depth > 8)
|
||||
ctx->cur_buf = (uint8_t*)ctx->direct_buf;
|
||||
else
|
||||
ctx->cur_buf = ctx->indexed_buf;
|
||||
}
|
||||
|
||||
void nubus_video_init(void *_ctx, uint8_t slotnum,
|
||||
|
@ -94,8 +90,8 @@ void nubus_video_init(void *_ctx, uint8_t slotnum,
|
|||
ctx->scanline_width = scanline_width;
|
||||
ctx->pixels = scanline_width * height;
|
||||
|
||||
ctx->direct_buf = p_alloc(shoe.pool, ctx->pixels * sizeof(video_ctx_color_t));
|
||||
ctx->indexed_buf = p_alloc(shoe.pool, ctx->pixels);
|
||||
ctx->direct_buf = p_alloc(shoe.pool, (ctx->pixels+4) * sizeof(video_ctx_color_t));
|
||||
ctx->temp_buf = p_alloc(shoe.pool, (ctx->pixels+4) * sizeof(video_ctx_color_t));
|
||||
|
||||
ctx->clut = p_alloc(shoe.pool, 256 * sizeof(video_ctx_color_t));
|
||||
ctx->rom = p_alloc(shoe.pool, 4096);
|
||||
|
@ -128,13 +124,13 @@ void nubus_video_init(void *_ctx, uint8_t slotnum,
|
|||
params[3].right = htons(width);
|
||||
params[3].bottom = htons(height);
|
||||
|
||||
/*params[4].line_width = htons(scanline_width * 2);
|
||||
params[4].line_width = htons(scanline_width * 2);
|
||||
params[4].right = htons(width);
|
||||
params[4].bottom = htons(height);
|
||||
|
||||
params[5].line_width = htons(scanline_width * 4);
|
||||
params[5].right = htons(width);
|
||||
params[5].bottom = htons(height);*/
|
||||
params[5].bottom = htons(height);
|
||||
|
||||
// Recompute the rom crc
|
||||
compute_nubus_crc(ctx->rom, 4096);
|
||||
|
@ -175,10 +171,10 @@ uint32_t nubus_video_read_func(const uint32_t rawaddr, const uint32_t size,
|
|||
|
||||
// Else, this is video ram
|
||||
|
||||
uint32_t i, myaddr = addr % ctx->pixels, result = 0;
|
||||
for (i=0; i<size; i++) {
|
||||
result <<= 8;
|
||||
result |= ctx->indexed_buf[(myaddr + i) % ctx->pixels];
|
||||
uint32_t i, result = 0;
|
||||
if (addr < (ctx->pixels * 4)) {
|
||||
for (i=0; i<size; i++)
|
||||
result = (result << 8) | ((uint8_t*)ctx->direct_buf)[addr + i];
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -272,13 +268,13 @@ void nubus_video_write_func(const uint32_t rawaddr, const uint32_t size,
|
|||
|
||||
// Else, this is video ram
|
||||
|
||||
uint32_t myaddr, mydata;
|
||||
for (myaddr = addr + size, mydata = data; addr < myaddr; ) {
|
||||
// assert(myaddr < ctx->pixels)
|
||||
ctx->indexed_buf[(--myaddr) % ctx->pixels] = mydata & 0xff;
|
||||
mydata >>= 8;
|
||||
if (addr < (ctx->pixels * 4)) {
|
||||
uint32_t mydata, myaddr;
|
||||
for (myaddr = addr + size, mydata = data; addr < myaddr; ) {
|
||||
((uint8_t*)ctx->direct_buf)[--myaddr] = mydata & 0xff;
|
||||
mydata >>= 8;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
Binary file not shown.
|
@ -22,97 +22,141 @@ uint8_t _video_rom[4096] = {
|
|||
0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x00,
|
||||
0x00, 0x04, 0x80, 0x00, 0x00, 0x00, 0x00, 0x08,
|
||||
0x00, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x0c, 0x80, 0x00, 0x00, 0x7e,
|
||||
0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x18,
|
||||
0x02, 0x00, 0x00, 0x1c, 0x20, 0x00, 0x00, 0x50,
|
||||
0x22, 0x00, 0x00, 0x2c, 0x24, 0x00, 0x00, 0x3e,
|
||||
0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x53, 0x68, 0x6f, 0x65,
|
||||
0x62, 0x69, 0x6c, 0x6c, 0x20, 0x50, 0x68, 0x6f,
|
||||
0x6e, 0x79, 0x20, 0x56, 0x69, 0x64, 0x65, 0x6f,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16,
|
||||
0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x00,
|
||||
0x0b, 0x40, 0x00, 0x00, 0x00, 0x00, 0x03, 0x84,
|
||||
0x05, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x04, 0x80, 0x00, 0x00, 0x04,
|
||||
0x80, 0x00, 0x00, 0x10, 0x00, 0x10, 0x00, 0x03,
|
||||
0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x16, 0x80,
|
||||
0x00, 0x00, 0x00, 0x00, 0x03, 0x84, 0x05, 0xa0,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x04, 0x80, 0x00, 0x00, 0x04, 0x80, 0x00,
|
||||
0x00, 0x10, 0x00, 0x20, 0x00, 0x03, 0x00, 0x08,
|
||||
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x10,
|
||||
0x80, 0x00, 0x01, 0x66, 0x81, 0x00, 0x01, 0x2e,
|
||||
0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1c,
|
||||
0x02, 0x00, 0x00, 0x20, 0x20, 0x00, 0x00, 0x50,
|
||||
0x22, 0x00, 0x00, 0x30, 0x24, 0x00, 0x00, 0xee,
|
||||
0x26, 0x00, 0x00, 0x3c, 0xff, 0x00, 0x00, 0x00,
|
||||
0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x53, 0x68, 0x6f, 0x65, 0x62, 0x69, 0x6c, 0x6c,
|
||||
0x20, 0x50, 0x68, 0x6f, 0x6e, 0x79, 0x20, 0x56,
|
||||
0x69, 0x64, 0x65, 0x6f, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x14, 0x02, 0x02, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x04, 0x31, 0x7c, 0x00, 0x01,
|
||||
0x00, 0x02, 0x4e, 0x75, 0x00, 0x00, 0x00, 0xae,
|
||||
0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
|
||||
0x31, 0x7c, 0x00, 0x01, 0x00, 0x02, 0x2a, 0x48,
|
||||
0x31, 0x7c, 0x00, 0x01, 0x00, 0x02, 0x10, 0x10,
|
||||
0x12, 0x00, 0x00, 0x01, 0x00, 0xf0, 0xe0, 0x99,
|
||||
0x22, 0x41, 0x9e, 0xfc, 0x00, 0x38, 0x20, 0x4f,
|
||||
0x11, 0x40, 0x00, 0x31, 0x42, 0x28, 0x00, 0x33,
|
||||
0x42, 0xa8, 0x00, 0x04, 0x20, 0x3c, 0x00, 0x00,
|
||||
0xa8, 0x9f, 0xa7, 0x46, 0x22, 0x08, 0x20, 0x3c,
|
||||
0x00, 0x00, 0xab, 0x03, 0xa7, 0x46, 0xb1, 0xc1,
|
||||
0x67, 0x62, 0x20, 0x4f, 0x42, 0x28, 0x00, 0x32,
|
||||
0x42, 0x28, 0x00, 0x30, 0x31, 0x7c, 0x00, 0x03,
|
||||
0x00, 0x28, 0x31, 0x7c, 0x00, 0x01, 0x00, 0x2a,
|
||||
0x31, 0x7c, 0x00, 0x01, 0x00, 0x2c, 0x31, 0x7c,
|
||||
0x54, 0x03, 0x00, 0x2e, 0x70, 0x15, 0xa0, 0x6e,
|
||||
0x3a, 0x28, 0x00, 0x26, 0x0c, 0x28, 0x00, 0x81,
|
||||
0x00, 0x32, 0x67, 0x00, 0x00, 0x30, 0x70, 0x31,
|
||||
0xa0, 0x6e, 0x11, 0x78, 0x00, 0x81, 0x00, 0x32,
|
||||
0x42, 0x68, 0x00, 0x26, 0x42, 0xa8, 0x00, 0x18,
|
||||
0x42, 0xa8, 0x00, 0x04, 0x70, 0x0a, 0xa0, 0x6e,
|
||||
0x59, 0x4f, 0xaa, 0x29, 0x20, 0x5f, 0x20, 0x50,
|
||||
0xba, 0x50, 0x66, 0x08, 0x20, 0x68, 0x00, 0x16,
|
||||
0x20, 0x50, 0x20, 0x89, 0x4f, 0xef, 0x00, 0x38,
|
||||
0x4e, 0x75, 0x01, 0x00, 0x00, 0x0c, 0x03, 0x00,
|
||||
0x00, 0x14, 0x04, 0x00, 0x00, 0x18, 0x53, 0x68,
|
||||
0x6f, 0x65, 0x62, 0x69, 0x6c, 0x6c, 0x00, 0x00,
|
||||
0x00, 0x00, 0x52, 0x65, 0x76, 0x2d, 0x31, 0x00,
|
||||
0x00, 0x00, 0x4d, 0x6f, 0x6f, 0x66, 0x00, 0x00,
|
||||
0x00, 0x00, 0x01, 0x00, 0x00, 0x9c, 0x02, 0x00,
|
||||
0x00, 0x78, 0x04, 0x00, 0x00, 0x9c, 0x08, 0x00,
|
||||
0x00, 0x01, 0x0c, 0x00, 0x00, 0x64, 0x0d, 0x00,
|
||||
0x00, 0x64, 0x80, 0x00, 0x00, 0x14, 0x81, 0x00,
|
||||
0x00, 0x20, 0x82, 0x00, 0x00, 0x2c, 0x83, 0x00,
|
||||
0x00, 0x38, 0xff, 0x00, 0x00, 0x00, 0x01, 0xff,
|
||||
0xfe, 0x9a, 0x03, 0x00, 0x00, 0x01, 0x04, 0x00,
|
||||
0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x01, 0xff,
|
||||
0xfe, 0xb8, 0x03, 0x00, 0x00, 0x01, 0x04, 0x00,
|
||||
0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x01, 0xff,
|
||||
0xfe, 0xd6, 0x03, 0x00, 0x00, 0x01, 0x04, 0x00,
|
||||
0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x01, 0xff,
|
||||
0xfe, 0xf4, 0x03, 0x00, 0x00, 0x01, 0x04, 0x00,
|
||||
0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x44, 0x69,
|
||||
0x73, 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x56, 0x69,
|
||||
0x64, 0x65, 0x6f, 0x5f, 0x41, 0x70, 0x70, 0x6c,
|
||||
0x65, 0x5f, 0x53, 0x68, 0x6f, 0x65, 0x62, 0x69,
|
||||
0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
|
||||
0x00, 0x01, 0x00, 0x01, 0x54, 0x03, 0x02, 0x00,
|
||||
0x00, 0x08, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x01, 0xa6, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x62,
|
||||
0x01, 0x62, 0x01, 0x70, 0x1d, 0x2e, 0x44, 0x69,
|
||||
0x73, 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x56, 0x69,
|
||||
0x64, 0x65, 0x6f, 0x5f, 0x41, 0x70, 0x70, 0x6c,
|
||||
0x65, 0x5f, 0x53, 0x68, 0x6f, 0x65, 0x62, 0x69,
|
||||
0x6c, 0x6c, 0x00, 0x00, 0x24, 0x48, 0x26, 0x49,
|
||||
0x70, 0x10, 0xa7, 0x1e, 0x66, 0x00, 0x01, 0x64,
|
||||
0x49, 0xfa, 0x01, 0x3e, 0x31, 0x7c, 0x00, 0x06,
|
||||
0x00, 0x04, 0x21, 0x4c, 0x00, 0x08, 0x21, 0x6b,
|
||||
0x00, 0x2a, 0x00, 0x0c, 0x70, 0x00, 0x10, 0x2b,
|
||||
0x00, 0x28, 0xa0, 0x75, 0x66, 0x00, 0x01, 0x44,
|
||||
0x70, 0x00, 0x4e, 0x75, 0x48, 0xe7, 0x7f, 0xfe,
|
||||
0x72, 0x00, 0x32, 0x28, 0x00, 0x1a, 0x24, 0x69,
|
||||
0x00, 0x2a, 0xd5, 0xfc, 0x00, 0xf0, 0x00, 0x00,
|
||||
0x26, 0x68, 0x00, 0x1c, 0x0c, 0x41, 0x00, 0x00,
|
||||
0x66, 0x00, 0x00, 0x16, 0x25, 0x78, 0x00, 0x80,
|
||||
0x00, 0x04, 0x25, 0x7c, 0x00, 0x00, 0x00, 0x01,
|
||||
0x00, 0x08, 0x70, 0x00, 0x60, 0x00, 0x00, 0xc8,
|
||||
0x0c, 0x41, 0x00, 0x01, 0x66, 0x00, 0x00, 0x08,
|
||||
0x70, 0x00, 0x60, 0x00, 0x00, 0xba, 0x0c, 0x41,
|
||||
0x00, 0x02, 0x66, 0x00, 0x00, 0x0c, 0x35, 0x53,
|
||||
0x00, 0x04, 0x70, 0x00, 0x60, 0x00, 0x00, 0xa8,
|
||||
0x0c, 0x41, 0x00, 0x03, 0x66, 0x00, 0x00, 0x4a,
|
||||
0x28, 0x53, 0x74, 0x00, 0x34, 0x2b, 0x00, 0x04,
|
||||
0x76, 0x00, 0x36, 0x2b, 0x00, 0x06, 0x0c, 0x42,
|
||||
0xff, 0xff, 0x66, 0x00, 0x00, 0x04, 0x4e, 0x70,
|
||||
0x28, 0x02, 0xe7, 0x8c, 0xd9, 0xc4, 0x52, 0x83,
|
||||
0x78, 0x00, 0x25, 0x42, 0x00, 0x0c, 0x35, 0x6c,
|
||||
0x00, 0x02, 0x00, 0x10, 0x35, 0x6c, 0x00, 0x04,
|
||||
0x00, 0x14, 0x35, 0x6c, 0x00, 0x06, 0x00, 0x18,
|
||||
0x52, 0x82, 0x50, 0x8c, 0x52, 0x84, 0xb6, 0x44,
|
||||
0x66, 0xe0, 0x70, 0xef, 0x60, 0x00, 0x00, 0x58,
|
||||
0x0c, 0x41, 0x00, 0x04, 0x66, 0x00, 0x00, 0x08,
|
||||
0x70, 0xef, 0x60, 0x00, 0x00, 0x4a, 0x0c, 0x41,
|
||||
0x00, 0x05, 0x66, 0x00, 0x00, 0x08, 0x70, 0xef,
|
||||
0x60, 0x00, 0x00, 0x3c, 0x0c, 0x41, 0x00, 0x06,
|
||||
0x00, 0x00, 0x01, 0x00, 0x00, 0xf0, 0x02, 0x00,
|
||||
0x00, 0xcc, 0x04, 0x00, 0x00, 0xf0, 0x08, 0x00,
|
||||
0x00, 0x01, 0x0c, 0x00, 0x00, 0xb8, 0x0d, 0x00,
|
||||
0x00, 0xb8, 0x80, 0x00, 0x00, 0x48, 0x81, 0x00,
|
||||
0x00, 0x54, 0x82, 0x00, 0x00, 0x60, 0x83, 0x00,
|
||||
0x00, 0x6c, 0x84, 0x00, 0x00, 0x78, 0x85, 0x00,
|
||||
0x00, 0x84, 0xff, 0x00, 0x00, 0x00, 0x01, 0x00,
|
||||
0x00, 0xbc, 0x02, 0x00, 0x00, 0x98, 0x04, 0x00,
|
||||
0x00, 0xbc, 0x08, 0x00, 0x00, 0x01, 0x0c, 0x00,
|
||||
0x00, 0x84, 0x0d, 0x00, 0x00, 0x84, 0x80, 0x00,
|
||||
0x00, 0x14, 0x81, 0x00, 0x00, 0x20, 0x82, 0x00,
|
||||
0x00, 0x2c, 0x83, 0x00, 0x00, 0x38, 0xff, 0x00,
|
||||
0x00, 0x00, 0x01, 0xff, 0xfd, 0x56, 0x03, 0x00,
|
||||
0x00, 0x01, 0x04, 0x00, 0x00, 0x00, 0xff, 0x00,
|
||||
0x00, 0x00, 0x01, 0xff, 0xfd, 0x74, 0x03, 0x00,
|
||||
0x00, 0x01, 0x04, 0x00, 0x00, 0x00, 0xff, 0x00,
|
||||
0x00, 0x00, 0x01, 0xff, 0xfd, 0x92, 0x03, 0x00,
|
||||
0x00, 0x01, 0x04, 0x00, 0x00, 0x00, 0xff, 0x00,
|
||||
0x00, 0x00, 0x01, 0xff, 0xfd, 0xb0, 0x03, 0x00,
|
||||
0x00, 0x01, 0x04, 0x00, 0x00, 0x00, 0xff, 0x00,
|
||||
0x00, 0x00, 0x01, 0xff, 0xfd, 0xce, 0x03, 0x00,
|
||||
0x00, 0x01, 0x04, 0x00, 0x00, 0x02, 0xff, 0x00,
|
||||
0x00, 0x00, 0x01, 0xff, 0xfd, 0xec, 0x03, 0x00,
|
||||
0x00, 0x01, 0x04, 0x00, 0x00, 0x02, 0xff, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
|
||||
0x00, 0x00, 0x44, 0x69, 0x73, 0x70, 0x6c, 0x61,
|
||||
0x79, 0x5f, 0x56, 0x69, 0x64, 0x65, 0x6f, 0x5f,
|
||||
0x41, 0x70, 0x70, 0x6c, 0x65, 0x5f, 0x53, 0x68,
|
||||
0x6f, 0x65, 0x62, 0x69, 0x6c, 0x6c, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x01,
|
||||
0x54, 0x03, 0x02, 0x00, 0x00, 0x08, 0xff, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x01, 0xa6, 0x4c, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32,
|
||||
0x00, 0x00, 0x00, 0x62, 0x01, 0x62, 0x01, 0x70,
|
||||
0x1d, 0x2e, 0x44, 0x69, 0x73, 0x70, 0x6c, 0x61,
|
||||
0x79, 0x5f, 0x56, 0x69, 0x64, 0x65, 0x6f, 0x5f,
|
||||
0x41, 0x70, 0x70, 0x6c, 0x65, 0x5f, 0x53, 0x68,
|
||||
0x6f, 0x65, 0x62, 0x69, 0x6c, 0x6c, 0x00, 0x00,
|
||||
0x24, 0x48, 0x26, 0x49, 0x70, 0x10, 0xa7, 0x1e,
|
||||
0x66, 0x00, 0x01, 0x64, 0x49, 0xfa, 0x01, 0x3e,
|
||||
0x31, 0x7c, 0x00, 0x06, 0x00, 0x04, 0x21, 0x4c,
|
||||
0x00, 0x08, 0x21, 0x6b, 0x00, 0x2a, 0x00, 0x0c,
|
||||
0x70, 0x00, 0x10, 0x2b, 0x00, 0x28, 0xa0, 0x75,
|
||||
0x66, 0x00, 0x01, 0x44, 0x70, 0x00, 0x4e, 0x75,
|
||||
0x48, 0xe7, 0x7f, 0xfe, 0x72, 0x00, 0x32, 0x28,
|
||||
0x00, 0x1a, 0x24, 0x69, 0x00, 0x2a, 0xd5, 0xfc,
|
||||
0x00, 0xf0, 0x00, 0x00, 0x26, 0x68, 0x00, 0x1c,
|
||||
0x0c, 0x41, 0x00, 0x00, 0x66, 0x00, 0x00, 0x16,
|
||||
0x25, 0x78, 0x00, 0x80, 0x00, 0x04, 0x25, 0x7c,
|
||||
0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x70, 0x00,
|
||||
0x60, 0x00, 0x00, 0xc8, 0x0c, 0x41, 0x00, 0x01,
|
||||
0x66, 0x00, 0x00, 0x08, 0x70, 0x00, 0x60, 0x00,
|
||||
0x00, 0xba, 0x0c, 0x41, 0x00, 0x02, 0x66, 0x00,
|
||||
0x00, 0x0c, 0x35, 0x53, 0x00, 0x04, 0x70, 0x00,
|
||||
0x60, 0x00, 0x00, 0xa8, 0x0c, 0x41, 0x00, 0x03,
|
||||
0x66, 0x00, 0x00, 0x4a, 0x28, 0x53, 0x74, 0x00,
|
||||
0x34, 0x2b, 0x00, 0x04, 0x76, 0x00, 0x36, 0x2b,
|
||||
0x00, 0x06, 0x0c, 0x42, 0xff, 0xff, 0x66, 0x00,
|
||||
0x00, 0x04, 0x4e, 0x70, 0x28, 0x02, 0xe7, 0x8c,
|
||||
0xd9, 0xc4, 0x52, 0x83, 0x78, 0x00, 0x25, 0x42,
|
||||
0x00, 0x0c, 0x35, 0x6c, 0x00, 0x02, 0x00, 0x10,
|
||||
0x35, 0x6c, 0x00, 0x04, 0x00, 0x14, 0x35, 0x6c,
|
||||
0x00, 0x06, 0x00, 0x18, 0x52, 0x82, 0x50, 0x8c,
|
||||
0x52, 0x84, 0xb6, 0x44, 0x66, 0xe0, 0x70, 0xef,
|
||||
0x60, 0x00, 0x00, 0x58, 0x0c, 0x41, 0x00, 0x04,
|
||||
0x66, 0x00, 0x00, 0x08, 0x70, 0xef, 0x60, 0x00,
|
||||
0x00, 0x2e, 0x0c, 0x41, 0x00, 0x07, 0x66, 0x00,
|
||||
0x00, 0x08, 0x70, 0xef, 0x60, 0x00, 0x00, 0x20,
|
||||
0x0c, 0x41, 0x00, 0x08, 0x66, 0x00, 0x00, 0x08,
|
||||
0x70, 0xef, 0x60, 0x00, 0x00, 0x12, 0x0c, 0x41,
|
||||
0x00, 0x09, 0x66, 0x00, 0x00, 0x08, 0x70, 0xef,
|
||||
0x60, 0x00, 0x00, 0x04, 0x70, 0xef, 0x4c, 0xdf,
|
||||
0x7f, 0xfe, 0x4e, 0x75, 0x26, 0x7c, 0xfa, 0x00,
|
||||
0xbe, 0xef, 0x26, 0xbc, 0xde, 0xad, 0xbe, 0xef,
|
||||
0x4e, 0x70, 0x26, 0x7c, 0xfa, 0x00, 0xbe, 0xef,
|
||||
0x26, 0xbc, 0xde, 0xad, 0xbe, 0xef, 0x4e, 0x70,
|
||||
0x20, 0x09, 0xe1, 0x98, 0x02, 0x80, 0x00, 0x00,
|
||||
0x00, 0x0f, 0x20, 0x49, 0xd1, 0xfc, 0x00, 0xf0,
|
||||
0x00, 0x00, 0x20, 0xbc, 0x00, 0x00, 0x00, 0x01,
|
||||
0x20, 0x78, 0x0d, 0x28, 0x4e, 0x90, 0x70, 0x01,
|
||||
0x4e, 0x75, 0x4e, 0x70, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x4a, 0x0c, 0x41, 0x00, 0x05, 0x66, 0x00,
|
||||
0x00, 0x08, 0x70, 0xef, 0x60, 0x00, 0x00, 0x3c,
|
||||
0x0c, 0x41, 0x00, 0x06, 0x66, 0x00, 0x00, 0x08,
|
||||
0x70, 0xef, 0x60, 0x00, 0x00, 0x2e, 0x0c, 0x41,
|
||||
0x00, 0x07, 0x66, 0x00, 0x00, 0x08, 0x70, 0xef,
|
||||
0x60, 0x00, 0x00, 0x20, 0x0c, 0x41, 0x00, 0x08,
|
||||
0x66, 0x00, 0x00, 0x08, 0x70, 0xef, 0x60, 0x00,
|
||||
0x00, 0x12, 0x0c, 0x41, 0x00, 0x09, 0x66, 0x00,
|
||||
0x00, 0x08, 0x70, 0xef, 0x60, 0x00, 0x00, 0x04,
|
||||
0x70, 0xef, 0x4c, 0xdf, 0x7f, 0xfe, 0x4e, 0x75,
|
||||
0x26, 0x7c, 0xfa, 0x00, 0xbe, 0xef, 0x26, 0xbc,
|
||||
0xde, 0xad, 0xbe, 0xef, 0x4e, 0x70, 0x26, 0x7c,
|
||||
0xfa, 0x00, 0xbe, 0xef, 0x26, 0xbc, 0xde, 0xad,
|
||||
0xbe, 0xef, 0x4e, 0x70, 0x20, 0x09, 0xe1, 0x98,
|
||||
0x02, 0x80, 0x00, 0x00, 0x00, 0x0f, 0x20, 0x49,
|
||||
0xd1, 0xfc, 0x00, 0xf0, 0x00, 0x00, 0x20, 0xbc,
|
||||
0x00, 0x00, 0x00, 0x01, 0x20, 0x78, 0x0d, 0x28,
|
||||
0x4e, 0x90, 0x70, 0x01, 0x4e, 0x75, 0x4e, 0x70,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
|
@ -464,50 +508,7 @@ uint8_t _video_rom[4096] = {
|
|||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf0, 0xcc,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf1, 0x28,
|
||||
0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x01, 0x01, 0x5a, 0x93, 0x2b, 0xc7, 0x00, 0xe1};
|
||||
0x01, 0x01, 0x5a, 0x93, 0x2b, 0xc7, 0x00, 0xe1
|
||||
};
|
||||
|
|
0
core/video_rom/shoebill_video.make
Normal file → Executable file
0
core/video_rom/shoebill_video.make
Normal file → Executable file
0
core/video_rom/shoebill_video_driver.a
Normal file → Executable file
0
core/video_rom/shoebill_video_driver.a
Normal file → Executable file
2
core/video_rom/shoebill_video_primary_init.a
Normal file → Executable file
2
core/video_rom/shoebill_video_primary_init.a
Normal file → Executable file
|
@ -1 +1 @@
|
|||
BLANKS ON
STRING ASIS
MACHINE MC68020
WITH seBlock
DC.B 2 ; Code revision
DC.B 2 ; 68020
DC.W 0 ; reserved
DC.L PrimaryInitStart-*
PrimaryInitStart
move.w #1, seStatus(a0) ; seStatus > 0 -> success
move.l a0, a5
rts
PrimaryInitEnd
|
||||
BLANKS ON
STRING ASIS
MACHINE MC68020
WITH seBlock
DC.B 2 ; Code revision
DC.B 2 ; 68020
DC.W 0 ; reserved
DC.L PrimaryInitStart-*
PrimaryInitStart
; Return "success"
move.w #1, seStatus(a0) ; seStatus > 0 -> success
; FIXME: Designing Cards and Drivers for the Macintosh Family says I should disable VBLs here...
; FIXME: Also gray out the screen
; Usually, we would check if 32bit QD exists
; If it doesn't, then we'd try to invalidate sResourceVideo_qd32
; unless the Mac II slot manager is loaded, in which case, we can't actually
; invalidate anything.
; Since Shoebill very likely won't support non-Mac II ROMs for a while,
; we have nothing to do
rts
PrimaryInitEnd
|
2
core/video_rom/shoebill_video_rom.a
Normal file → Executable file
2
core/video_rom/shoebill_video_rom.a
Normal file → Executable file
File diff suppressed because one or more lines are too long
1
core/video_rom/shoebill_video_secondary_init.a
Executable file
1
core/video_rom/shoebill_video_secondary_init.a
Executable file
|
@ -0,0 +1 @@
|
|||
BLANKS ON
STRING ASIS
MACHINE MC68020
WITH seBlock,spBlock
DC.B 2 ; Code revision
DC.B 2 ; 68020
DC.W 0 ; reserved
DC.L SecondaryInitStart-*
SecondaryInitStart
; Return "success"
move.w #1, seStatus(a0) ; seStatus > 0 -> success
; Figure out the slot base address (non-superslot)
move.b seSlot(a0), d0 ; -> d0.b = slotnum
move.b d0, d1
or.b #$F0, d1
ror.l #8, d1
move.l d1, a1 ; -> a1 = slot base addr
; Set up a slot parameter block
suba #spBlockSize, sp
move.l sp, a0
move.b d0, spSlot(a0)
clr.b spExtDev(a0)
clr.l spsPointer(a0)
; Verify that 32bit QD is loaded
move.l #$a89f, d0
_GetTrapAddress ,NewTool
move.l a0, d1
move.l #$ab03, d0
_GetTrapAddress ,NewTool
cmpa.l d1, a0
beq.s sec_done
; Find the current video sResource
move.l sp, a0
clr.b spID(a0) ; start at id=0
clr.b spTBMask(a0) ; match exactly
move.w #CatDisplay, spCategory(a0)
move.w #TypVideo, spCType(a0)
move.w #DrSwApple, spDrvrSW(a0)
move.w #DrHwShoe, spDrvrHW(a0)
_sNextTypesRsrc
move.w spRefNum(a0), d5
; If, somehow, the 32 bit video sResource is the only active one, then just return
cmp.b #CategoryVideo_qd32, spID(a0)
beq.w sec_done
; Otherwise, it's the non-32bit sResource - so nuke it
_sDeleteSRTRec
; And activate the 32bit sResource
move.b CategoryVideo_qd32, spID(a0)
clr.w spRefNum(a0) ; ?
clr.l spParamData(a0) ; clear for activation
clr.l spsPointer(a0) ; add back a sRsrc in directory
_InsertSRTRec
; If this is the boot screen, then update its gDevice
subq #4, sp ; make room for function return
_GetDeviceList ; get the boot gDevice
move.l (sp)+, a0 ; get the gdHandle
move.l (a0), a0 ; get pointer to gDevice
cmp.w gdRefNum(a0), d5 ; was this the boot device?
bne.s sec_done ; No? then return
move.l gdPMap(a0), a0 ; get pixMap handle
move.l (a0), a0 ; getpixMap ptr
move.l a1, pmBaseAddr(a0) ; save new base address
; FIXME: Wait, that wasn't necessary. All video modes have the same pmBaseAddr, I think
sec_done
adda #spBlockSize, sp
rts
SecondaryInitEnd
|
|
@ -42,6 +42,9 @@ struct dbg_state_t {
|
|||
uint64_t breakpoint_counter;
|
||||
dbg_breakpoint_t *breakpoints;
|
||||
_Bool trace;
|
||||
|
||||
char *ring;
|
||||
uint32_t ring_i, ring_len;
|
||||
|
||||
};
|
||||
|
||||
|
@ -369,6 +372,8 @@ void stepper()
|
|||
|
||||
cpu_step();
|
||||
|
||||
|
||||
|
||||
if (dbg_state.trace) {
|
||||
print_pc();
|
||||
printregs();
|
||||
|
@ -622,58 +627,10 @@ void timer_func (int arg)
|
|||
glutPostRedisplay();
|
||||
}
|
||||
|
||||
static void _do_clut_translation(shoebill_card_video_t *ctx)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
switch (ctx->depth) {
|
||||
case 1: {
|
||||
for (i=0; i < ctx->pixels/8; i++) {
|
||||
const uint8_t byte = ctx->indexed_buf[i];
|
||||
ctx->direct_buf[i * 8 + 0] = ctx->clut[(byte >> 7) & 1];
|
||||
ctx->direct_buf[i * 8 + 1] = ctx->clut[(byte >> 6) & 1];
|
||||
ctx->direct_buf[i * 8 + 2] = ctx->clut[(byte >> 5) & 1];
|
||||
ctx->direct_buf[i * 8 + 3] = ctx->clut[(byte >> 4) & 1];
|
||||
ctx->direct_buf[i * 8 + 4] = ctx->clut[(byte >> 3) & 1];
|
||||
ctx->direct_buf[i * 8 + 5] = ctx->clut[(byte >> 2) & 1];
|
||||
ctx->direct_buf[i * 8 + 6] = ctx->clut[(byte >> 1) & 1];
|
||||
ctx->direct_buf[i * 8 + 7] = ctx->clut[(byte >> 0) & 1];
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
for (i=0; i < ctx->pixels/4; i++) {
|
||||
const uint8_t byte = ctx->indexed_buf[i];
|
||||
ctx->direct_buf[i * 4 + 0] = ctx->clut[(byte >> 6) & 3];
|
||||
ctx->direct_buf[i * 4 + 1] = ctx->clut[(byte >> 4) & 3];
|
||||
ctx->direct_buf[i * 4 + 2] = ctx->clut[(byte >> 2) & 3];
|
||||
ctx->direct_buf[i * 4 + 3] = ctx->clut[(byte >> 0) & 3];
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 4: {
|
||||
for (i=0; i < ctx->pixels/2; i++) {
|
||||
const uint8_t byte = ctx->indexed_buf[i];
|
||||
ctx->direct_buf[i * 2 + 0] = ctx->clut[(byte >> 4) & 0xf];
|
||||
ctx->direct_buf[i * 2 + 1] = ctx->clut[(byte >> 0) & 0xf];
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 8:
|
||||
for (i=0; i < ctx->pixels; i++)
|
||||
ctx->direct_buf[i] = ctx->clut[ctx->indexed_buf[i]];
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(!"unknown depth");
|
||||
}
|
||||
}
|
||||
|
||||
void _display_func (void)
|
||||
{
|
||||
shoebill_card_video_t *video = (shoebill_card_video_t*)shoe.slots[9].ctx;
|
||||
|
||||
_do_clut_translation(video);
|
||||
shoebill_video_frame_info_t frame = shoebill_get_video_frame(9, 0);
|
||||
|
||||
shoebill_send_vbl_interrupt(9);
|
||||
|
||||
|
@ -682,18 +639,18 @@ void _display_func (void)
|
|||
|
||||
glClearColor(0.0, 0.0, 0.0, 0.0);
|
||||
|
||||
glViewport(0, 0, video->width, video->height);
|
||||
glRasterPos2i(0, video->height);
|
||||
glViewport(0, 0, frame.width, frame.height);
|
||||
glRasterPos2i(0, frame.height);
|
||||
glPixelStorei(GL_UNPACK_LSB_FIRST, GL_TRUE);
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
|
||||
glPixelZoom(1.0, -1.0);
|
||||
|
||||
glDrawPixels(video->width,
|
||||
video->height,
|
||||
glDrawPixels(frame.width,
|
||||
frame.height,
|
||||
GL_RGBA,
|
||||
GL_UNSIGNED_BYTE,
|
||||
video->direct_buf);
|
||||
frame.buf);
|
||||
|
||||
glutSwapBuffers();
|
||||
}
|
||||
|
@ -883,11 +840,16 @@ int main (int argc, char **argv)
|
|||
config.debug_mode = 1;
|
||||
|
||||
config.aux_verbose = 1;
|
||||
config.ram_size = 16 * 1024 * 1024;
|
||||
config.ram_size = 8 * 1024 * 1024;
|
||||
config.aux_kernel_path = "/unix";
|
||||
config.rom_path = "../priv/macii.rom";
|
||||
|
||||
config.scsi_devices[0].path = "../priv/Apple_UNIX_3.iso";
|
||||
config.scsi_devices[0].path = "../priv/aux_3.0.1.img";
|
||||
config.scsi_devices[1].path = "../priv/marathon.img";
|
||||
|
||||
/*dbg_state.ring_len = 256 * 1024 * 1024;
|
||||
dbg_state.ring = malloc(dbg_state.ring_len);
|
||||
dbg_state.ring_i = 0;*/
|
||||
|
||||
if (!shoebill_initialize(&config)) {
|
||||
printf("%s\n", config.error_msg);
|
||||
|
@ -898,8 +860,8 @@ int main (int argc, char **argv)
|
|||
|
||||
shoebill_install_video_card(&config,
|
||||
9, // slotnum
|
||||
1024,
|
||||
768,
|
||||
640, // 1024,
|
||||
480, // 768,
|
||||
60.0);
|
||||
|
||||
// Start the VIA timer thread
|
||||
|
|
Loading…
Reference in New Issue
Block a user