Added disk selection functionality, fixed power cycle bug.

This commit is contained in:
Shamus Hammons 2014-03-30 13:07:30 -05:00
parent b64a9cc3bb
commit 452bb36844
9 changed files with 178 additions and 24 deletions

View File

@ -283,7 +283,6 @@ static bool LoadApple2State(const char * filename)
static void ResetApple2State(void) static void ResetApple2State(void)
{ {
mainCPU.cpuFlags |= V65C02_ASSERT_LINE_RESET;
keyDown = false; keyDown = false;
openAppleDown = false; openAppleDown = false;
closedAppleDown = false; closedAppleDown = false;
@ -297,9 +296,14 @@ static void ResetApple2State(void)
ioudis = true; ioudis = true;
dhires = false; dhires = false;
lcState = 0x02; lcState = 0x02;
SwitchLC(); // Make sure MMU is in sane state // SwitchLC(); // Make sure MMU is in sane state
//NOPE, does nothing SetupAddressMap();
ResetMMUPointers();
// Without this, you can wedge the system :-/
memset(ram, 0, 0x10000); memset(ram, 0, 0x10000);
memset(ram2, 0, 0x10000); // memset(ram2, 0, 0x10000);
mainCPU.cpuFlags |= V65C02_ASSERT_LINE_RESET;
} }
@ -324,6 +328,7 @@ int main(int /*argc*/, char * /*argv*/[])
// Set up MMU // Set up MMU
SetupAddressMap(); SetupAddressMap();
ResetMMUPointers();
// Set up V65C02 execution context // Set up V65C02 execution context
memset(&mainCPU, 0, sizeof(V65C02REGS)); memset(&mainCPU, 0, sizeof(V65C02REGS));

View File

