From 4493a5bea7b19565e6fe392eaa356e20aef8bd81 Mon Sep 17 00:00:00 2001 From: Shamus Hammons Date: Fri, 11 Sep 2020 18:39:32 -0500 Subject: [PATCH] Add support for .hdv hard drive images, new "Rob Color TV" palette. --- src/fileio.cpp | 8 ++- src/fileio.h | 2 +- src/gui/diskselector.cpp | 4 +- src/harddrive.cpp | 32 ++++++++--- src/mmu.cpp | 2 +- src/v65c02.cpp | 6 +- src/video.cpp | 116 +++++++++++++++++++++++---------------- web/index.html | 1 + 8 files changed, 112 insertions(+), 59 deletions(-) diff --git a/src/fileio.cpp b/src/fileio.cpp index ccda0d7..cc2ef48 100644 --- a/src/fileio.cpp +++ b/src/fileio.cpp @@ -33,7 +33,7 @@ uint8_t standardTMAP[160] = { // // sizePtr is optional // -uint8_t * ReadFile(const char * filename, uint32_t * sizePtr/*= NULL*/) +uint8_t * ReadFile(const char * filename, uint32_t * sizePtr/*= NULL*/, uint32_t skip/*= 0*/) { FILE * fp = fopen(filename, "rb"); @@ -44,6 +44,12 @@ uint8_t * ReadFile(const char * filename, uint32_t * sizePtr/*= NULL*/) uint32_t size = ftell(fp); fseek(fp, 0, SEEK_SET); + if (skip > 0) + { + fseek(fp, skip, SEEK_CUR); + size -= skip; + } + uint8_t * buffer = (uint8_t *)malloc(size); fread(buffer, 1, size, fp); fclose(fp); diff --git a/src/fileio.h b/src/fileio.h index e7a15bc..1ab5b0f 100644 --- a/src/fileio.h +++ b/src/fileio.h @@ -99,7 +99,7 @@ struct WOZ2 }; // Exported functions -uint8_t * ReadFile(const char * filename, uint32_t * sizePtr = NULL); +uint8_t * ReadFile(const char * filename, uint32_t * sizePtr = NULL, uint32_t skip = 0); void InitWOZ2Headers(WOZ2 &); uint8_t * InitWOZ(uint32_t * pSize = NULL); uint8_t * UpconvertWOZ1ToWOZ2(uint8_t * woz1Data, uint32_t woz1Size, uint32_t * newSize); diff --git a/src/gui/diskselector.cpp b/src/gui/diskselector.cpp index ac3ec44..57014b5 100644 --- a/src/gui/diskselector.cpp +++ b/src/gui/diskselector.cpp @@ -401,7 +401,9 @@ void DiskSelector::FindHardDisks(const char * path) { const char * ext = strrchr(ent->d_name, '.'); - if ((ext != NULL) && (strcasecmp(ext, ".2mg") == 0)) + if ((ext != NULL) + && ((strcasecmp(ext, ".2mg") == 0) + || (strcasecmp(ext, ".hdv") == 0))) { FileStruct fs; fs.image = ent->d_name; diff --git a/src/harddrive.cpp b/src/harddrive.cpp index 66a750e..e0fae03 100644 --- a/src/harddrive.cpp +++ b/src/harddrive.cpp @@ -222,7 +222,7 @@ static void RunDevice(void) SetNextState(DVM_DATA_IN); bytesToSend = cmd[4] * 512; // amount is set in blocks uint32_t lba = ((cmd[1] & 0x1F) << 16) | (cmd[2] << 8) | cmd[3]; - buf = (hdData != NULL ? &hdData[(lba * 512) + 0x40] : NULL); + buf = (hdData != NULL ? &hdData[lba * 512] : NULL); bufPtr = 0; } // Handle "Inquire" command @@ -280,7 +280,7 @@ static void RunDevice(void) SetNextState(DVM_DATA_IN); bytesToSend = ((cmd[7] << 8) | cmd[8]) * 512; // amount is set in blocks uint32_t lba = (cmd[2] << 24) | (cmd[3] << 16) | (cmd[4] << 8) | cmd[5]; - buf = (hdData != NULL ? &hdData[(lba * 512) + 0x40] : NULL); + buf = (hdData != NULL ? &hdData[lba * 512] : NULL); bufPtr = 0; } // Handle "Write" (10) command @@ -291,7 +291,7 @@ static void RunDevice(void) SetNextState(DVM_DATA_OUT); bytesToSend = ((cmd[7] << 8) | cmd[8]) * 512; // amount is set in blocks uint32_t lba = (cmd[2] << 24) | (cmd[3] << 16) | (cmd[4] << 8) | cmd[5]; - buf = (hdData != NULL ? &hdData[(lba * 512) + 0x40] : NULL); + buf = (hdData != NULL ? &hdData[lba * 512] : NULL); bufPtr = 0; } else @@ -621,13 +621,31 @@ void InstallHardDrive(uint8_t slot) char fnBuf[MAX_PATH + 1]; // If this fails to read the file, the pointer is set to NULL - uint32_t size = 0; + uint32_t size = 0, skip = (uint32_t)-1; sprintf(fnBuf, "%s%s", settings.disksPath, settings.hd[0]); - hdData = ReadFile(fnBuf, &size); + + // Check to see which type of HD image we have... + char * ext = strrchr(settings.hd[0], '.'); + + if (ext != NULL) + { + if (strcasecmp(ext, ".2mg") == 0) + skip = 0x40; + else if (strcasecmp(ext, ".hdv") == 0) + skip = 0; + } + + if (skip == (uint32_t)-1) + { + hdData = NULL; + WriteLog("HD: Unknown HD image file: %s\n", settings.hd[0]); + return; + } + + hdData = ReadFile(fnBuf, &size, skip); if (hdData) - WriteLog("HD: Read Hard Drive image file '%s', %u bytes ($%X)\n", settings.hd[0], size - 0x40, size - 0x40); + WriteLog("HD: Read Hard Drive image file '%s', %u bytes ($%X)\n", settings.hd[0], size, size); else WriteLog("HD: Could not read Hard Drive image file!\n"); } - diff --git a/src/mmu.cpp b/src/mmu.cpp index c1ca98a..dc5e57c 100644 --- a/src/mmu.cpp +++ b/src/mmu.cpp @@ -362,7 +362,7 @@ void InstallSlotHandler(uint8_t slot, SlotData * slotData) // Sanity check if (slot > 7) { - WriteLog("InstallSlotHanlder: Caller attempted to put device into slot #%u...\n", slot); + WriteLog("InstallSlotHandler: Caller attempted to put device into slot #%u...\n", slot); return; } diff --git a/src/v65c02.cpp b/src/v65c02.cpp index 05acaed..f0a589d 100644 --- a/src/v65c02.cpp +++ b/src/v65c02.cpp @@ -2301,9 +2301,11 @@ void Execute65C02(V65C02REGS * context, uint32_t cycles) #if 0 if (first && (regs->pc == 0x801)) { - regs->WrMem(0x42, 1); - regs->WrMem(0x44, 0); +// regs->WrMem(0x42, 1); // v3.0 does this now... + regs->WrMem(0x44, 0); // who writes non-zero to here??? (AHSSC does) first = false; +// dumpDis = true; +//WriteLog("V65C02: Executing $801...\n"); } else if (regs->pc == 0x869) { diff --git a/src/video.cpp b/src/video.cpp index c9c0173..cc5805c 100644 --- a/src/video.cpp +++ b/src/video.cpp @@ -85,7 +85,7 @@ static bool showFrameTicks = false; // We set up the colors this way so that they'll be endian safe // when we cast them to a uint32_t. Note that the format is RGBA. -// "Master Color Values" palette +// "Master Color Values" palette (ugly, Apple engineer hand-picked colors) static uint8_t colors[16 * 4] = { 0x00, 0x00, 0x00, 0xFF, // Black @@ -126,6 +126,69 @@ static uint8_t altColors[16 * 4] = { 0x7D, 0xDB, 0xBA, 0xFF, 0xFB, 0xFB, 0xFB, 0xFF }; +// This color palette comes from xapple2 (looks a bit shit to me :-) +// I've included it to have yet another point of comparison to the execrable +// "Master Color Values" palette. +/* + * https://mrob.com/pub/xapple2/colors.html + * detailed research into accurate colors + --chroma-- + Color name phase ampl luma -R- -G- -B- + black COLOR=0 0 0 0 0 0 0 + gray COLOR=5 0 0 50 156 156 156 + grey COLOR=10 0 0 50 156 156 156 + white COLOR=15 0 0 100 255 255 255 + dk blue COLOR=2 0 60 25 96 78 189 + lt blue COLOR=7 0 60 75 208 195 255 + purple COLOR=3 45 100 50 255 68 253 + purple HCOLOR=2 45 100 50 255 68 253 + red COLOR=1 90 60 25 227 30 96 + pink COLOR=11 90 60 75 255 160 208 + orange COLOR=9 135 100 50 255 106 60 + orange HCOLOR=5 135 100 50 255 106 60 + brown COLOR=8 180 60 25 96 114 3 + yellow COLOR=13 180 60 75 208 221 141 + lt green COLOR=12 225 100 50 20 245 60 + green HCOLOR=1 225 100 50 20 245 60 + dk green COLOR=4 270 60 25 0 163 96 + aqua COLOR=14 270 60 75 114 255 208 + med blue COLOR=6 315 100 50 20 207 253 + blue HCOLOR=6 315 100 50 20 207 253 + NTSC Hsync 0 0 -40 0 0 0 + NTSC black 0 0 7.5 41 41 41 + NTSC Gray75 0 0 77 212 212 212 + YIQ +Q 33 100 50 255 81 255 + NTSC magenta 61 82 36 255 40 181 + NTSC red 104 88 28 255 28 76 + YIQ +I 123 100 50 255 89 82 + NTSC yellow 167 62 69 221 198 121 + Color burst 180 40 0 0 4 0 + YIQ -Q 213 100 50 51 232 41 + NTSC green 241 82 48 12 234 97 + NTSC cyan 284 88 56 10 245 198 + YIQ -I 303 100 50 0 224 231 + NTSC blue 347 62 15 38 65 155 +*/ + +static uint8_t robColors[16 * 4] = { + 0x00, 0x00, 0x00, 0xFF, // Black + 0xE3, 0x1E, 0x60, 0xFF, // Deep Red (Magenta) 227 30 96 + 0x60, 0x4E, 0xBD, 0xFF, // Dark Blue 96 78 189 + 0xFF, 0x44, 0xFD, 0xFF, // Purple (Violet) 255 68 253 + 0x00, 0xA3, 0x60, 0xFF, // Dark Green 0 163 96 + 0x9C, 0x9C, 0x9C, 0xFF, // Dark Gray (Gray 1) 156 156 156 + 0x14, 0xCF, 0xFD, 0xFF, // Medium Blue (Blue) 20 207 253 + 0xD0, 0xC3, 0xFF, 0xFF, // Light Blue (Cyan) 208 195 255 + 0x60, 0x72, 0x03, 0xFF, // Brown 96 114 3 + 0xFF, 0x6A, 0x3C, 0xFF, // Orange 255 106 60 + 0xD4, 0xD4, 0xD4, 0xFF, // Light Gray (Gray 2) 212 212 212 + 0xFF, 0xA0, 0xD0, 0xFF, // Pink 255 160 208 + 0x14, 0xF5, 0x3C, 0xFF, // Light Green (Green) 20 245 60 + 0xD0, 0xDD, 0x8D, 0xFF, // Yellow 208 221 141 + 0x72, 0xFF, 0xD0, 0xFF, // Aquamarine (Aqua) 114 255 208 + 0xFF, 0xFF, 0xFF, 0xFF // White +}; + // Lo-res starting line addresses static uint16_t lineAddrLoRes[24] = { @@ -300,7 +363,12 @@ void TogglePalette(void) if (palette == (uint32_t *)colors) { palette = (uint32_t *)altColors; - SpawnMessage("Color TV palette"); + SpawnMessage("ApplePC Color TV palette"); + } + else if (palette == (uint32_t *)altColors) + { + palette = (uint32_t *)robColors; + SpawnMessage("Rob's Color TV palette"); } else { @@ -629,31 +697,6 @@ fb fb fb -> 15 [1111] -> 15 WHITE */ uint8_t mirrorNybble[16] = { 0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15 }; -//This is the old "perfect monitor" rendering code... -/* if (screenType != ST_COLOR_TV) // Not correct, but for now... -//if (1) - { - for(uint16_t y=0; y> 4]; - - for(int cy=4; cy<8; cy++) - for(int cx=0; cx<14; cx++) - scrBuffer[(x * 14) + (y * VIRTUAL_SCREEN_WIDTH * 8) + cx + (cy * VIRTUAL_SCREEN_WIDTH)] = pixel; - } - } - } - else//*/ - uint32_t pixelOn = (screenType == ST_WHITE_MONO ? 0xFFFFFFFF : 0xFF61FF61); for(uint16_t y=0; y 15 [1111] -> 15 WHITE static void RenderHiRes(uint16_t toLine/*= 192*/) { -//printf("RenderHiRes to line %u\n", toLine); -// NOTE: Not endian safe. !!! FIX !!! [DONE] #if 0 uint32_t pixelOn = (screenType == ST_WHITE_MONO ? 0xFFFFFFFF : 0xFF61FF61); #else @@ -965,12 +1006,6 @@ static void RenderHiRes(uint16_t toLine/*= 192*/) pixels = previous3bits | (pixels << 14) | pixels2; -//testing (this shows on the screen, so it's OK) -//if (x == 0) -//{ -// pixels = 0x7FFFFFFF; -//} - // We now have 28 pixels (expanded from 14) in word: mask is $0F FF FF FF // 0ppp 1111 1111 1111 1111 1111 1111 1111 // 31 27 23 19 15 11 7 3 0 @@ -1154,16 +1189,6 @@ bool InitVideo(void) return false; } -#if 0 - int retVal = SDL_CreateWindowAndRenderer(VIRTUAL_SCREEN_WIDTH * 2, VIRTUAL_SCREEN_HEIGHT * 2, 0, &sdlWindow, &sdlRenderer); -// int retVal = SDL_CreateWindowAndRenderer(VIRTUAL_SCREEN_WIDTH * 1, VIRTUAL_SCREEN_HEIGHT * 1, 0, &sdlWindow, &sdlRenderer); - - if (retVal != 0) - { - WriteLog("Video: Could not create window and/or renderer: %s\n", SDL_GetError()); - return false; - } -#else sdlWindow = SDL_CreateWindow("Apple2", settings.winX, settings.winY, VIRTUAL_SCREEN_WIDTH * 2, VIRTUAL_SCREEN_HEIGHT * 2, 0); if (sdlWindow == NULL) @@ -1179,7 +1204,6 @@ bool InitVideo(void) WriteLog("Video: Could not create renderer: %s\n", SDL_GetError()); return false; } -#endif // Make sure what we put there is what we get: SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear"); diff --git a/web/index.html b/web/index.html index b6dae4f..4386a15 100644 --- a/web/index.html +++ b/web/index.html @@ -41,6 +41,7 @@
  • 128K RAM
  • Two Disk II floppy disk drives in slot 6
  • One Mockingboard A (also known as Sound II) in slot 4
  • +
  • One Apple II High-Speed SCSI Card in slot 7
  • 80-column card in slot 3
  • Double Hi-res
  • Double Lo-res