From f051d425976555236de8e28c60d019e17c4393c7 Mon Sep 17 00:00:00 2001 From: Peter Rutenbar Date: Sun, 15 Jun 2014 16:41:06 -0400 Subject: [PATCH] Resuscitated the toby frame buffer - Integrated it into the SDL GUI (via the "toby" cli parameter) - It does not include the card ROM, so it will not run on A/UX 1, 2, or 3 --- README.md | 2 +- core/Makefile | 2 +- core/core_api.c | 111 ++++++------------------ core/shoebill.h | 32 +++---- core/toby_frame_buffer.c | 173 +++++++++++++++----------------------- core/video.c | 99 +++++++++++++++++++++- core/video_rom/rom.c | 2 +- core/video_rom/rom_to_c.c | 2 +- debugger/debugger.c | 20 +++-- sdl-gui/lin_build.sh | 22 +++++ sdl-gui/sdl.c | 23 +++-- sdl-gui/win_build.bat | 2 +- 12 files changed, 255 insertions(+), 235 deletions(-) create mode 100755 sdl-gui/lin_build.sh diff --git a/README.md b/README.md index 2eee03d..62dd390 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ A Macintosh II emulator that runs A/UX (and A/UX only). Shoebill is an all-new, BSD-licensed Macintosh II emulator designed from the ground up with the singular goal of running A/UX. -Shoebill requires a OS X, a Macintosh II, IIx or IIcx ROM, and a disk image with A/UX installed. +Shoebill requires OS X, a Macintosh II, IIx or IIcx ROM, and a disk image with A/UX installed. [Download the latest release], and then see the [getting started] wiki. Also check out [screenshots]. diff --git a/core/Makefile b/core/Makefile index ff0b688..9d5b7f5 100644 --- a/core/Makefile +++ b/core/Makefile @@ -7,7 +7,7 @@ CFLAGS = -O3 -ggdb -flto -Wno-deprecated-declarations DEPS = mc68851.h shoebill.h Makefile macro.pl NEED_DECODER = cpu dis NEED_PREPROCESSING = adb fpu mc68851 mem via floppy core_api -NEED_NOTHING = atrap_tab coff exception macii_symbols redblack scsi video filesystem alloc_pool +NEED_NOTHING = atrap_tab coff exception macii_symbols redblack scsi video filesystem alloc_pool toby_frame_buffer # Object files that can be compiled directly from the source OBJ_NEED_NOTHING = $(patsubst %,$(TEMP)/%.o,$(NEED_NOTHING)) diff --git a/core/core_api.c b/core/core_api.c index 1259da9..bed57ee 100644 --- a/core/core_api.c +++ b/core/core_api.c @@ -259,7 +259,7 @@ static void _init_kernel_info(shoebill_config_t *config, scsi_device_t *disks, u } // FIXME: I need to stick the auto_id for each nubus card in here - // ki.auto_id[0xb] = 0x5; // Macintosh II video card has an auto_id of 5 (I guess?) + // ki.auto_id[9] = 0x5; // Macintosh II video card has an auto_id of 5 (I guess?) ki.auto_command = config->aux_autoconfig; // AUTO_NONE/AUTO_CONFIG @@ -553,110 +553,49 @@ uint32_t shoebill_install_video_card(shoebill_config_t *config, uint8_t slotnum, return 1; } -static void _do_clut_translation(shoebill_card_video_t *ctx) +uint32_t shoebill_install_tfb_card(shoebill_config_t *config, uint8_t slotnum) { - uint32_t i; + shoebill_card_tfb_t *ctx; - switch (ctx->depth) { - case 1: { - for (i=0; i < ctx->pixels/8; i++) { - 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->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->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: { - for (i=0; i < ctx->pixels; 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(!"unsupported depth"); - + if (shoe.slots[slotnum].card_type != card_none) { + sprintf(config->error_msg, "This slot (%u) already has a card\n", slotnum); + return 0; } + + ctx = p_alloc(shoe.pool, sizeof(shoebill_card_tfb_t)); + shoe.slots[slotnum].ctx = ctx; + + shoe.slots[slotnum].card_type = card_toby_frame_buffer; + + shoe.slots[slotnum].connected = 1; + shoe.slots[slotnum].read_func = nubus_tfb_read_func; + shoe.slots[slotnum].write_func = nubus_tfb_write_func; + shoe.slots[slotnum].interrupts_enabled = 1; + nubus_tfb_init(ctx, slotnum); + return 1; } shoebill_video_frame_info_t shoebill_get_video_frame(uint8_t slotnum, _Bool just_params) { - shoebill_card_video_t *ctx = (shoebill_card_video_t*)shoe.slots[slotnum].ctx; shoebill_video_frame_info_t result; - assert(shoe.slots[slotnum].card_type == card_shoebill_video); // TBF not supported yet - if (!shoe.running) { memset(&result, 0, sizeof(result)); return result; } - result.width = ctx->width; - result.height = ctx->height; - result.scan_width = ctx->scanline_width; - result.depth = ctx->depth; + void *ctx = shoe.slots[slotnum].ctx; - // If caller just wants video parameters... - if (just_params) - return result; + if (shoe.slots[slotnum].card_type == card_toby_frame_buffer) + return nubus_tfb_get_frame(ctx, just_params); + else if (shoe.slots[slotnum].card_type == card_shoebill_video) + return nubus_video_get_frame(ctx, just_params); - _do_clut_translation(ctx); - result.buf = (uint8_t*)ctx->temp_buf; + assert(!"Unknown card type"); + memset(&result, 0, sizeof(result)); return result; - - } /* diff --git a/core/shoebill.h b/core/shoebill.h index 09317b5..28afc48 100644 --- a/core/shoebill.h +++ b/core/shoebill.h @@ -131,6 +131,8 @@ void shoebill_restart (void); uint32_t shoebill_install_video_card(shoebill_config_t *config, uint8_t slotnum, uint16_t width, uint16_t height); +uint32_t shoebill_install_tfb_card(shoebill_config_t *config, uint8_t slotnum); + /* Get a video frame from a particular video card */ shoebill_video_frame_info_t shoebill_get_video_frame(uint8_t slotnum, _Bool just_params); @@ -493,22 +495,6 @@ typedef struct { uint8_t changed; } mouse_state_t; -/*typedef struct { - uint8_t *buf_base; - uint32_t buf_size; - - uint32_t h_offset; // offset in bytes for each horizontal line - - uint8_t vsync; - - // unit8_t via_interrupt_flag; - - uint8_t depth; - uint8_t clut[256 * 3]; - uint32_t clut_idx; - -} video_state_t;*/ - typedef struct { // lsb==phase0, msb==L7 uint8_t latch; @@ -592,15 +578,15 @@ typedef struct { uint32_t pixels; - uint16_t width, height, scanline_width; + uint16_t width, height, scanline_width, line_offset; uint16_t depth, clut_idx; - - double refresh_rate; } shoebill_card_video_t; typedef struct { - uint8_t *frame_buffer; + uint8_t *direct_buf, *temp_buf, *clut, *rom; + uint16_t depth, clut_idx, line_offset; + uint8_t vsync; } shoebill_card_tfb_t; typedef struct { @@ -1018,9 +1004,11 @@ struct macii_rom_symbols_t { extern const struct macii_rom_symbols_t macii_rom_symbols[]; // Emulated Toby Frame Buffer nubus card -void nubus_tfb_init(uint8_t slotnum); +void nubus_tfb_init(void *_ctx, uint8_t slotnum); uint32_t nubus_tfb_read_func(uint32_t, uint32_t, uint8_t); void nubus_tfb_write_func(uint32_t, uint32_t, uint32_t, uint8_t); +shoebill_video_frame_info_t nubus_tfb_get_frame(shoebill_card_tfb_t *ctx, + _Bool just_params); // Shoebill Virtual Video Card void nubus_video_init(void *_ctx, uint8_t slotnum, @@ -1030,6 +1018,8 @@ uint32_t nubus_video_read_func(const uint32_t rawaddr, const uint32_t size, const uint8_t slotnum); void nubus_video_write_func(const uint32_t rawaddr, const uint32_t size, const uint32_t data, const uint8_t slotnum); +shoebill_video_frame_info_t nubus_video_get_frame(shoebill_card_video_t *ctx, + _Bool just_params); diff --git a/core/toby_frame_buffer.c b/core/toby_frame_buffer.c index d1dcfc1..4da2fc3 100644 --- a/core/toby_frame_buffer.c +++ b/core/toby_frame_buffer.c @@ -26,7 +26,6 @@ #include #include #include -#include #include "shoebill.h" #define ROM_SIZE 4096 @@ -41,45 +40,11 @@ uint8_t macii_video_rom[ROM_SIZE] = { */ }; -typedef struct { - uint8_t *buf_base; - uint32_t buf_size; - uint32_t clut_idx; - uint32_t h_offset; // offset in bytes for each horizontal line - uint8_t clut[256 * 3]; - uint8_t depth; - uint8_t vsync; - - uint8_t *gldat; -} tfb_ctx_t; - - -void nubus_tfb_display_func (void) +static void nubus_tfb_clut_translate(shoebill_card_tfb_t *ctx) { - uint32_t myw = glutGet(GLUT_WINDOW_WIDTH); - uint32_t myh = glutGet(GLUT_WINDOW_HEIGHT); - uint32_t slotnum, i; - int32_t my_window_id = glutGetWindow(); - - for (slotnum = 0; slotnum < 16; slotnum++) - if (shoe.slots[slotnum].glut_window_id == my_window_id) - break; - - tfb_ctx_t *ctx = (tfb_ctx_t*)shoe.slots[slotnum].ctx; - + uint32_t i, gli = 0; const uint8_t depth = ctx->depth; - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(0, myw, 0, myh, 0, 1); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - - glClear(GL_COLOR_BUFFER_BIT); - - glColor3f(0.1, 0.1, 0.8); - - uint32_t gli = 0; for (i=0; i < (1024 * 480);) { uint8_t code; @@ -91,87 +56,60 @@ void nubus_tfb_display_func (void) assert(gli < (640 * 480)); if (depth <= 1) { - code = (ctx->buf_base[ctx->h_offset + i/8] & (0x80 >> (i % 8))) != 0; + code = (ctx->direct_buf[ctx->line_offset + i/8] & (0x80 >> (i % 8))) != 0; code = (code << 7) | 0x7f; } else if (depth == 2) { - const uint8_t byte = ctx->buf_base[ctx->h_offset + i/4]; + const uint8_t byte = ctx->direct_buf[ctx->line_offset + i/4]; const uint8_t mod = i % 4; code = (byte << (mod * 2)) & 0xc0; code |= 0x3f; } else if (depth == 4) { - const uint8_t byte = ctx->buf_base[ctx->h_offset + i/2]; + const uint8_t byte = ctx->direct_buf[ctx->line_offset + i/2]; const uint8_t mod = i % 2; code = (byte << (mod * 4)) & 0xf0; code |= 0x0f; } else if (depth == 8) { - code = ctx->buf_base[ctx->h_offset + i]; + code = ctx->direct_buf[ctx->line_offset + i]; } - ctx->gldat[gli * 3 + 0] = ctx->clut[code * 3 + 2]; - ctx->gldat[gli * 3 + 1] = ctx->clut[code * 3 + 1]; - ctx->gldat[gli * 3 + 2] = ctx->clut[code * 3 + 0]; + ctx->temp_buf[gli * 4 + 0] = ctx->clut[code * 3 + 2]; + ctx->temp_buf[gli * 4 + 1] = ctx->clut[code * 3 + 1]; + ctx->temp_buf[gli * 4 + 2] = ctx->clut[code * 3 + 0]; gli++; i++; } - - glViewport(0, 0, myw, myh); - glRasterPos2i(0, myh); - glPixelStorei(GL_UNPACK_LSB_FIRST, GL_TRUE); - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - - glPixelZoom(1.0, -1.0); - - glDrawPixels(myw, myh, GL_RGB, GL_UNSIGNED_BYTE, ctx->gldat); - - glFlush(); } -void global_mouse_func (int button, int state, int x, int y); -void global_motion_func (int x, int y); -void global_passive_motion_func (int x, int y); -void global_keyboard_up_func (unsigned char c, int x, int y); -void global_keyboard_down_func (unsigned char c, int x, int y); -void global_special_up_func (int special, int x, int y); -void global_special_down_func (int special, int x, int y); - -void nubus_tfb_init(uint8_t slotnum) +void nubus_tfb_init(void *_ctx, uint8_t slotnum) { - tfb_ctx_t *ctx = (tfb_ctx_t*)calloc(sizeof(tfb_ctx_t), 1); + shoebill_card_tfb_t *ctx = (shoebill_card_tfb_t*)_ctx; + + ctx->direct_buf = p_alloc(shoe.pool, 512 * 1024 + 4); + ctx->temp_buf = p_alloc(shoe.pool, 640 * 480 * 4); + ctx->rom = p_alloc(shoe.pool, 4096); + ctx->clut = p_alloc(shoe.pool, 256 * 3); - ctx->buf_size = 512 * 1024; - ctx->buf_base = (uint8_t*)calloc(ctx->buf_size, 1); - ctx->depth = 1; ctx->clut_idx = 786; - ctx->gldat = valloc(480 * 640 * 3); + ctx->line_offset = 0; - memset(ctx->clut, 0x0, 384); - memset(ctx->clut+384, 0xff, 384); - memset(ctx->buf_base, 0xff, ctx->buf_size); + // memcpy(ctx->rom, macii_video_rom, 4096); + + // Offset to the TFB sResource + ctx->rom[4096 - 20] = 0; + ctx->rom[4096 - 19] = 0xff; + ctx->rom[4096 - 18] = 0xf0; + ctx->rom[4096 - 17] = 0x14; + + // Init CLUT to 1-bit depth + ctx->depth = 1; + memset(ctx->clut, 0x0, 3*128); + memset(ctx->clut + (3*128), 0xff, 3*128); shoe.slots[slotnum].ctx = ctx; - - glutInitWindowSize(640, 480); - shoe.slots[slotnum].glut_window_id = glutCreateWindow(""); - glutDisplayFunc(nubus_tfb_display_func); - - glutIgnoreKeyRepeat(1); - glutKeyboardFunc(global_keyboard_down_func); - glutKeyboardUpFunc(global_keyboard_up_func); - - glutSpecialFunc(global_special_down_func); - glutSpecialUpFunc(global_special_up_func); - - glutMouseFunc(global_mouse_func); - glutMotionFunc(global_motion_func); - glutPassiveMotionFunc(global_passive_motion_func); - - glShadeModel(GL_FLAT); - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - glClearColor(0.1, 1.0, 0.1, 1.0); } uint32_t nubus_tfb_read_func(const uint32_t rawaddr, const uint32_t size, const uint8_t slotnum) @@ -190,7 +128,8 @@ uint32_t nubus_tfb_read_func(const uint32_t rawaddr, const uint32_t size, const // 1101 // 1110 // 1111 = ROM (repeating 4kb images in S bits) - tfb_ctx_t *ctx = (tfb_ctx_t*)shoe.slots[slotnum].ctx; + //tfb_ctx_t *ctx = (tfb_ctx_t*)shoe.slots[slotnum].ctx; + shoebill_card_tfb_t *ctx = (shoebill_card_tfb_t*)shoe.slots[slotnum].ctx; const uint32_t addr = rawaddr & 0x000fffff; uint32_t result = 0; @@ -199,15 +138,15 @@ uint32_t nubus_tfb_read_func(const uint32_t rawaddr, const uint32_t size, const case 0x0 ... 0x7: { // frame buffer uint32_t i; for (i=0; ibuf_base[addr + i]; + result = (result << 8) | ctx->direct_buf[addr + i]; break; } case 0xf: { // rom if ((addr & 3) == 0) { const uint32_t rom_addr = (addr >> 2) % 4096; - result = macii_video_rom[rom_addr]; - slog("nubus_tfb_read_func: returning %x for addr %x (rom_addr=%x)\n", (uint32_t)result, shoe.physical_addr, rom_addr); + result = ctx->rom[rom_addr]; + slog("nubus_tfb_read_func: returning %x for addr %x (rom_addr=%x)\n", (uint32_t)result, rawaddr, rom_addr); } else result = 0; @@ -227,14 +166,14 @@ uint32_t nubus_tfb_read_func(const uint32_t rawaddr, const uint32_t size, const break; } else { - slog("nubus_tfb_read_func: unknown read of *0x%08x\n", shoe.physical_addr); + slog("nubus_tfb_read_func: unknown read of *0x%08x\n", rawaddr); result = 0; break; } } default: { - slog("nubus_tfb_read_func: unknown read of *0x%08x\n", shoe.physical_addr); + slog("nubus_tfb_read_func: unknown read of *0x%08x\n", rawaddr); result = 0; break; } @@ -246,7 +185,7 @@ uint32_t nubus_tfb_read_func(const uint32_t rawaddr, const uint32_t size, const void nubus_tfb_write_func(const uint32_t rawaddr, const uint32_t size, const uint32_t data, const uint8_t slotnum) { - tfb_ctx_t *ctx = (tfb_ctx_t*)shoe.slots[slotnum].ctx; + shoebill_card_tfb_t *ctx = (shoebill_card_tfb_t*)shoe.slots[slotnum].ctx; const uint32_t addr = rawaddr & 0x000fffff; switch (addr >> 16) { @@ -254,7 +193,7 @@ void nubus_tfb_write_func(const uint32_t rawaddr, const uint32_t size, case 0x0 ... 0x7: { // frame buffer uint32_t i; for (i=0; ibuf_base[addr + size - (i+1)] = (data >> (8*i)) & 0xFF; + ctx->direct_buf[addr + size - (i+1)] = (data >> (8*i)) & 0xFF; } return ; } @@ -277,19 +216,20 @@ void nubus_tfb_write_func(const uint32_t rawaddr, const uint32_t size, } if (addr == 0x8000c) { // horizontal offset - ctx->h_offset = 4 * ((~data) & 0xff); + ctx->line_offset = 4 * ((~data) & 0xff); return ; } else { - slog("video_nubus_set: unknown write to *0x%08x (0x%x)\n", shoe.physical_addr, data); + slog("video_nubus_set: unknown write to *0x%08x (0x%x)\n", rawaddr, data); return ; } } case 0x9: { // CLUT registers? if (addr == 0x90018) { // CLUT + uint8_t *clut = (uint8_t*)ctx->clut; slog("clut[0x%03x (0x%02x+%u)] = 0x%02x\n", ctx->clut_idx, ctx->clut_idx/3, ctx->clut_idx%3, (uint8_t)(data & 0xff)); - ctx->clut[ctx->clut_idx] = 255 - (data & 0xff); + clut[ctx->clut_idx] = 255 - (data & 0xff); ctx->clut_idx = (ctx->clut_idx == 0) ? 767 : ctx->clut_idx-1; @@ -302,20 +242,41 @@ void nubus_tfb_write_func(const uint32_t rawaddr, const uint32_t size, ctx->clut_idx = clut_dat * 3 + 2; } - slog("video_nubus_set: unknown write to *0x%08x (0x%x)\n", shoe.physical_addr, data); + slog("video_nubus_set: unknown write to *0x%08x (0x%x)\n", rawaddr, data); return ; } case 0xa: { // clear interrupt for slot 0xa(?) in via2.rega (by setting the appropriate bit) assert((data & 0xff) == 0); - // shoe.via[1].rega |= 0b00000010; - shoe.via[1].rega |= (1 << (slotnum - 9)); + shoe.via[1].rega_input |= (1 << (slotnum - 9)); return ; } default: { - slog("video_nubus_set: unknown write to *0x%08x (0x%x)\n", shoe.physical_addr, data); + slog("video_nubus_set: unknown write to *0x%08x (0x%x)\n", rawaddr, data); return ; } } } + +shoebill_video_frame_info_t nubus_tfb_get_frame(shoebill_card_tfb_t *ctx, + _Bool just_params) +{ + shoebill_video_frame_info_t result; + + result.width = 640; + result.height = 480; + result.scan_width = 640; + result.depth = ctx->depth; + + // If caller just wants video parameters... + if (just_params) + return result; + + nubus_tfb_clut_translate(ctx); + + result.buf = ctx->temp_buf; + return result; +} + + diff --git a/core/video.c b/core/video.c index 0fb92a4..a2c010e 100644 --- a/core/video.c +++ b/core/video.c @@ -54,7 +54,7 @@ typedef struct __attribute__ ((__packed__)) { uint32_t plane_bytes; } video_params_t; -uint32_t compute_nubus_crc(uint8_t *rom, uint32_t len) +static uint32_t compute_nubus_crc(uint8_t *rom, uint32_t len) { uint32_t i, sum = 0; @@ -88,6 +88,7 @@ void nubus_video_init(void *_ctx, uint8_t slotnum, ctx->height = height; ctx->scanline_width = scanline_width; ctx->pixels = scanline_width * height; + ctx->line_offset = 0; 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)); @@ -277,8 +278,100 @@ void nubus_video_write_func(const uint32_t rawaddr, const uint32_t size, } - - +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->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->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->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: { + for (i=0; i < ctx->pixels; 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(!"unsupported depth"); + + } +} + +shoebill_video_frame_info_t nubus_video_get_frame(shoebill_card_video_t *ctx, + _Bool just_params) +{ + shoebill_video_frame_info_t result; + + result.width = ctx->width; + result.height = ctx->height; + result.scan_width = ctx->scanline_width; + result.depth = ctx->depth; + + // If caller just wants video parameters... + if (just_params) + return result; + + _do_clut_translation(ctx); + result.buf = (uint8_t*)ctx->temp_buf; + return result; +} diff --git a/core/video_rom/rom.c b/core/video_rom/rom.c index e59fe28..73026d2 100644 --- a/core/video_rom/rom.c +++ b/core/video_rom/rom.c @@ -1,4 +1,4 @@ -uint8_t _video_rom[4096] = { +static uint8_t _video_rom[4096] = { 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, 0x00, 0x03, 0x84, 0x05, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, diff --git a/core/video_rom/rom_to_c.c b/core/video_rom/rom_to_c.c index 89f475f..f45600e 100644 --- a/core/video_rom/rom_to_c.c +++ b/core/video_rom/rom_to_c.c @@ -19,7 +19,7 @@ int main (int argc, char **argv) assert(fread(rom, 4096, 1, in) == 1); - fprintf(out, "uint8_t _video_rom[4096] = {\n\t"); + fprintf(out, "static uint8_t _video_rom[4096] = {\n\t"); for (i=0; i<4095; i++) { fprintf(out, "0x%02x, ", rom[i]); if ((i % 8) == 7) diff --git a/debugger/debugger.c b/debugger/debugger.c index a60e172..6af830e 100644 --- a/debugger/debugger.c +++ b/debugger/debugger.c @@ -784,9 +784,9 @@ static void _init_keyboard_map (void) static void _init_glut_video (void) { - shoebill_card_video_t *ctx = (shoebill_card_video_t*)shoe.slots[9].ctx; + shoebill_video_frame_info_t frame = shoebill_get_video_frame(9, 1); - glutInitWindowSize(ctx->width, ctx->height); + glutInitWindowSize(frame.width, frame.height); glutCreateWindow("Shoebill"); glutDisplayFunc(_display_func); glutIgnoreKeyRepeat(1); @@ -812,9 +812,9 @@ static void _init_glut_video (void) glLoadIdentity(); glMatrixMode(GL_PROJECTION); glLoadIdentity(); - glOrtho(0, ctx->width, 0, ctx->height, -1.0, 1.0); + glOrtho(0, frame.width, 0, frame.height, -1.0, 1.0); - glViewport(0, 0, ctx->width, ctx->height); + glViewport(0, 0, frame.width, frame.height); } @@ -838,12 +838,12 @@ int main (int argc, char **argv) config.debug_mode = 1; config.aux_verbose = 1; - config.ram_size = 8 * 1024 * 1024; + config.ram_size = 16 * 1024 * 1024; config.aux_kernel_path = "/unix"; config.rom_path = "../priv/macii.rom"; - config.scsi_devices[0].path = "../priv/aux_3.0.1.img"; - config.scsi_devices[1].path = "../priv/marathon.img"; + config.scsi_devices[0].path = "../priv/aux_beta_compacted.img"; + //config.scsi_devices[1].path = "../priv/marathon.img"; /*dbg_state.ring_len = 256 * 1024 * 1024; dbg_state.ring = malloc(dbg_state.ring_len); @@ -856,10 +856,12 @@ int main (int argc, char **argv) _init_keyboard_map(); - shoebill_install_video_card(&config, + /*shoebill_install_video_card(&config, 9, // slotnum 640, // 1024, - 480); // 768, + 480);*/ // 768, + + shoebill_install_tfb_card(&config, 9); // Start the VIA timer thread shoebill_start(); diff --git a/sdl-gui/lin_build.sh b/sdl-gui/lin_build.sh new file mode 100755 index 0000000..d515722 --- /dev/null +++ b/sdl-gui/lin_build.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +CC=gcc + +files="" +for i in adb fpu mc68851 mem via floppy core_api cpu dis; do + perl ../core/macro.pl ../core/$i.c $i.post.c + files="$files $i.post.c" +done + +for i in atrap_tab coff exception macii_symbols redblack scsi video filesystem alloc_pool toby_frame_buffer; do + files="$files ../core/$i.c" +done + +$CC -O1 ../core/decoder_gen.c -o decoder_gen +./decoder_gen inst . +./decoder_gen dis . + + +cmd="$CC -O3 -ggdb -flto $files sdl.c -lpthread -lm -lSDL2 -lGL -o shoebill" +echo $cmd +$cmd diff --git a/sdl-gui/sdl.c b/sdl-gui/sdl.c index 6d26054..ec97bc1 100644 --- a/sdl-gui/sdl.c +++ b/sdl-gui/sdl.c @@ -195,7 +195,7 @@ struct { uint32_t height, width; uint32_t ram_megabytes; - _Bool verbose; + _Bool verbose, use_tfb; } user_params; #define equals_arg(name) keylen = strlen(name); value = argv[i]+keylen; if (strncmp((name), argv[i], keylen) == 0) @@ -214,9 +214,16 @@ static void _init_user_params (int argc, char **argv) user_params.width = 800; user_params.ram_megabytes = 16; user_params.verbose = 1; + user_params.use_tfb = 0; for (i=1; i