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)
{
mainCPU.cpuFlags |= V65C02_ASSERT_LINE_RESET;
keyDown = false;
openAppleDown = false;
closedAppleDown = false;
@ -297,9 +296,14 @@ static void ResetApple2State(void)
ioudis = true;
dhires = false;
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(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
SetupAddressMap();
ResetMMUPointers();
// Set up V65C02 execution context
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*/)
{
//printf("RenderHiRes to line %u\n", toLine);
// NOTE: Not endian safe. !!! FIX !!! [DONE]
#if 0
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;
//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

View File

@ -46,7 +46,7 @@ FloppyDrive::FloppyDrive(): motorOn(0), activeDrive(0), ioMode(IO_MODE_READ), ph
{
disk[0] = disk[1] = NULL;
diskSize[0] = diskSize[1] = 0;
diskType[0] = diskType[1] = DT_UNKNOWN;
diskType[0] = diskType[1] = DFT_UNKNOWN;
imageDirty[0] = imageDirty[1] = false;
writeProtected[0] = writeProtected[1] = false;
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)
{
diskType[driveNum] = DT_UNKNOWN;
diskType[driveNum] = DFT_UNKNOWN;
if (diskSize[driveNum] == 232960)
{
@ -551,7 +551,7 @@ void FloppyDrive::EjectImage(uint8_t driveNum/*= 0*/)
disk[driveNum] = NULL;
diskSize[driveNum] = 0;
diskType[driveNum] = DT_UNKNOWN;
diskType[driveNum] = DFT_UNKNOWN;
imageDirty[driveNum] = false;
writeProtected[driveNum] = false;
imageName[driveNum][0] = 0; // Zero out filenames

View File

@ -14,7 +14,7 @@
#endif
#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 };
class FloppyDrive

View File

@ -20,11 +20,25 @@
#include <algorithm>
#include <string>
#include <vector>
#include "apple2.h"
#include "font10pt.h"
#include "log.h"
#include "settings.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
//
@ -61,7 +75,7 @@ typedef std::basic_string<char, ci_char_traits> ci_string;
static SDL_Texture * window = 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];
bool DiskSelector::showWindow = false;
std::vector<ci_string> imageList;
@ -70,7 +84,7 @@ std::vector<ci_string> imageList;
void DiskSelector::Init(SDL_Renderer * renderer)
{
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,
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)
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;
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 21 chars apiece (with 6X11 font), 27 rows
int count = 0;
unsigned int count = 0;
while (count < imageList.size())
{
@ -168,7 +182,8 @@ void DiskSelector::DrawFilenames(SDL_Renderer * renderer)
if (i >= imageList[count].length())
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++;
@ -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
// 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);
#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];
SDL_Rect dst;
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++)
stamp[i] = pixel | ptr[i];
stamp[i] = (pixel | ptr[i]) ^ inv;
SDL_UpdateTexture(charStamp, NULL, stamp, FONT_WIDTH * sizeof(Uint32));
SDL_RenderCopy(renderer, charStamp, NULL, &dst);
#endif
}
/*
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)
{
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)
{
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)
{
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)
{
if (!(window || showWindow))
if (!(window && showWindow))
return;
// HandleSelection(renderer);
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);
}

View File

@ -15,10 +15,12 @@ class DiskSelector
static void FindDisks(const char *);
static bool HasLegalExtension(const char *);
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 MouseUp(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 *);
public:

View File

@ -187,7 +187,7 @@ void GUI::Init(SDL_Renderer * renderer)
}
DiskSelector::Init(renderer);
DiskSelector::showWindow = true;
// DiskSelector::showWindow = true;
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)
{
DiskSelector::MouseDown(x, y, buttons);
if (sidebarState != SBS_SHOWN)
return;
// char [2][2] = {};
switch (iconSelected)
{
// Power
@ -230,7 +230,16 @@ void GUI::MouseDown(int32_t x, int32_t y, uint32_t buttons)
SpawnMessage("*** DISK #1 ***");
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;
// Disk #2
@ -238,12 +247,22 @@ void GUI::MouseDown(int32_t x, int32_t y, uint32_t buttons)
SpawnMessage("*** DISK #2 ***");
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;
// Swap disks
case 3:
SpawnMessage("*** SWAP DISKS ***");
floppyDrive.SwapImages();
SpawnMessage("*** DISKS SWAPPED ***");
break;
// Save state
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)
{
DiskSelector::MouseUp(x, y, buttons);
}
void GUI::MouseMove(int32_t x, int32_t y, uint32_t buttons)
{
DiskSelector::MouseMove(x, y, buttons);
if (sidebarState != SBS_SHOWN)
{
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
//

View File

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