mirror of
https://github.com/cmosher01/Epple-II.git
synced 2024-12-27 17:29:16 +00:00
fix drive motor on cancels pending off; fix LSS timing during switch changes; fix GUI disk dirty flag
This commit is contained in:
parent
117d4af8ef
commit
ee420e1c02
@ -63,17 +63,17 @@ Apple2::~Apple2()
|
||||
}
|
||||
|
||||
|
||||
void Apple2::tick()
|
||||
{
|
||||
this->slts.tick();
|
||||
void Apple2::tick() {
|
||||
this->cpu.tick();
|
||||
this->video.tick();
|
||||
this->paddles.tick();
|
||||
this->speaker.tick();
|
||||
this->cassette.tick();
|
||||
this->slts.tick();
|
||||
this->video.tick();
|
||||
this->paddles.tick();
|
||||
this->speaker.tick();
|
||||
this->cassette.tick();
|
||||
|
||||
if (this->revision > 0)
|
||||
this->powerUpReset.tick();
|
||||
if (this->revision > 0) {
|
||||
this->powerUpReset.tick();
|
||||
}
|
||||
}
|
||||
|
||||
void Apple2::powerOn()
|
||||
|
@ -25,6 +25,7 @@ DiskController::DiskController(ScreenImage& gui, int slot, bool lss13):
|
||||
currentDrive(&this->drive1),
|
||||
load(false),
|
||||
write(false),
|
||||
ioStepped(false),
|
||||
lssp6rom(lss13),
|
||||
seq(0x20), // gotta start somewhere
|
||||
t(0) {
|
||||
@ -39,6 +40,8 @@ unsigned char DiskController::io(const unsigned short addr, const unsigned char
|
||||
const unsigned char q = (addr & 0x000E) >> 1;
|
||||
const bool on = (addr & 0x0001);
|
||||
|
||||
// printf("Q%d<--%s\n", q, on?"ON":"OFF");
|
||||
|
||||
switch (q) {
|
||||
case 0:
|
||||
case 1: // TODO if phase-1 is on, it also acts as write-protect (UA2, 9-8)
|
||||
@ -57,19 +60,22 @@ unsigned char DiskController::io(const unsigned short addr, const unsigned char
|
||||
break;
|
||||
case 6:
|
||||
this->load = on;
|
||||
// TODO when to do these GUI updates?
|
||||
// this->gui.setDirty(this->slot,getCurrentDriveNumber(),true);
|
||||
break;
|
||||
case 7:
|
||||
this->write = on;
|
||||
break;
|
||||
}
|
||||
// if (this->dataRegister == 0xD5u) {
|
||||
// printf("\n");
|
||||
// }
|
||||
// if (this->dataRegister & 0x80u) {
|
||||
// printf("%02X ", this->dataRegister);
|
||||
// }
|
||||
if (this->write && !this->load) {
|
||||
this->gui.setDirty(this->slot,getCurrentDriveNumber(),true);
|
||||
}
|
||||
|
||||
// UA2, 9-23, Figure 9.12
|
||||
// 2 LSS cycles need to happen AFTER setting the Qx switch, and
|
||||
// BEFORE reading LSS's update of the data register
|
||||
this->ioStepped = false;
|
||||
tick();
|
||||
this->ioStepped = true; // flag that we ran it already
|
||||
|
||||
return on ? d : this->dataRegister;
|
||||
}
|
||||
|
||||
@ -81,8 +87,13 @@ unsigned char DiskController::io(const unsigned short addr, const unsigned char
|
||||
* (When the motor is on, that is.)
|
||||
*/
|
||||
void DiskController::tick() {
|
||||
if (this->ioStepped) { // if we already ran it, above in io(), skip here
|
||||
this->ioStepped = false;
|
||||
return;
|
||||
}
|
||||
this->gui.setIO(this->slot, getCurrentDriveNumber(), this->motor.isOn());
|
||||
if (!this->motor.isOn()) {
|
||||
this->ioStepped = false;
|
||||
return;
|
||||
}
|
||||
this->motor.tick(); // only need to send tick when motor is powered on
|
||||
@ -90,7 +101,6 @@ void DiskController::tick() {
|
||||
rotateCurrentDisk();
|
||||
|
||||
// run two LSS cycles = 2MHz
|
||||
|
||||
stepLss();
|
||||
// pulse lasts only 500 nanoseconds (1 LSS clock cycle), so clear it now:
|
||||
this->currentDrive->clearPulse();
|
||||
|
@ -42,6 +42,7 @@ private:
|
||||
|
||||
bool load; // Q6
|
||||
bool write; // Q7
|
||||
bool ioStepped;
|
||||
|
||||
/*
|
||||
* Only one drive's motor can be on at a time,
|
||||
|
@ -35,6 +35,10 @@ bool DriveMotor::isOn() const {
|
||||
void DriveMotor::power(bool on) {
|
||||
if (on) {
|
||||
this->on = true;
|
||||
if (this->pendingTicks > 0) {
|
||||
this->pendingTicks = 0;
|
||||
// printf("MOTOR: cancel pending power off\n");
|
||||
}
|
||||
// printf("MOTOR: power on\n");
|
||||
} else {
|
||||
// delay power-off by about one second (a little longer, for momentum)
|
||||
|
@ -51,6 +51,12 @@ WozFile::WozFile() : tmap(0) {
|
||||
WozFile::~WozFile() {
|
||||
}
|
||||
|
||||
static void print_compat(std::uint16_t compat, std::uint16_t mask, const char *name) {
|
||||
if (compat & mask) {
|
||||
printf(" Apple %s\n", name);
|
||||
}
|
||||
}
|
||||
|
||||
bool WozFile::load(const std::string& filePath) {
|
||||
std::ifstream in(filePath.c_str(),std::ios::binary|std::ios::in);
|
||||
if (!in.is_open()) {
|
||||
@ -111,6 +117,23 @@ bool WozFile::load(const std::string& filePath) {
|
||||
this->creator = std::string((char*)buf+5, 32);
|
||||
printf("Creator: \"%.32s\"\n", buf+5);
|
||||
this->timing = buf[39];
|
||||
printf("Timing: %d/8 microseconds per bit\n", this->timing);
|
||||
std::uint16_t compat = *((std::uint16_t*)buf+40);
|
||||
printf("Campatible hardware: ");
|
||||
if (!compat) {
|
||||
printf("unknown\n");
|
||||
} else {
|
||||
printf("\n");
|
||||
print_compat(compat, 0x0001, "][");
|
||||
print_compat(compat, 0x0002, "][ plus");
|
||||
print_compat(compat, 0x0004, "//e");
|
||||
print_compat(compat, 0x0008, "//c");
|
||||
print_compat(compat, 0x0010, "//e (enhanced)");
|
||||
print_compat(compat, 0x0020, "IIGS");
|
||||
print_compat(compat, 0x0040, "IIc Plus");
|
||||
print_compat(compat, 0x0080, "///");
|
||||
print_compat(compat, 0x0100, "/// plus");
|
||||
}
|
||||
delete[] buf;
|
||||
}
|
||||
break;
|
||||
@ -118,13 +141,13 @@ bool WozFile::load(const std::string& filePath) {
|
||||
this->tmap = new std::uint8_t[chunk_size];
|
||||
in.read((char*)this->tmap, chunk_size);
|
||||
|
||||
this->initalQtrack = 0;
|
||||
while (this->initalQtrack < chunk_size && this->tmap[this->initalQtrack] == 0xFFu) {
|
||||
++this->initalQtrack;
|
||||
this->initialQtrack = 0;
|
||||
while (this->initialQtrack < chunk_size && this->tmap[this->initialQtrack] == 0xFFu) {
|
||||
++this->initialQtrack;
|
||||
}
|
||||
if (this->initalQtrack == chunk_size) {
|
||||
this->initalQtrack = 0xFFu;
|
||||
printf("Could not find any initial track (%02X).\n", this->initalQtrack);
|
||||
if (this->initialQtrack == chunk_size) {
|
||||
this->initialQtrack = 0xFFu;
|
||||
printf("Could not find any initial track (%02X).\n", this->initialQtrack);
|
||||
}
|
||||
|
||||
this->finalQtrack = chunk_size-1;
|
||||
@ -147,10 +170,10 @@ bool WozFile::load(const std::string& filePath) {
|
||||
printf("TMAP track 0x%02X : TRKS track index 0x%02X", t/100, tmap[qt]);
|
||||
}
|
||||
printf("\x1b[0m");
|
||||
if (qt == this->initalQtrack && qt == this->finalQtrack) {
|
||||
if (qt == this->initialQtrack && qt == this->finalQtrack) {
|
||||
printf(" <-- lone track");
|
||||
} else if (qt == this->initalQtrack) {
|
||||
printf(" <-- inital track");
|
||||
} else if (qt == this->initialQtrack) {
|
||||
printf(" <-- initial track");
|
||||
} else if (qt == this->finalQtrack) {
|
||||
printf(" <-- final track");
|
||||
}
|
||||
@ -177,8 +200,9 @@ bool WozFile::load(const std::string& filePath) {
|
||||
if (ts.blockCount) {
|
||||
printf("TRK index %02X: start byte in BITS %08x; %08x bytes; %08x bits ", qt, ts.blockFirst<<9, ts.blockCount<<9, ts.bitCount);
|
||||
this->trk_bits[qt] = ts.bitCount;
|
||||
this->trk[qt] = new std::uint8_t[ts.blockCount<<9];
|
||||
memcpy(this->trk[qt], buf+C_QTRACK*8+(ts.blockFirst<<9), ts.blockCount<<9);
|
||||
this->trk_byts[qt] = ts.blockCount<<9;
|
||||
this->trk[qt] = new std::uint8_t[this->trk_byts[qt]];
|
||||
memcpy(this->trk[qt], buf+C_QTRACK*8+(ts.blockFirst<<9), this->trk_byts[qt]);
|
||||
printf("("
|
||||
BYTE_TO_BINARY_PATTERN
|
||||
BYTE_TO_BINARY_PATTERN
|
||||
@ -272,12 +296,22 @@ void WozFile::save() {
|
||||
if (isWriteProtected() || !isLoaded()) {
|
||||
return;
|
||||
}
|
||||
// std::ofstream out(filePath.c_str(),std::ios::binary);
|
||||
// TODO SAVE FILE!
|
||||
// out.flush();
|
||||
// out.close();
|
||||
std::ofstream out(filePath.c_str(), std::ios::binary);
|
||||
|
||||
// this->modified = false;
|
||||
// TODO: SAVE WOZ 2.0 format FILE PROPERLY!
|
||||
|
||||
for (std::uint8_t qt(0); qt < C_QTRACK; ++qt) {
|
||||
|
||||
// staight dump of track FOR DEBUGGING ONLY
|
||||
if (this->trk[qt]) {
|
||||
printf("dumping q-track: %02X, %08X bytes\n", qt, this->trk_byts[qt]);
|
||||
out.write(reinterpret_cast<char*>(this->trk[qt]), this->trk_byts[qt]);
|
||||
}
|
||||
}
|
||||
out.flush();
|
||||
out.close();
|
||||
|
||||
// TODO: this->modified = false;
|
||||
}
|
||||
|
||||
void WozFile::unload() {
|
||||
@ -413,6 +447,7 @@ void WozFile::setBit(std::uint8_t currentQuarterTrack, bool on) {
|
||||
return; // write-protected
|
||||
}
|
||||
|
||||
// printf("%c",(on?'1':'0')); fflush(stdout);
|
||||
if (on) {
|
||||
this->trk[this->tmap[currentQuarterTrack]][this->byt] |= this->bit;
|
||||
} else {
|
||||
|
@ -59,7 +59,7 @@ class WozFile {
|
||||
// map of quarter-tracks from T00.00 through T39.75, values are indexes into trk
|
||||
std::uint8_t* tmap;
|
||||
// first actual quarter-track (e.g., 0 for normal 35-track disk), or 0xFF if no tracks
|
||||
std::uint8_t initalQtrack;
|
||||
std::uint8_t initialQtrack;
|
||||
// last actual quarter-track (e.g., 136 for normal 35-track disk), or 0xFF if no tracks
|
||||
std::uint8_t finalQtrack;
|
||||
|
||||
@ -67,6 +67,8 @@ class WozFile {
|
||||
std::uint8_t* trk[C_QTRACK];
|
||||
// count of bits in each track
|
||||
std::uint32_t trk_bits[C_QTRACK];
|
||||
// count of allocated bytes
|
||||
std::uint16_t trk_byts[C_QTRACK];
|
||||
|
||||
// bit and byt together represent the rotational position
|
||||
// of the floppy disk.
|
||||
|
Loading…
Reference in New Issue
Block a user