mirror of
https://github.com/robmcmullen/apple2.git
synced 2024-12-26 11:30:19 +00:00
Add support for .hdv hard drive images, new "Rob Color TV" palette.
This commit is contained in:
parent
8e30a909ce
commit
4493a5bea7
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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");
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
116
src/video.cpp
116
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<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");
|
||||
|
@ -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>
|
||||
|
Loading…
Reference in New Issue
Block a user