Add support for .hdv hard drive images, new "Rob Color TV" palette.

This commit is contained in:
Shamus Hammons 2020-09-11 18:39:32 -05:00
parent 8e30a909ce
commit 4493a5bea7
8 changed files with 112 additions and 59 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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");
}

View File

@ -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;
}

View File

@ -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)
{

View File

@ -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<toLine; y++)
{
for(uint16_t x=0; x<40; x++)
{
uint8_t scrByte = ram[lineAddrLoRes[y] + (displayPage2 ? 0x0400 : 0x0000) + x];
uint32_t pixel = palette[scrByte & 0x0F];
for(int cy=0; cy<4; cy++)
for(int cx=0; cx<14; cx++)
scrBuffer[((x * 14) + cx) + (((y * 8) + cy) * VIRTUAL_SCREEN_WIDTH)] = pixel;
pixel = palette[scrByte >> 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<toLine; y++)
@ -936,8 +979,6 @@ FB FB FB -> 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");

View File

@ -41,6 +41,7 @@
<li>128K RAM</li>
<li>Two Disk II floppy disk drives in slot 6</li>
<li>One Mockingboard A (also known as Sound II) in slot 4</li>
<li>One Apple II High-Speed SCSI Card in slot 7</li>
<li>80-column card in slot 3</li>
<li>Double Hi-res</li>
<li>Double Lo-res</li>