From 6773dd60200a7efc8585d2e0413cecd1f4b4fe63 Mon Sep 17 00:00:00 2001 From: Peter Rutenbar Date: Mon, 30 Jun 2014 16:50:38 -0400 Subject: [PATCH] Tweaks to SDL GUI, video driver, and FPU - Fewer FPU-related crashes - Fewer video driver-related crashes - Cleaned up the SDL GUI - Bumped up cocoa GUI to v0.0.4 --- core/Makefile | 2 +- core/core_api.c | 17 +- core/ethernet.c | 0 core/fpu.c | 205 ++++++++++-------- core/mem.c | 14 +- core/shoebill.h | 7 +- core/sound.c | 51 +++++ core/video.c | 78 ++++++- core/video_rom/rom.bin | Bin 4096 -> 4096 bytes core/video_rom/rom.c | 116 +++++----- core/video_rom/shoebill_video_driver.a | 2 +- .../video_rom/shoebill_video_secondary_init.a | 2 +- debugger/debugger.c | 11 +- gui/Shoebill/Shoebill-Info.plist | 4 +- gui/Shoebill/shoeApplication.m | 10 +- gui/Shoebill/shoeScreenView.xib | 2 +- sdl-gui/lin_build.sh | 2 +- sdl-gui/osx_build.sh | 22 ++ sdl-gui/sdl.c | 204 ++++++++++++++++- sdl-gui/win_build.bat | 2 +- 20 files changed, 572 insertions(+), 179 deletions(-) create mode 100644 core/ethernet.c create mode 100644 core/sound.c create mode 100755 sdl-gui/osx_build.sh diff --git a/core/Makefile b/core/Makefile index 9d5b7f5..c53f2d9 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 toby_frame_buffer +NEED_NOTHING = atrap_tab coff exception macii_symbols redblack scsi video filesystem alloc_pool toby_frame_buffer sound ethernet # 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 bed57ee..04d5bad 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[9] = 0x5; // Macintosh II video card has an auto_id of 5 (I guess?) + ki.auto_id[9] = 0x0050; // Macintosh II video card has an auto_id of 5 (I guess?) ki.auto_command = config->aux_autoconfig; // AUTO_NONE/AUTO_CONFIG @@ -967,6 +967,21 @@ void shoebill_send_vbl_interrupt(uint8_t slotnum) } } +void shoebill_validate_or_zap_pram(uint8_t *pram, _Bool forcezap) +{ + if (!forcezap) { + if (memcmp(pram + 0xc, "NuMc", 4) == 0) + return ; + } + + memset(pram, 0, 256); + memcpy(pram + 0xc, "NuMc", 4); // Mark PRAM as "valid" + + /* + * Set text box I-beam blink speed and mouse acceleration to something reasonable + */ + pram[9] = 0x88; +} void slog(const char *fmt, ...) { diff --git a/core/ethernet.c b/core/ethernet.c new file mode 100644 index 0000000..e69de29 diff --git a/core/fpu.c b/core/fpu.c index 6c8f74b..864c5ba 100644 --- a/core/fpu.c +++ b/core/fpu.c @@ -424,24 +424,41 @@ static void fpu_set_reg_cc(long double f, uint8_t r) fpu_set_cc(fpu_set_reg(f, r)); } -static long double fpu_bytes_to_long_double(uint8_t bytes[12]) +static void x87_to_motorola(long double x87, uint8_t motorola[12]) { - volatile long double f; - uint8_t *ptr = (uint8_t*)&f; + uint8_t *x87_ptr = (uint8_t*)&x87; + motorola[0] = x87_ptr[9]; + motorola[1] = x87_ptr[8]; + motorola[2] = 0; + motorola[3] = 0; + motorola[4] = x87_ptr[7]; + motorola[5] = x87_ptr[6]; + motorola[6] = x87_ptr[5]; + motorola[7] = x87_ptr[4]; + motorola[8] = x87_ptr[3]; + motorola[9] = x87_ptr[2]; + motorola[10] = x87_ptr[1]; + motorola[11] = x87_ptr[0]; +} + +static long double motorola_to_x87(const uint8_t motorola[12]) +{ + uint8_t x87[12]; - ptr[9] = bytes[0]; - ptr[8] = bytes[1]; + x87[11] = 0; + x87[10] = 0; + x87[9] = motorola[0]; + x87[8] = motorola[1]; - ptr[7] = bytes[4]; - ptr[6] = bytes[5]; - ptr[5] = bytes[6]; - ptr[4] = bytes[7]; - ptr[3] = bytes[8]; - ptr[2] = bytes[9]; - ptr[1] = bytes[10]; - ptr[0] = bytes[11]; - - return f; + x87[7] = motorola[4]; + x87[6] = motorola[5]; + x87[5] = motorola[6]; + x87[4] = motorola[7]; + x87[3] = motorola[8]; + x87[2] = motorola[9]; + x87[1] = motorola[10]; + x87[0] = motorola[11]; + return *(long double*)&x87[0]; } void inst_fmovecr(uint16_t op, uint16_t ext) @@ -476,7 +493,7 @@ void inst_fmovecr(uint16_t op, uint16_t ext) } // The constants in the 68881's ROM must be in the "intermediate" format, because they're rounded differently based on fpcr.rnd - const long double f = fpu_bytes_to_long_double(c->dat[shoe.fpcr.b.mc_rnd]); + const long double f = motorola_to_x87(c->dat[shoe.fpcr.b.mc_rnd]); fpu_set_reg_cc(f, r); @@ -707,43 +724,6 @@ void dis_fbcc(uint16_t op, uint16_t ext) sprintf(dis.str, "fb%s.%c *0x%08x", fpu_cc_names[c], "wl"[s], addr); } -static void x87_to_motorola(long double x87, uint8_t motorola[12]) -{ - uint8_t *x87_ptr = (uint8_t*)&x87; - motorola[0] = x87_ptr[9]; - motorola[1] = x87_ptr[8]; - motorola[2] = 0; - motorola[3] = 0; - motorola[4] = x87_ptr[7]; - motorola[5] = x87_ptr[6]; - motorola[6] = x87_ptr[5]; - motorola[7] = x87_ptr[4]; - motorola[8] = x87_ptr[3]; - motorola[9] = x87_ptr[2]; - motorola[10] = x87_ptr[1]; - motorola[11] = x87_ptr[0]; -} - -static long double motorola_to_x87(const uint8_t motorola[12]) -{ - uint8_t x87[12]; - - x87[11] = 0; - x87[10] = 0; - x87[9] = motorola[0]; - x87[8] = motorola[1]; - - x87[7] = motorola[4]; - x87[6] = motorola[5]; - x87[5] = motorola[6]; - x87[4] = motorola[7]; - x87[3] = motorola[8]; - x87[2] = motorola[9]; - x87[1] = motorola[10]; - x87[0] = motorola[11]; - return *(long double*)&x87[0]; -} - static void reverse_order(uint8_t *buf, const uint32_t size) { uint32_t i; @@ -1236,14 +1216,9 @@ void dis_fmove(uint16_t op, uint16_t ext) } -void dis_dyadic(uint16_t op, uint16_t ext) +void dis_fmath(uint16_t op, uint16_t ext) { - sprintf(dis.str, "dyadic fpu???"); -} - -void dis_monadic(uint16_t op, uint16_t ext) -{ - sprintf(dis.str, "monadic fpu??"); + sprintf(dis.str, "fmath ??"); } static void fpu_set_fpsr_quotient(long double a, long double b, long double result) @@ -1290,7 +1265,24 @@ void inst_fmath(uint16_t op, uint16_t ext) slog(" dest = fp%u = %Lf\n", dest_register, dest); switch (e) { - case ~b(0000001): assert(!"fpu_inst_fint;"); + case ~b(0000001): {// fpu_inst_fint + const uint8_t dir = shoe.fpcr.b.mc_rnd; + + // {FE_TONEAREST, FE_TOWARDZERO, FE_DOWNWARD, FE_UPWARD}; + + if (dir == 0) + result = roundl(source); + else if (dir == 1) + result = truncl(source); + else if (dir == 2) + result = floorl(source); + else + result = ceill(source); + + slog("inst_fint: source = %Lf result = %Lf round=%u\n", source, result, dir); + + break; + } case ~b(0000010): assert(!"fpu_inst_fsinh;"); case ~b(0000011): // fpu_inst_fintrz slog("inst_fintrz dest = %Lf source = %Lf\n", dest, source); @@ -1332,11 +1324,29 @@ void inst_fmath(uint16_t op, uint16_t ext) result = cosl(source); break; - case ~b(0011110): assert(!"fpu_inst_fgetexp;"); + case ~b(0011110): {// fpu_inst_fgetexp + if (!((source > 0) || (source < 0))) + result = source; // positive or negative zero + else if (!isfinite(source)) { + assert(!"fgetexp: isinfl(source)"); + // returns NAN and an exception bit - not implemented for the moment + } + else { + // Extract the debiased exponent from the 80-bit source + uint8_t motorola[12]; + x87_to_motorola(source, motorola); + int32_t exp = (motorola[0] & 0x7f) << 8; + exp |= motorola[1]; + exp -= 16383; // debias + result = exp; + } + break; + } case ~b(0011111): assert(!"fpu_inst_fgetman;"); case ~b(0100001): // don't forget to set fpu_set_fpsr_quotient(); assert(!"fpu_inst_fmod;"); + case ~b(0100100): assert(!"fpu_inst_fsgldiv;"); case ~b(0100101): { // fpu_inst_frem assert(source != 0.0); @@ -1354,12 +1364,20 @@ void inst_fmath(uint16_t op, uint16_t ext) do_write_back_result = 0; // don't write result back to register break; } - case ~b(0111010): assert(!"fpu_inst_ftst;"); + case ~b(0111010): { // fpu_inst_ftst + slog("fpu_inst_ftst: dest = %Lf\n"); + fpu_set_cc(source); + do_write_back_result = 0; // don't write result back to register + break; + } - case ~b(0011000): - case ~b(1011000): case ~b(1011100): - assert(!"fpu_inst_fabs;"); + case ~b(1011000): + assert(!"inst_fabs: can't handle"); + case ~b(0011000):// fpu_inst_fabs + result = fabsl(source); + slog("inst_fabs: source=%Lf result=%Lf\n", source, result); + break; case ~b(1100010): case ~b(1100110): @@ -1419,6 +1437,9 @@ void inst_fmath(uint16_t op, uint16_t ext) case ~b(0110000) ... ~b(0110111): assert(!"fpu_inst_fsincos;"); + + default: + assert(!"inst_fmath: unknown instruction"); } // Finalize the read, if source was in memory @@ -1467,36 +1488,48 @@ void fpu_setup_jump_table() fpu_inst_table[fpu_inst_fsave].emu = inst_fsave; fpu_inst_table[fpu_inst_fsave].dis = dis_fsave; - const fpu_inst_name_t monadic[] = { + const fpu_inst_name_t _fmath[] = { + fpu_inst_fsincos, + fpu_inst_fint, + fpu_inst_fsinh, fpu_inst_fintrz, - fpu_inst_fsqrt, fpu_inst_flognp1, - fpu_inst_fetox, - fpu_inst_fsin, - fpu_inst_fcos, - fpu_inst_fneg, + fpu_inst_fetoxm1, + fpu_inst_ftanh, fpu_inst_fatan, - }; - - const fpu_inst_name_t dyadic[] = { + fpu_inst_fatanh, + fpu_inst_fsin, + fpu_inst_ftan, + fpu_inst_fetox, + fpu_inst_ftwotox, + fpu_inst_ftentox, + fpu_inst_flogn, + fpu_inst_flog10, + fpu_inst_flog2, + fpu_inst_fcosh, + fpu_inst_facos, + fpu_inst_fcos, + fpu_inst_fgetexp, + fpu_inst_fgetman, + fpu_inst_fmod, + fpu_inst_fsgldiv, + fpu_inst_frem, + fpu_inst_fscale, fpu_inst_fcmp, + fpu_inst_ftst, + fpu_inst_fabs, fpu_inst_fadd, fpu_inst_fdiv, fpu_inst_fmul, - fpu_inst_fsub, - fpu_inst_frem, + fpu_inst_fneg, + fpu_inst_fsqrt, + fpu_inst_fsub }; - for (i=0; i < sizeof(monadic) / sizeof(monadic[0]); i++) { - fpu_inst_table[monadic[i]].emu = inst_fmath; - fpu_inst_table[monadic[i]].dis = dis_monadic; + for (i=0; i < sizeof(_fmath) / sizeof(fpu_inst_name_t); i++) { + fpu_inst_table[_fmath[i]].emu = inst_fmath; + fpu_inst_table[_fmath[i]].dis = dis_fmath; } - - for (i=0; i < sizeof(dyadic) / sizeof(dyadic[0]); i++) { - fpu_inst_table[dyadic[i]].emu = inst_fmath; - fpu_inst_table[dyadic[i]].dis = dis_dyadic; - } - } diff --git a/core/mem.c b/core/mem.c index 2d1514e..bd1d0ef 100644 --- a/core/mem.c +++ b/core/mem.c @@ -80,10 +80,11 @@ void _physical_get_io (void) shoe.physical_dat = scsi_dma_read(); return ; case 0x50014000 ... 0x50015fff: // Sound - //slog("physical_get: got read to sound\n"); - slog("soundsound read : register 0x%04x sz=%u\n", - shoe.physical_addr - 0x50014000, shoe.physical_size); - shoe.physical_dat = 0; + // slog("physical_get: got read to sound\n"); + shoe.physical_dat = sound_dma_read_raw(shoe.physical_addr - 0x50014000, shoe.physical_size); + // slog("soundsound read : register 0x%04x sz=%u\n", + //shoe.physical_addr - 0x50014000, shoe.physical_size); + // shoe.physical_dat = 0; return ; case 0x50016000 ... 0x50017fff: // SWIM (IWM?) // slog("physical_get: got read to IWM\n"); @@ -208,8 +209,9 @@ void _physical_set_io (void) scsi_dma_write(shoe.physical_dat); return ; case 0x50014000 ... 0x50015fff: // Sound - slog("soundsound write: register 0x%04x sz=%u dat=0x%x\n", - shoe.physical_addr - 0x50014000, shoe.physical_size, (uint32_t)shoe.physical_dat); + sound_dma_write_raw(shoe.physical_addr - 0x50014000, shoe.physical_size, shoe.physical_dat); + // slog("soundsound write: register 0x%04x sz=%u dat=0x%x\n", + // shoe.physical_addr - 0x50014000, shoe.physical_size, (uint32_t)shoe.physical_dat); // slog("physical_set: got write to sound\n"); return ; case 0x50016000 ... 0x50017fff: // SWIM (IWM?) diff --git a/core/shoebill.h b/core/shoebill.h index 28afc48..62d743c 100644 --- a/core/shoebill.h +++ b/core/shoebill.h @@ -139,6 +139,9 @@ shoebill_video_frame_info_t shoebill_get_video_frame(uint8_t slotnum, _Bool just /* Call this after rendering a video frame to send a VBL interrupt */ void shoebill_send_vbl_interrupt(uint8_t slotnum); +/* Call to validate input pram and zap if invalid */ +void shoebill_validate_or_zap_pram(uint8_t *pram, _Bool forcezap); + /* * These keyboard modifier constants match the ones used * in NSEvent shifted right by 16 bits. @@ -1021,6 +1024,8 @@ void nubus_video_write_func(const uint32_t rawaddr, const uint32_t size, shoebill_video_frame_info_t nubus_video_get_frame(shoebill_card_video_t *ctx, _Bool just_params); - +// Sound (Apple Sound Chip) +void sound_dma_write_raw(uint16_t addr, uint8_t sz, uint32_t data); +uint32_t sound_dma_read_raw(uint16_t addr, uint8_t sz); #endif // _SHOEBILL_H diff --git a/core/sound.c b/core/sound.c new file mode 100644 index 0000000..2b60ebe --- /dev/null +++ b/core/sound.c @@ -0,0 +1,51 @@ +#include +#include "../core/shoebill.h" + + +static uint8_t sound_dma_read_byte(uint16_t addr) +{ + if (addr == 0x804) + return 0xff; + return 0; +} + +static void sound_dma_write_byte(uint16_t addr, uint8_t data) +{ + if (addr >= 0x800) { + // registers + } + else if (addr >= 0x400) { + // Buf B + } + else { + // Buf A + /*FILE *f = fopen("buf_a.dmp", "ab"); + if (f) { + fwrite(&data, 1, 1, f); + fclose(f); + }*/ + } +} + + +void sound_dma_write_raw(uint16_t addr, uint8_t sz, uint32_t data) +{ + int32_t i; + slog("sound_dma_write: addr=0x%04x sz=%u dat=0x%x\n", addr, sz, data); + + for (i = (sz-1) * 8; i >= 0; i -= 8) + sound_dma_write_byte(addr, (data >> i) & 0xff); +} + +uint32_t sound_dma_read_raw(uint16_t addr, uint8_t sz) +{ + uint32_t i, result = 0; + slog("sound_dma_read: addr=0x%04x sz=%u\n", addr, sz); + + for (i=0; idepth <= 8) { + uint16_t pat; + uint8_t *ptr = ctx->direct_buf; + uint32_t width_bytes = (ctx->depth * ctx->scanline_width) / 8; + switch (ctx->depth) { + case 1: + pat = 0xaaaa; + break; + case 2: + pat = 0xcccc; + break; + case 4: + pat = 0xf0f0; + break; + case 8: + pat = 0x00ff; + break; + } + + for (h=0; hheight; h++) { + for (w=0; w < width_bytes; w++) + ptr[w] = pat >> ((w&1)*8); + ptr += width_bytes; + pat ^= 0xffff; + } + } + else if (ctx->depth == 16) { + const uint16_t fill_word = htons(0x4210); + uint16_t *ptr = (uint16_t*)ctx->direct_buf; + for (i=0; i < (ctx->width * ctx->height); i++) + ptr[i] = fill_word; + } + else if (ctx->depth == 32) { + const uint32_t fill_long = htonl(0x00808080); + uint32_t *ptr = (uint32_t*)ctx->direct_buf; + for (i=0; i < (ctx->width * ctx->height); i++) + ptr[i] = fill_long; + } + else + assert(!"unknown depth"); +} void nubus_video_write_func(const uint32_t rawaddr, const uint32_t size, const uint32_t data, const uint8_t slotnum) { shoebill_card_video_t *ctx = (shoebill_card_video_t*)shoe.slots[slotnum].ctx; const uint32_t addr = rawaddr & 0x00ffffff; + uint32_t i; // ROM and control registers if ((addr >> 20) == 0xf) { @@ -234,8 +279,10 @@ void nubus_video_write_func(const uint32_t rawaddr, const uint32_t size, slog("nubus_magic: set depth = %u\n", ctx->depth); break; } - case 2: { // Gray out screen - // FIXME: implement me + case 2: { // Gray out screen buffer + + _gray_page(ctx); + slog("nubus_magic: grey screen\n"); break; } @@ -260,6 +307,31 @@ void nubus_video_write_func(const uint32_t rawaddr, const uint32_t size, slog("nubus_magic: set %u.blue = 0x%04x\n", ctx->clut_idx, data); break; } + case 7: { // Set interrupts + shoe.slots[slotnum].interrupts_enabled = (data != 0); + slog("nubus_magic: interrupts_enabled = %u\n", + shoe.slots[slotnum].interrupts_enabled); + break; + } + case 8: { // Debug + slog("video_debug: 0x%08x\n", data); + break; + } + case 9: { // Gray out CLUT + if (!data) break; + for (i=0; i<256; i++) { + ctx->clut[i].r = 0x80; + ctx->clut[i].g = 0x80; + ctx->clut[i].b = 0x80; + } + break; + } + case 10: { // Use luminance (a.k.a. setGray) + slog("nubus_magic: use_luminance = %u\n", data); + // FIXME: not implemented + break; + } + } } diff --git a/core/video_rom/rom.bin b/core/video_rom/rom.bin index 11aeb921a6550b587bd4e21fba5e244f62a0a7fb..15a363c00a2766c7466f2003a376f44717235e91 100644 GIT binary patch delta 381 zcmZorXi(VT!z{w&#p1>^4_+auHW-|>&D;`G% z#xw>7jsk`R21Xqqj|s>V60KoiWKb~;W?%t}i%e!=@vaA|U^oI)!2(jDVY7jSfkD-U zL80J1P<#zgoE0c81{7z7h&!!>gE+>#{160llQ$FtxgN1^>U?zhGgQ1fKgK?n0 zLVtnaf;{xD? pP$+l@w1uVM9TqjB3_u^rsMah1D+DPhVDKy5e1@f!Yw}xuVE`>kTB`s6 delta 229 zcmZorXi(VT!z{wM%!dIAjDU0!V-jP*CooGhx=dcfY^KC;g2$18 zF^z$NqktiSfngVr#{}f@m z9y^?;0OWDNc|t%QC!EJp@ZRTs{Xf4_wVGcH``)YVxwm%Td%pryo&x9QEY@bO$qQKL JOn%ER3;?d`J_rB+ diff --git a/core/video_rom/rom.c b/core/video_rom/rom.c index 73026d2..4d75b99 100644 --- a/core/video_rom/rom.c +++ b/core/video_rom/rom.c @@ -1,4 +1,4 @@ -static uint8_t _video_rom[4096] = { +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, @@ -104,79 +104,79 @@ static uint8_t _video_rom[4096] = { 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, 0x02, 0x42, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, - 0x00, 0x00, 0x00, 0x62, 0x01, 0x62, 0x01, 0x70, + 0x00, 0x00, 0x00, 0x62, 0x01, 0xd4, 0x01, 0xf8, 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, + 0x66, 0x00, 0x02, 0x00, 0x49, 0xfa, 0x01, 0xda, 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, + 0x66, 0x00, 0x01, 0xe0, 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, + 0x60, 0x00, 0x01, 0x3a, 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, 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, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x2c, 0x0c, 0x41, 0x00, 0x02, 0x66, 0x00, + 0x00, 0x12, 0x15, 0x7c, 0x00, 0x01, 0x00, 0x24, + 0x35, 0x53, 0x00, 0x04, 0x70, 0x00, 0x60, 0x00, + 0x01, 0x14, 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, 0x00, 0x60, 0x00, + 0x00, 0xc4, 0x0c, 0x41, 0x00, 0x04, 0x66, 0x00, + 0x00, 0x12, 0x28, 0x3c, 0xb0, 0x04, 0x00, 0x00, + 0x25, 0x44, 0x00, 0x20, 0x70, 0xef, 0x60, 0x00, + 0x00, 0xac, 0x0c, 0x41, 0x00, 0x05, 0x66, 0x00, + 0x00, 0x16, 0x28, 0x3c, 0xb0, 0x05, 0x00, 0x00, + 0x25, 0x44, 0x00, 0x20, 0x42, 0xaa, 0x00, 0x08, + 0x70, 0x00, 0x60, 0x00, 0x00, 0x90, 0x0c, 0x41, + 0x00, 0x06, 0x66, 0x00, 0x00, 0x16, 0x28, 0x3c, + 0xb0, 0x06, 0x00, 0x00, 0x25, 0x44, 0x00, 0x20, + 0x15, 0x53, 0x00, 0x28, 0x70, 0x00, 0x60, 0x00, + 0x00, 0x74, 0x0c, 0x41, 0x00, 0x07, 0x66, 0x00, + 0x00, 0x1a, 0x28, 0x3c, 0xb0, 0x07, 0x00, 0x00, + 0x18, 0x13, 0x25, 0x44, 0x00, 0x20, 0x12, 0x13, + 0x15, 0x41, 0x00, 0x1c, 0x70, 0x00, 0x60, 0x00, + 0x00, 0x54, 0x0c, 0x41, 0x00, 0x08, 0x66, 0x00, + 0x00, 0x08, 0x70, 0xef, 0x60, 0x00, 0x00, 0x46, + 0x0c, 0x41, 0x00, 0x09, 0x66, 0x00, 0x00, 0x3c, + 0x28, 0x3c, 0xb0, 0x09, 0x00, 0x00, 0x18, 0x13, + 0x25, 0x44, 0x00, 0x20, 0x9e, 0xfc, 0x00, 0x38, + 0x20, 0x4f, 0x11, 0x69, 0x00, 0x28, 0x00, 0x31, + 0x42, 0x28, 0x00, 0x33, 0x51, 0x4f, 0x20, 0x8f, + 0x70, 0x11, 0xa0, 0x6e, 0x1f, 0x53, 0x00, 0x03, + 0x21, 0x4f, 0x00, 0x04, 0x70, 0x12, 0xa0, 0x6e, + 0x4f, 0xef, 0x00, 0x40, 0x70, 0x00, 0x60, 0x00, + 0x00, 0x04, 0x70, 0xef, 0x4c, 0xdf, 0x7f, 0xfe, + 0x4e, 0x75, 0x48, 0xe7, 0x7f, 0xfe, 0x24, 0x69, + 0x00, 0x2a, 0xd5, 0xfc, 0x00, 0xf0, 0x00, 0x00, + 0x25, 0x7c, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x20, + 0x70, 0xee, 0x60, 0x00, 0x00, 0x04, 0x70, 0xee, + 0x4c, 0xdf, 0x7f, 0xfe, 0x4e, 0x75, 0x48, 0xe7, + 0x7f, 0xfe, 0x24, 0x69, 0x00, 0x2a, 0xd5, 0xfc, + 0x00, 0xf0, 0x00, 0x00, 0x42, 0xaa, 0x00, 0x1c, + 0x25, 0x7c, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x20, + 0x4c, 0xdf, 0x7f, 0xfe, 0x70, 0x00, 0x4e, 0x75, + 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, 0x00, 0x00, 0x00, 0x00, diff --git a/core/video_rom/shoebill_video_driver.a b/core/video_rom/shoebill_video_driver.a index fa6ee9d..c070b78 100755 --- a/core/video_rom/shoebill_video_driver.a +++ b/core/video_rom/shoebill_video_driver.a @@ -1 +1 @@ - BLANKS ON STRING ASIS IMPORT test_func shoeClearInterrupt EQU 4*0 ; Write 1 to clear the via2 interrupt shoeSetMode EQU 4*1 ; write depth in bits shoeGrayScreen EQU 4*2 ; Gray out the screen buffer shoeSetClutIndex EQU 4*3 ; Set the index of the clut entry I'm about to modify shoeSetClutRed EQU 4*4 ; Set the red uint16_t for this clut entry shoeSetClutGreen EQU 4*5 ; green shoeSetClutBlue EQU 4*6 ; blue DriverStart DC.W $4C00 ; "ctl, status, needsLock" (what?) DC.W 0, 0, 0 ; "not an ornament" (??) DC.W VideoOpen-DriverStart DC.W 0 ; What does "prime" do? DC.W VideoCtl-DriverStart DC.W VideoStatus-DriverStart DC.W VideoClose-DriverStart STRING Pascal ; This needs to match the name in shoebill_video_rom.a DC.B '.Display_Video_Apple_Shoebill' STRING ASIS ALIGN 2 DC.W $0 ; Version number (overrides INIT if very high) VideoOpen move.l a0, a2 ; param block pointer move.l a1, a3 ; DCE pointer ; Allocate a slot queue element moveq.l #sqHDSize, d0 _NewPtr ,SYS,CLEAR bne Reset ; Install the interrupt handler lea InterruptHandler, a4 move.w #SIQType, SQType(a0) move.l a4, SQAddr(a0) move.l dctlDevBase(a3), SQParm(a0) moveq.l #0, d0 move.b dctlSlot(a3), d0 _SIntInstall bne Reset ; Return success moveq.l #0, d0 rts VideoCtl movem.l a0-a6/d1-d7, -(sp) moveq.l #0, d1 move.w csCode(a0), d1 move.l dCtlDevBase(a1), a2 add.l #$00F00000, a2 move.l csParam(a0), a3 ; a0 -> "IO parameter block" ; a1 -> DCE pointer ; a2 -> register base address ; a3 -> parameters ; d1 -> ctl code VideoCtl_reset cmp.w #0, d1 bne VideoCtl_killio move.l OneBitMode, shoeSetMode(a2) ; set to B&W move.l #1, shoeGrayScreen(a2) ; gray out the screen move.l #noErr, d0 ; success bra VideoCtl_rtn VideoCtl_killio cmp.w #1, d1 bne VideoCtl_setvidmode moveq.l #noErr, d0 ; no async IO on shoebill, so succeed bra VideoCtl_rtn VideoCtl_setvidmode cmp.w #2, d1 bne VideoCtl_setentries ; (it's okay to write bytes/words to these long register addresses) move.w csMode(a3), shoeSetMode(a2) moveq.l #noErr, d0 bra VideoCtl_rtn VideoCtl_setentries cmp.w #3, d1 bne VideoCtl_setgamma move.l (a3), a4 ; csTable moveq.l #0, d2 move.w 4(a3), d2 ; csStart moveq.l #0, d3 move.w 6(a3), d3 ; csCount cmp.w #$ffff, d2 bne cont reset cont: move.l d2, d4 lsl.l #3, d4 ; multiply csStart by 8, sizeof(ColorSpec)==8 add.l d4, a4 ; add (csStart*8) to csTable addq.l #1, d3 ; csCount is 0-based (why??) Make it 1-based moveq.l #0, d4 setentries_loop: move.l d2, shoeSetClutIndex(a2) ; communicate the clut entry index move.w 2(a4), shoeSetClutRed(a2) ; communicate the red component move.w 4(a4), shoeSetClutGreen(a2) move.w 6(a4), shoeSetClutBlue(a2) addq.l #1, d2 ; increment csStart addq.l #8, a4 ; increment csTable pointer addq.l #1, d4 ; increment loop counter cmp d4, d3 bne setentries_loop ; Not implemented moveq.l #controlErr, d0 bra VideoCtl_rtn VideoCtl_setgamma cmp.w #4, d1 bne VideoCtl_graypage ; Not implemented moveq.l #controlErr, d0 bra VideoCtl_rtn VideoCtl_graypage cmp.w #5, d1 bne VideoCtl_setgray ; Not implemented moveq.l #controlErr, d0 bra VideoCtl_rtn VideoCtl_setgray cmp.w #6, d1 bne VideoCtl_setinterrupt ; Not implemented moveq.l #controlErr, d0 bra VideoCtl_rtn VideoCtl_setinterrupt cmp.w #7, d1 bne VideoCtl_directsetentries ; Not implemented moveq.l #controlErr, d0 bra VideoCtl_rtn VideoCtl_directsetentries cmp.w #8, d1 bne VideoCtl_setdefault ; Not implemented moveq.l #controlErr, d0 bra VideoCtl_rtn VideoCtl_setdefault cmp.w #9, d1 bne VideoCtl_bogus ; Not implemented moveq.l #controlErr, d0 bra VideoCtl_rtn VideoCtl_bogus move.l #controlErr, d0; ; fall through VideoCtl_rtn movem.l (sp)+, a0-a6/d1-d7 rts ; ---- Video status ---- VideoStatus move.l #$fa00beef, a3 move.l #$deadbeef, (a3) reset VideoClose move.l #$fa00beef, a3 move.l #$deadbeef, (a3) reset InterruptHandler ; Compute the slot number given the base address in a1 move.l a1, d0 rol.l #8, d0 and.l #$0f, d0 ; Tell Shoebill to clear the interrupt flag move.l a1, a0 add.l #$00F00000, a0 ; the "clear interrupt" register move.l #1, (a0) ; Call JVBLTask (with d0 = slot number) move.l JVBLTask, a0 jsr (a0) ; Return success moveq.l #1, d0 rts Reset reset \ No newline at end of file + BLANKS ON STRING ASIS IMPORT test_func shoeClearInterrupt EQU 4*0 ; Write 1 to clear the via2 interrupt shoeSetMode EQU 4*1 ; write depth in bits shoeGrayPage EQU 4*2 ; Gray out the screen buffer shoeSetClutIndex EQU 4*3 ; Set the index of the clut entry I'm about to modify shoeSetClutRed EQU 4*4 ; Set the red uint16_t for this clut entry shoeSetClutGreen EQU 4*5 ; green shoeSetClutBlue EQU 4*6 ; blue shoeEnableInts EQU 4*7 ; Enable/disable interrupts shoeDebug EQU 4*8 ; Print out the long value written to this "register" shoeGrayCLUT EQU 4*9 ; Gray out the CLUT shoeUseLuminance EQU 4*10 ; "designing cards" calls this SetGray, but that's confusing DriverStart DC.W $4C00 ; "ctl, status, needsLock" (what?) DC.W 0, 0, 0 ; "not an ornament" (??) DC.W VideoOpen-DriverStart DC.W 0 ; What does "prime" do? DC.W VideoCtl-DriverStart DC.W VideoStatus-DriverStart DC.W VideoClose-DriverStart STRING Pascal ; This needs to match the name in shoebill_video_rom.a DC.B '.Display_Video_Apple_Shoebill' STRING ASIS ALIGN 2 DC.W $0 ; Version number (overrides INIT if very high) VideoOpen move.l a0, a2 ; param block pointer move.l a1, a3 ; DCE pointer ; Allocate a slot queue element moveq.l #sqHDSize, d0 _NewPtr ,SYS,CLEAR bne Reset ; Install the interrupt handler lea InterruptHandler, a4 move.w #SIQType, SQType(a0) move.l a4, SQAddr(a0) move.l dctlDevBase(a3), SQParm(a0) moveq.l #0, d0 move.b dctlSlot(a3), d0 _SIntInstall bne Reset ; Return success moveq.l #0, d0 rts VideoCtl movem.l a0-a6/d1-d7, -(sp) moveq.l #0, d1 move.w csCode(a0), d1 move.l dCtlDevBase(a1), a2 add.l #$00F00000, a2 move.l csParam(a0), a3 ; a0 -> "IO parameter block" ; a1 -> DCE pointer ; a2 -> register base address ; a3 -> parameters ; d1 -> ctl code VideoCtl_reset cmp.w #0, d1 bne VideoCtl_killio move.l OneBitMode, shoeSetMode(a2) ; set to B&W move.l #1, shoeGrayPage(a2) ; gray out the screen move.l #noErr, d0 ; success bra VideoCtl_rtn VideoCtl_killio cmp.w #1, d1 bne VideoCtl_setvidmode moveq.l #noErr, d0 ; no async IO on shoebill, so succeed bra VideoCtl_rtn VideoCtl_setvidmode cmp.w #2, d1 bne VideoCtl_setentries ; Gray out the CLUT move.b #1, shoeGrayCLUT(a2) ; (it's okay to write bytes/words to these long register addresses) move.w csMode(a3), shoeSetMode(a2) moveq.l #noErr, d0 bra VideoCtl_rtn VideoCtl_setentries cmp.w #3, d1 bne VideoCtl_setgamma move.l (a3), a4 ; csTable moveq.l #0, d2 move.w 4(a3), d2 ; csStart moveq.l #0, d3 move.w 6(a3), d3 ; csCount cmp.w #$ffff, d2 bne cont reset cont: move.l d2, d4 lsl.l #3, d4 ; multiply csStart by 8, sizeof(ColorSpec)==8 add.l d4, a4 ; add (csStart*8) to csTable addq.l #1, d3 ; csCount is 0-based (why??) Make it 1-based moveq.l #0, d4 setentries_loop: move.l d2, shoeSetClutIndex(a2) ; communicate the clut entry index move.w 2(a4), shoeSetClutRed(a2) ; communicate the red component move.w 4(a4), shoeSetClutGreen(a2) move.w 6(a4), shoeSetClutBlue(a2) addq.l #1, d2 ; increment csStart addq.l #8, a4 ; increment csTable pointer addq.l #1, d4 ; increment loop counter cmp d4, d3 bne setentries_loop moveq.l #noErr, d0 bra VideoCtl_rtn VideoCtl_setgamma cmp.w #4, d1 bne VideoCtl_graypage ; Debug-print setgamma move.l #$b0040000, d4 move.l d4, shoeDebug(a2) ; Not implemented moveq.l #controlErr, d0 bra VideoCtl_rtn VideoCtl_graypage cmp.w #5, d1 bne VideoCtl_setgray ; Debug-print graypage move.l #$b0050000, d4 move.l d4, shoeDebug(a2) move.l #0, shoeGrayPage(a2) moveq.l #noErr, d0 bra VideoCtl_rtn VideoCtl_setgray ; cmp.w #6, d1 bne VideoCtl_setinterrupt ; Debug-print setgray move.l #$b0060000, d4 move.l d4, shoeDebug(a2) move.b csMode(a3), shoeUseLuminance(a2) moveq.l #noErr, d0 bra VideoCtl_rtn VideoCtl_setinterrupt cmp.w #7, d1 bne VideoCtl_directsetentries ; Debug-print csMode(a3) move.l #$b0070000, d4 move.b csMode(a3), d4 move.l d4, shoeDebug(a2) move.b csMode(a3), d1 move.b d1, shoeEnableInts(a2) moveq.l #noErr, d0 bra VideoCtl_rtn VideoCtl_directsetentries cmp.w #8, d1 bne VideoCtl_setdefault ; Not implemented moveq.l #controlErr, d0 bra VideoCtl_rtn VideoCtl_setdefault ; setDefaultMode cmp.w #9, d1 bne VideoCtl_bogus ; Debug-print csMode(a3) move.l #$b0090000, d4 move.b csMode(a3), d4 move.l d4, shoeDebug(a2) suba #spBlockSize, sp ; allocate a slot parameter block move.l sp, a0 move.b dCtlSlot(a1), spSlot(a0) clr.b spExtDev(a0) suba #sizesPRAMRec, sp move.l sp,spResult(a0) _sReadPRAMRec ; read this slot's pram data ; copy the new default mode to VendorUse2 (byte idx 3) move.b csMode(a3), 3(sp) move.l sp, spsPointer(a0) _SPutPRAMRec ; write the new pram data adda #SizesPRAMRec+spBlockSize, SP moveq.l #noErr, d0 bra VideoCtl_rtn VideoCtl_bogus move.l #controlErr, d0; ; fall through VideoCtl_rtn movem.l (sp)+, a0-a6/d1-d7 rts ; ---- Video status ---- VideoStatus movem.l a0-a6/d1-d7, -(sp) move.l dCtlDevBase(a1), a2 add.l #$00F00000, a2 move.l #$e0000000, shoeDebug(a2) move.l #statusErr, d0 bra VideoStatus_rtn VideoStatus_bogus move.l #statusErr, d0 VideoStatus_rtn movem.l (sp)+, a0-a6/d1-d7 rts ; ---- Video close ---- VideoClose movem.l a0-a6/d1-d7, -(sp) move.l dCtlDevBase(a1), a2 add.l #$00F00000, a2 ; Nothing much to do except disable interrupts ; I don't think VideoClose is ever even called move.l #0, shoeEnableInts(a2) move.l #$a0000000, shoeDebug(a2) movem.l (sp)+, a0-a6/d1-d7 moveq.l #0, d0 rts ; --- Interrupt handler --- InterruptHandler ; Compute the slot number given the base address in a1 move.l a1, d0 rol.l #8, d0 and.l #$0f, d0 ; Tell Shoebill to clear the interrupt flag move.l a1, a0 add.l #$00F00000, a0 ; the "clear interrupt" register move.l #1, (a0) ; Call JVBLTask (with d0 = slot number) move.l JVBLTask, a0 jsr (a0) ; Return success moveq.l #1, d0 rts Reset reset \ No newline at end of file diff --git a/core/video_rom/shoebill_video_secondary_init.a b/core/video_rom/shoebill_video_secondary_init.a index a566481..2fe9936 100755 --- a/core/video_rom/shoebill_video_secondary_init.a +++ b/core/video_rom/shoebill_video_secondary_init.a @@ -1 +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 \ No newline at end of file + 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 ; Load our PRAM bytes, which contain the default depth ; suba.l #sizesPRAMRec, sp ; _sReadPRAMRec ; move.b VendorUse2(sp), spID(a0) ; adda.l #sizesPRAMRec, sp ; 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 \ No newline at end of file diff --git a/debugger/debugger.c b/debugger/debugger.c index 6af830e..80b3142 100644 --- a/debugger/debugger.c +++ b/debugger/debugger.c @@ -45,6 +45,8 @@ struct dbg_state_t { char *ring; uint32_t ring_i, ring_len; + + uint64_t op_count[0x10000]; }; @@ -842,7 +844,8 @@ int main (int argc, char **argv) config.aux_kernel_path = "/unix"; config.rom_path = "../priv/macii.rom"; - config.scsi_devices[0].path = "../priv/aux_beta_compacted.img"; + + config.scsi_devices[0].path = "../priv/aux3.0.1.img"; //config.scsi_devices[1].path = "../priv/marathon.img"; /*dbg_state.ring_len = 256 * 1024 * 1024; @@ -856,12 +859,10 @@ 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, - - shoebill_install_tfb_card(&config, 9); + 480); // 768, // Start the VIA timer thread shoebill_start(); diff --git a/gui/Shoebill/Shoebill-Info.plist b/gui/Shoebill/Shoebill-Info.plist index 7243666..7d161eb 100644 --- a/gui/Shoebill/Shoebill-Info.plist +++ b/gui/Shoebill/Shoebill-Info.plist @@ -17,11 +17,11 @@ CFBundlePackageType APPL CFBundleShortVersionString - 0.0.3 + 0.0.4 CFBundleSignature ???? CFBundleVersion - 0.0.3 + 0.0.4 LSMinimumSystemVersion ${MACOSX_DEPLOYMENT_TARGET} NSMainNibFile diff --git a/gui/Shoebill/shoeApplication.m b/gui/Shoebill/shoeApplication.m index 4ea1b45..dd6742d 100644 --- a/gui/Shoebill/shoeApplication.m +++ b/gui/Shoebill/shoeApplication.m @@ -301,15 +301,7 @@ { uint8_t init[256]; - memset(init, 0, 256); - - /* Mark PRAM as "valid" */ - memcpy(init+0xc, "NuMc", 4); - /* - * Set text box I-beam blink speed and mouse acceleration - * to something reasonable - */ - init[9] = 0x88; + shoebill_validate_or_zap_pram(init, 1); if (ptr) memcpy(ptr, init, 256); diff --git a/gui/Shoebill/shoeScreenView.xib b/gui/Shoebill/shoeScreenView.xib index 041bca9..e6aeb9e 100644 --- a/gui/Shoebill/shoeScreenView.xib +++ b/gui/Shoebill/shoeScreenView.xib @@ -13,7 +13,7 @@ - + diff --git a/sdl-gui/lin_build.sh b/sdl-gui/lin_build.sh index d515722..da2227c 100755 --- a/sdl-gui/lin_build.sh +++ b/sdl-gui/lin_build.sh @@ -8,7 +8,7 @@ for i in adb fpu mc68851 mem via floppy core_api cpu dis; do 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 +for i in atrap_tab coff exception macii_symbols redblack scsi video filesystem alloc_pool toby_frame_buffer ethernet sound; do files="$files ../core/$i.c" done diff --git a/sdl-gui/osx_build.sh b/sdl-gui/osx_build.sh new file mode 100755 index 0000000..16f14f3 --- /dev/null +++ b/sdl-gui/osx_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 ethernet sound; 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 -framework OpenGL -framework SDL2 -o shoebill" +echo $cmd +$cmd diff --git a/sdl-gui/sdl.c b/sdl-gui/sdl.c index ec97bc1..e8a8923 100644 --- a/sdl-gui/sdl.c +++ b/sdl-gui/sdl.c @@ -27,10 +27,17 @@ #include #include #include +#include +#include #include #include #include "../core/shoebill.h" +static void _print_vers(void) +{ + printf("Shoebill v0.0.4 - http://github.com/pruten/shoebill - Peter Rutenbar (c) 2014\n\n"); +} + rb_tree *keymap; static void _init_keyboard_map (void) { @@ -188,18 +195,114 @@ static void _display_frame (SDL_Window *win) SDL_GL_SwapWindow(win); } +struct shoe_app_pram_data_t { + uint8_t pram[256]; + FILE *f; + pthread_t threadid; + volatile _Bool updated, tear_down_thread; +}; + struct { const char *scsi_path[8]; const char *rom_path; const char *relative_unix_path; + const char *pram_path; uint32_t height, width; uint32_t ram_megabytes; _Bool verbose, use_tfb; + + struct shoe_app_pram_data_t pram_data; } user_params; #define equals_arg(name) keylen = strlen(name); value = argv[i]+keylen; if (strncmp((name), argv[i], keylen) == 0) +#if !((defined WIN32) || (defined _WIN64)) +#include +#include +#include +#endif + +static char* _get_home_dir (const char *terminal_element) +{ + char *result = NULL; + +#if (defined WIN32) || (defined _WIN64) + if (getenv("USERPROFILE") != NULL) { + result = malloc(strlen(getenv("USERPROFILE")) + strlen(terminal_element) + 32); + sprintf(result, "%s\\%s", getenv("USERPROFILE"), terminal_element); + goto done; + } + + if (getenv("HOMEDRIVE") && getenv("HOMEPATH")) { + result = malloc(strlen(getenv("HOMEDRIVE")) + strlen(getenv("HOMEPATH")) + strlen(terminal_element) + 32); + sprintf(result, "%s\\%s\\%s", getenv("HOMEDRIVE"), getenv("HOMEPATH"), terminal_element); + goto done; + } + +#else + + if (getenv("HOME") != NULL) { + result = malloc(strlen(getenv("HOME")) + strlen(terminal_element) + 32); + sprintf(result, "%s/%s", getenv("HOME"), terminal_element); + goto done; + } + + struct passwd *pwd = getpwuid(getuid()); + if (pwd) { + result = malloc(strlen(pwd->pw_dir) + strlen(terminal_element) + 32); + sprintf(result, "%s/%s", pwd->pw_dir, terminal_element); + goto done; + } + +#endif + +done: + + // printf("_get_home_dir: debug: %s\n", result); + + return result; +} + +static void _print_help (void) +{ + printf("Arguments have the form name=value.\n"); + printf("\n"); + printf("rom=\n"); + printf("Specifies the path to a Macintosh II ROM.\n"); + printf("E.g. rom=/home/foo/macii.rom\n"); + printf("\n"); + printf("disk0..disk6=\n"); + printf("Specifies the path to a disk image for the given SCSI ID. Shoebill will always boot from disk0, so make sure disk0 points to a bootable A/UX image.\n"); + printf("E.g. disk0=/home/foo/aux3.img disk1=/blah.img\n"); + printf("\n"); + printf("ram=\n"); + printf("E.g. ram=16\n"); + printf("\n"); + printf("height=\n"); + printf("Specifies the height of the screen in pixels.\n"); + printf("\n"); + printf("width=\n"); + printf("Specifies the width of the screen in pixels.\n"); + printf("\n"); + printf("pram-path=\n"); + printf("Defaults to ~/.shoebill_pram\n"); + printf("\n"); + printf("verbose=<1 or 0>\n"); + printf("Whether to boot A/UX in verbose mode. Best to leave it at default (1).\n"); + printf("\n"); + printf("unix-path=\n"); + printf("Path to the kernel file on the root disk image. Best to leave it at default (/unix).\n"); + printf("\n"); + printf("\n"); + printf("Examples:\n"); + printf("\n"); + printf("shoebill.exe disk0=C:\\aux3.img rom=C:\\macii.rom width=1024 height=768 ram=64\n"); + printf("\n"); + printf("./shoebill disk0=/aux3.img rom=/macii.rom width=1024 height=768 ram=64\n"); + printf("\n"); +} + static void _init_user_params (int argc, char **argv) { char *key; @@ -216,8 +319,26 @@ static void _init_user_params (int argc, char **argv) user_params.verbose = 1; user_params.use_tfb = 0; + user_params.pram_path = _get_home_dir(".shoebill_pram"); + + if (argc < 2) { + _print_help(); + exit(0); + } for (i=1; ipram[addr] = byte; + pram_data->updated = 1; +} + + +void* _pram_writer_thread (void *param) +{ + struct shoe_app_pram_data_t *pram_data = (struct shoe_app_pram_data_t*)param; + while (!pram_data->tear_down_thread) { + if (pram_data->updated) { + pram_data->updated = 0; + rewind(pram_data->f); + assert(fwrite(pram_data->pram, 256, 1, pram_data->f) == 1); + fflush(stdout); + pram_data->tear_down_thread = 0; + } + sleep(1); + } + + return NULL; +} + + static _Bool _setup_shoebill (void) { uint32_t i; @@ -282,6 +435,9 @@ static _Bool _setup_shoebill (void) config.ram_size = user_params.ram_megabytes * 1024 * 1024; config.aux_kernel_path = user_params.relative_unix_path; config.rom_path = user_params.rom_path; + config.pram_callback = _pram_callback; + config.pram_callback_param = (void*)&user_params.pram_data; + memcpy(config.pram, user_params.pram_data.pram, 256); for (i=0; i<7; i++) config.scsi_devices[i].path = user_params.scsi_path[i]; @@ -326,16 +482,54 @@ static void _handle_key_event (SDL_Event *event) } } +static _Bool _init_pram (void) +{ + FILE *f = fopen(user_params.pram_path, "r+b"); + memset(&user_params.pram_data, 0, sizeof(struct shoe_app_pram_data_t)); + + if ((f == NULL) || (fread(user_params.pram_data.pram, 256, 1, f) != 1)) { + if (f == NULL) + f = fopen(user_params.pram_path, "w+b"); + if (f == NULL) { + printf("Can't open pram_path! [%s] [errno=%s]\n", + user_params.pram_path, + sys_errlist[errno]); + return 0; + } + rewind(f); + shoebill_validate_or_zap_pram(user_params.pram_data.pram, 1); + + assert(fwrite(user_params.pram_data.pram, 256, 1, f) == 1); + fflush(f); + } + + user_params.pram_data.f = f; + shoebill_validate_or_zap_pram(user_params.pram_data.pram, 0); + + pthread_create(&user_params.pram_data.threadid, + NULL, + _pram_writer_thread, + &user_params.pram_data); + + return 1; +} + int main (int argc, char **argv) { const uint32_t frame_ticks = 1000 / 60; uint32_t last_frame_ticks; _Bool capture_cursor; + _print_vers(); + _init_keyboard_map(); _init_user_params(argc, argv); - if (!_setup_shoebill()) + if (!_init_pram()) return 0; + else if (!_setup_shoebill()) + return 0; + + shoebill_video_frame_info_t frame = shoebill_get_video_frame(9, 1); @@ -365,6 +559,8 @@ int main (int argc, char **argv) SDL_ShowCursor(0); SDL_SetRelativeMouseMode(1); + SDL_GL_SetSwapInterval(1); + last_frame_ticks = SDL_GetTicks(); while (1) { const uint32_t now = SDL_GetTicks(); @@ -384,7 +580,7 @@ int main (int argc, char **argv) switch (event.type) { case SDL_QUIT: - exit(0); + goto quit; case SDL_MOUSEBUTTONDOWN: { if ((event.button.button == SDL_BUTTON_LEFT) && capture_cursor) @@ -431,5 +627,9 @@ int main (int argc, char **argv) } } +quit: + + // FIXME: tear down the pram thread and flush pram + return 0; } diff --git a/sdl-gui/win_build.bat b/sdl-gui/win_build.bat index e05094d..4891afc 100755 --- a/sdl-gui/win_build.bat +++ b/sdl-gui/win_build.bat @@ -6,4 +6,4 @@ gcc -O1 ..\core\decoder_gen.c -o decoder_gen decoder_gen inst . decoder_gen dis . -gcc -O3 -flto -mno-ms-bitfields sdl.c adb.post.c fpu.post.c mc68851.post.c mem.post.c via.post.c floppy.post.c core_api.post.c cpu.post.c dis.post.c ..\core\atrap_tab.c ..\core\coff.c ..\core\exception.c ..\core\macii_symbols.c ..\core\redblack.c ..\core\scsi.c ..\core\video.c ..\core\filesystem.c ..\core\alloc_pool.c ..\core\toby_frame_buffer.c -lmingw32 -lopengl32 -lsdl2main -lsdl2 -o shoebill \ No newline at end of file +gcc -O3 -flto -mno-ms-bitfields sdl.c adb.post.c fpu.post.c mc68851.post.c mem.post.c via.post.c floppy.post.c core_api.post.c cpu.post.c dis.post.c ..\core\atrap_tab.c ..\core\coff.c ..\core\exception.c ..\core\macii_symbols.c ..\core\redblack.c ..\core\scsi.c ..\core\video.c ..\core\filesystem.c ..\core\alloc_pool.c ..\core\toby_frame_buffer.c ..\core\ethernet.c ..\core\sound.c -lmingw32 -lopengl32 -lsdl2main -lsdl2 -o shoebill \ No newline at end of file