@ -724,6 +724,7 @@ fb fb fb -> 15 [1111] -> 15 WHITE
static void RenderHiRes(uint16_t toLine/*= 192*/) static void RenderHiRes(uint16_t toLine/*= 192*/)
{ {
//printf("RenderHiRes to line %u\n", toLine);
// NOTE: Not endian safe. !!! FIX !!! [DONE] // NOTE: Not endian safe. !!! FIX !!! [DONE]
#if 0 #if 0
uint32_t pixelOn = (screenType == ST_WHITE_MONO ? 0xFFFFFFFF : 0xFF61FF61); uint32_t pixelOn = (screenType == ST_WHITE_MONO ? 0xFFFFFFFF : 0xFF61FF61);
@ -752,6 +753,12 @@ static void RenderHiRes(uint16_t toLine/*= 192*/)
pixels = previous3bits | (pixels << 14) | pixels2; 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 // We now have 28 pixels (expanded from 14) in word: mask is $0F FF FF FF
// 0ppp 1111 1111 1111 1111 1111 1111 1111 // 0ppp 1111 1111 1111 1111 1111 1111 1111
// 31 27 23 19 15 11 7 3 0 // 31 27 23 19 15 11 7 3 0

View File

@ -46,7 +46,7 @@ FloppyDrive::FloppyDrive(): motorOn(0), activeDrive(0), ioMode(IO_MODE_READ), ph
{ {
disk[0] = disk[1] = NULL; disk[0] = disk[1] = NULL;
diskSize[0] = diskSize[1] = 0; diskSize[0] = diskSize[1] = 0;
diskType[0] = diskType[1] = DT_UNKNOWN; diskType[0] = diskType[1] = DFT_UNKNOWN;
imageDirty[0] = imageDirty[1] = false; imageDirty[0] = imageDirty[1] = false;
writeProtected[0] = writeProtected[1] = false; writeProtected[0] = writeProtected[1] = false;
imageName[0][0] = imageName[1][0] = 0; // Zero out filenames imageName[0][0] = imageName[1][0] = 0; // Zero out filenames
@ -224,7 +224,7 @@ SpawnMessage("Drive 0: %s...", imageName[0]);
void FloppyDrive::DetectImageType(const char * filename, uint8_t driveNum) void FloppyDrive::DetectImageType(const char * filename, uint8_t driveNum)
{ {
diskType[driveNum] = DT_UNKNOWN; diskType[driveNum] = DFT_UNKNOWN;
if (diskSize[driveNum] == 232960) if (diskSize[driveNum] == 232960)
{ {
@ -551,7 +551,7 @@ void FloppyDrive::EjectImage(uint8_t driveNum/*= 0*/)
disk[driveNum] = NULL; disk[driveNum] = NULL;
diskSize[driveNum] = 0; diskSize[driveNum] = 0;
diskType[driveNum] = DT_UNKNOWN; diskType[driveNum] = DFT_UNKNOWN;
imageDirty[driveNum] = false; imageDirty[driveNum] = false;
writeProtected[driveNum] = false; writeProtected[driveNum] = false;
imageName[driveNum][0] = 0; // Zero out filenames imageName[driveNum][0] = 0; // Zero out filenames

View File

@ -14,7 +14,7 @@
#endif #endif
#include <stdint.h> #include <stdint.h>
enum { DT_UNKNOWN, DT_DOS33, DT_DOS33_HDR, DT_PRODOS, DT_NYBBLE }; enum { DFT_UNKNOWN, DT_DOS33, DT_DOS33_HDR, DT_PRODOS, DT_NYBBLE };
enum { DLS_OFF, DLS_READ, DLS_WRITE }; enum { DLS_OFF, DLS_READ, DLS_WRITE };
class FloppyDrive class FloppyDrive

View File

@ -20,11 +20,25 @@
#include <algorithm> #include <algorithm>
#include <string> #include <string>
#include <vector> #include <vector>
#include "apple2.h"
#include "font10pt.h" #include "font10pt.h"
#include "log.h" #include "log.h"
#include "settings.h" #include "settings.h"
#include "video.h" #include "video.h"
enum { DSS_SHOWING, DSS_HIDING, DSS_SHOWN, DSS_HIDDEN };
#define DS_WIDTH 400
#define DS_HEIGHT 300
bool entered = false;
int driveNumber;
int diskSelectorState = DSS_HIDDEN;
int diskSelected = -1;
int lastDiskSelected = -1;
// //
// Case insensitve string comparison voodoo // Case insensitve string comparison voodoo
// //
@ -61,7 +75,7 @@ typedef std::basic_string<char, ci_char_traits> ci_string;
static SDL_Texture * window = NULL; static SDL_Texture * window = NULL;
static SDL_Texture * charStamp = NULL; static SDL_Texture * charStamp = NULL;
static uint32_t windowPixels[400 * 300]; static uint32_t windowPixels[DS_WIDTH * DS_HEIGHT];
static uint32_t stamp[FONT_WIDTH * FONT_HEIGHT]; static uint32_t stamp[FONT_WIDTH * FONT_HEIGHT];
bool DiskSelector::showWindow = false; bool DiskSelector::showWindow = false;
std::vector<ci_string> imageList; std::vector<ci_string> imageList;
@ -70,7 +84,7 @@ std::vector<ci_string> imageList;
void DiskSelector::Init(SDL_Renderer * renderer) void DiskSelector::Init(SDL_Renderer * renderer)
{ {
window = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ABGR8888, window = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ABGR8888,
SDL_TEXTUREACCESS_TARGET, 400, 300); SDL_TEXTUREACCESS_TARGET, DS_WIDTH, DS_HEIGHT);
charStamp = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, charStamp = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888,
SDL_TEXTUREACCESS_TARGET, FONT_WIDTH, FONT_HEIGHT); SDL_TEXTUREACCESS_TARGET, FONT_WIDTH, FONT_HEIGHT);
@ -86,7 +100,7 @@ void DiskSelector::Init(SDL_Renderer * renderer)
if (SDL_SetTextureBlendMode(charStamp, SDL_BLENDMODE_BLEND) == -1) if (SDL_SetTextureBlendMode(charStamp, SDL_BLENDMODE_BLEND) == -1)
WriteLog("GUI (DiskSelector): Could not set blend mode for charStamp.\n"); WriteLog("GUI (DiskSelector): Could not set blend mode for charStamp.\n");
for(uint32_t i=0; i<400*300; i++) for(uint32_t i=0; i<DS_WIDTH*DS_HEIGHT; i++)
windowPixels[i] = 0xEF00FF00; windowPixels[i] = 0xEF00FF00;
SDL_UpdateTexture(window, NULL, windowPixels, 128 * sizeof(Uint32)); SDL_UpdateTexture(window, NULL, windowPixels, 128 * sizeof(Uint32));
@ -150,7 +164,7 @@ void DiskSelector::DrawFilenames(SDL_Renderer * renderer)
// 3 columns of 18 chars apiece (with 7X12 font), 24 rows // 3 columns of 18 chars apiece (with 7X12 font), 24 rows
// 3 columns of 21 chars apiece (with 6X11 font), 27 rows // 3 columns of 21 chars apiece (with 6X11 font), 27 rows
int count = 0; unsigned int count = 0;
while (count < imageList.size()) while (count < imageList.size())
{ {
@ -168,7 +182,8 @@ void DiskSelector::DrawFilenames(SDL_Renderer * renderer)
if (i >= imageList[count].length()) if (i >= imageList[count].length())
break; break;
DrawCharacter(renderer, currentX + i, currentY, imageList[count][i]); bool invert = (diskSelected == (int)count ? true : false);
DrawCharacter(renderer, currentX + i, currentY, imageList[count][i], invert);
} }
count++; count++;
@ -184,7 +199,8 @@ void DiskSelector::DrawFilenames(SDL_Renderer * renderer)
} }
void DiskSelector::DrawCharacter(SDL_Renderer * renderer, int x, int y, uint8_t c) void DiskSelector::DrawCharacter(SDL_Renderer * renderer, int x, int y, uint8_t c,
bool invert/*=false*/)
{ {
#if 0 #if 0
// uint32_t pixel = 0xFF7F0000; // uint32_t pixel = 0xFF7F0000;
@ -201,47 +217,120 @@ void DiskSelector::DrawCharacter(SDL_Renderer * renderer, int x, int y, uint8_t
SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0x00); SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0x00);
#else #else
uint32_t pixel = 0xFFFFA020; uint32_t inv = (invert ? 0x000000FF : 0x00000000);
uint32_t pixel = 0xFFFFC000; // RRGGBBAA
uint8_t * ptr = (uint8_t *)&font10pt[(c - 0x20) * FONT_WIDTH * FONT_HEIGHT]; uint8_t * ptr = (uint8_t *)&font10pt[(c - 0x20) * FONT_WIDTH * FONT_HEIGHT];
SDL_Rect dst; SDL_Rect dst;
dst.x = x * FONT_WIDTH, dst.y = y * FONT_HEIGHT, dst.w = FONT_WIDTH, dst.h = FONT_HEIGHT; dst.x = x * FONT_WIDTH, dst.y = y * FONT_HEIGHT, dst.w = FONT_WIDTH, dst.h = FONT_HEIGHT;
for(int i=0; i<FONT_WIDTH*FONT_HEIGHT; i++) for(int i=0; i<FONT_WIDTH*FONT_HEIGHT; i++)
stamp[i] = pixel | ptr[i]; stamp[i] = (pixel | ptr[i]) ^ inv;
SDL_UpdateTexture(charStamp, NULL, stamp, FONT_WIDTH * sizeof(Uint32)); SDL_UpdateTexture(charStamp, NULL, stamp, FONT_WIDTH * sizeof(Uint32));
SDL_RenderCopy(renderer, charStamp, NULL, &dst); SDL_RenderCopy(renderer, charStamp, NULL, &dst);
#endif #endif
} }
/* /*
void DiskSelector::() void DiskSelector::()
{ {
} }
*/ */
void DiskSelector::ShowWindow(int drive)
{
entered = false;
showWindow = true;
driveNumber = drive;
}
void DiskSelector::MouseDown(int32_t x, int32_t y, uint32_t buttons) void DiskSelector::MouseDown(int32_t x, int32_t y, uint32_t buttons)
{ {
if (!showWindow)
return;
if (!entered)
return;
if (diskSelected != -1)
{
char buffer[2048];
sprintf(buffer, "%s/%s", settings.disksPath, &imageList[diskSelected][0]);
// floppyDrive.LoadImage(&imageList[diskSelected][0], driveNumber);
floppyDrive.LoadImage(buffer, driveNumber);
}
showWindow = false;
} }
void DiskSelector::MouseUp(int32_t x, int32_t y, uint32_t buttons) void DiskSelector::MouseUp(int32_t x, int32_t y, uint32_t buttons)
{ {
if (!showWindow)
return;
} }
#define DS_XPOS ((VIRTUAL_SCREEN_WIDTH - DS_WIDTH) / 2)
#define DS_YPOS ((VIRTUAL_SCREEN_HEIGHT - DS_HEIGHT) / 2)
void DiskSelector::MouseMove(int32_t x, int32_t y, uint32_t buttons) void DiskSelector::MouseMove(int32_t x, int32_t y, uint32_t buttons)
{ {
if (!showWindow)
return;
if (!entered && ((x >= DS_XPOS) && (x <= (DS_XPOS + DS_WIDTH))
&& (y >= DS_YPOS) && (y <= (DS_YPOS + DS_HEIGHT))))
entered = true;
if (entered && ((x < DS_XPOS) || (x > (DS_XPOS + DS_WIDTH))
|| (y < DS_YPOS) || (y > (DS_YPOS + DS_HEIGHT))))
{
showWindow = false;
return;
}
// prevDiskSelected = diskSelected;
int xChar = (x - DS_XPOS) / FONT_WIDTH;
int yChar = (y - DS_YPOS) / FONT_HEIGHT;
// int currentX = (count / 27) * 22;
// int currentY = (count % 27);
diskSelected = ((xChar / 22) * 27) + yChar;
if ((yChar >= 27) || (diskSelected >= (int)imageList.size()))
diskSelected = -1;
if (diskSelected != lastDiskSelected)
{
HandleSelection(sdlRenderer);
lastDiskSelected = diskSelected;
}
}
void DiskSelector::HandleSelection(SDL_Renderer * renderer)
{
// if (diskSelected == prevDiskSelected)
// return;
SDL_UpdateTexture(window, NULL, windowPixels, 128 * sizeof(Uint32));
DrawFilenames(renderer);
} }
void DiskSelector::Render(SDL_Renderer * renderer) void DiskSelector::Render(SDL_Renderer * renderer)
{ {
if (!(window || showWindow)) if (!(window && showWindow))
return; return;
// HandleSelection(renderer);
SDL_Rect dst; SDL_Rect dst;
dst.x = (VIRTUAL_SCREEN_WIDTH - 400) / 2, dst.y = (VIRTUAL_SCREEN_HEIGHT - 300) / 2, dst.w = 400, dst.h = 300; // dst.x = (VIRTUAL_SCREEN_WIDTH - DS_WIDTH) / 2, dst.y = (VIRTUAL_SCREEN_HEIGHT - DS_HEIGHT) / 2, dst.w = DS_WIDTH, dst.h = DS_HEIGHT;
dst.x = DS_XPOS, dst.y = DS_YPOS, dst.w = DS_WIDTH, dst.h = DS_HEIGHT;
SDL_RenderCopy(renderer, window, NULL, &dst); SDL_RenderCopy(renderer, window, NULL, &dst);
} }

View File

@ -15,10 +15,12 @@ class DiskSelector
static void FindDisks(const char *); static void FindDisks(const char *);
static bool HasLegalExtension(const char *); static bool HasLegalExtension(const char *);
static void DrawFilenames(SDL_Renderer *); static void DrawFilenames(SDL_Renderer *);
static void DrawCharacter(SDL_Renderer *, int, int, uint8_t); static void DrawCharacter(SDL_Renderer *, int, int, uint8_t, bool inv=false);
static void ShowWindow(int);
static void MouseDown(int32_t, int32_t, uint32_t); static void MouseDown(int32_t, int32_t, uint32_t);
static void MouseUp(int32_t, int32_t, uint32_t); static void MouseUp(int32_t, int32_t, uint32_t);
static void MouseMove(int32_t, int32_t, uint32_t); static void MouseMove(int32_t, int32_t, uint32_t);
static void HandleSelection(SDL_Renderer *);
static void Render(SDL_Renderer *); static void Render(SDL_Renderer *);
public: public:

View File

@ -187,7 +187,7 @@ void GUI::Init(SDL_Renderer * renderer)
} }
DiskSelector::Init(renderer); DiskSelector::Init(renderer);
DiskSelector::showWindow = true; // DiskSelector::showWindow = true;
WriteLog("GUI: Successfully initialized.\n"); WriteLog("GUI: Successfully initialized.\n");
} }
@ -209,11 +209,11 @@ SDL_Texture * GUI::CreateTexture(SDL_Renderer * renderer, const void * source)
void GUI::MouseDown(int32_t x, int32_t y, uint32_t buttons) void GUI::MouseDown(int32_t x, int32_t y, uint32_t buttons)
{ {
DiskSelector::MouseDown(x, y, buttons);
if (sidebarState != SBS_SHOWN) if (sidebarState != SBS_SHOWN)
return; return;
// char [2][2] = {};
switch (iconSelected) switch (iconSelected)
{ {
// Power // Power
@ -230,7 +230,16 @@ void GUI::MouseDown(int32_t x, int32_t y, uint32_t buttons)
SpawnMessage("*** DISK #1 ***"); SpawnMessage("*** DISK #1 ***");
if (disk1EjectHovered && !floppyDrive.IsEmpty(0)) if (disk1EjectHovered && !floppyDrive.IsEmpty(0))
SpawnMessage("*** EJECT DISK #1 ***"); {
floppyDrive.EjectImage(0);
SpawnMessage("*** DISK #1 EJECTED ***");
}
if (!disk1EjectHovered)
{
// Load the disk selector
DiskSelector::ShowWindow(0);
}
break; break;
// Disk #2 // Disk #2
@ -238,12 +247,22 @@ void GUI::MouseDown(int32_t x, int32_t y, uint32_t buttons)
SpawnMessage("*** DISK #2 ***"); SpawnMessage("*** DISK #2 ***");
if (disk2EjectHovered && !floppyDrive.IsEmpty(1)) if (disk2EjectHovered && !floppyDrive.IsEmpty(1))
SpawnMessage("*** EJECT DISK #2 ***"); {
floppyDrive.EjectImage(1);
SpawnMessage("*** DISK #2 EJECTED ***");
}
if (!disk2EjectHovered)
{
// Load the disk selector
DiskSelector::ShowWindow(1);
}
break; break;
// Swap disks // Swap disks
case 3: case 3:
SpawnMessage("*** SWAP DISKS ***"); floppyDrive.SwapImages();
SpawnMessage("*** DISKS SWAPPED ***");
break; break;
// Save state // Save state
case 4: case 4:
@ -263,11 +282,14 @@ void GUI::MouseDown(int32_t x, int32_t y, uint32_t buttons)
void GUI::MouseUp(int32_t x, int32_t y, uint32_t buttons) void GUI::MouseUp(int32_t x, int32_t y, uint32_t buttons)
{ {
DiskSelector::MouseUp(x, y, buttons);
} }
void GUI::MouseMove(int32_t x, int32_t y, uint32_t buttons) void GUI::MouseMove(int32_t x, int32_t y, uint32_t buttons)
{ {
DiskSelector::MouseMove(x, y, buttons);
if (sidebarState != SBS_SHOWN) if (sidebarState != SBS_SHOWN)
{ {
iconSelected = -1; iconSelected = -1;

View File

@ -276,6 +276,34 @@ void SetupAddressMap(void)
} }
//
// Reset the MMU state after a power down event
//
void ResetMMUPointers(void)
{
if (store80Mode)
{
mainMemoryTextR = (displayPage2 ? &ram2[0x0400] : &ram[0x0400]);
mainMemoryTextW = (displayPage2 ? &ram2[0x0400] : &ram[0x0400]);
}
else
{
mainMemoryTextR = (ramwrt ? &ram2[0x0400] : &ram[0x0400]);
mainMemoryTextW = (ramwrt ? &ram2[0x0400] : &ram[0x0400]);
}
mainMemoryR = (ramrd ? &ram2[0x0200] : &ram[0x0200]);
mainMemoryHGRR = (ramrd ? &ram2[0x2000] : &ram[0x2000]);
mainMemoryW = (ramwrt ? &ram2[0x0200] : &ram[0x0200]);
mainMemoryHGRW = (ramwrt ? &ram2[0x2000] : &ram[0x2000]);
slot6Memory = (slotCXROM ? &diskROM[0] : &rom[0xC600]);
slot3Memory = (slotC3ROM ? &rom[0] : &rom[0xC300]);
pageZeroMemory = (altzp ? &ram2[0x0000] : &ram[0x0000]);
SwitchLC();
}
// //
// Built-in functions // Built-in functions
// //

View File

@ -4,6 +4,7 @@
#include <stdint.h> #include <stdint.h>
void SetupAddressMap(void); void SetupAddressMap(void);
void ResetMMUPointers(void);
uint8_t AppleReadMem(uint16_t); uint8_t AppleReadMem(uint16_t);
void AppleWriteMem(uint16_t, uint8_t); void AppleWriteMem(uint16_t, uint8_t);
void SwitchLC(void); void SwitchLC(void);