make disk read pulse 500 ns (not 1 us) (fixes DOS 3.2); enhance stepper motor logging; minor refactor

This commit is contained in:
Christopher A. Mosher 2018-12-18 22:59:20 -05:00
parent 745592a68c
commit d408f77e10
9 changed files with 44 additions and 50 deletions

View File

@ -66,6 +66,12 @@ unsigned char DiskController::io(const unsigned short addr, const unsigned char
this->write = on; this->write = on;
break; break;
} }
// if (this->dataRegister == 0xD5u) {
// printf("\n");
// }
// if (this->dataRegister & 0x80u) {
// printf("%02X ", this->dataRegister);
// }
return on ? d : this->dataRegister; return on ? d : this->dataRegister;
} }
@ -85,6 +91,7 @@ void DiskController::tick() {
// run two LSS cycles = 2MHz // run two LSS cycles = 2MHz
stepLss(); stepLss();
this->currentDrive->clearPulse();
stepLss(); stepLss();
} }
@ -93,9 +100,6 @@ void DiskController::rotateCurrentDisk() {
if (4 <= this->t) { // 4us interval between bits if (4 <= this->t) { // 4us interval between bits
this->currentDrive->rotateDiskOneBit(); // (will also generate a read-pulse when it reads a 1-bit) this->currentDrive->rotateDiskOneBit(); // (will also generate a read-pulse when it reads a 1-bit)
this->t = 0; this->t = 0;
} else {
// clear the read pulse (to make it last only 1us)
this->currentDrive->clearPulse();
} }
} }
@ -105,6 +109,7 @@ void DiskController::stepLss() {
this->seq = cmd & 0xF0u; this->seq = cmd & 0xF0u;
// LSS command functions (UA2, 9-15, Table 9.3) // LSS command functions (UA2, 9-15, Table 9.3)
// printf("%02x:", cmd);
if (cmd & 8u) { if (cmd & 8u) {
switch (cmd & 3u) { switch (cmd & 3u) {
case 3: case 3:
@ -118,6 +123,9 @@ void DiskController::stepLss() {
case 1: case 1:
this->dataRegister <<= 1; this->dataRegister <<= 1;
this->dataRegister |= ((cmd & 4u) >> 2); this->dataRegister |= ((cmd & 4u) >> 2);
// printf(this->dataRegister & 0x80u ? "\x1b[30;42m" : "\x1b[30;43m");
// printf("%02X\x1b[0m ", this->dataRegister);
// if (this->dataRegister & 0x80u) printf("\n");
// TODO how to handle writing? // TODO how to handle writing?
break; break;
} }

View File

@ -63,15 +63,6 @@ private:
this->currentDrive->writeBit(on); this->currentDrive->writeBit(on);
} }
// unsigned char get() const
// {
// if (!this->motorOn)
// {
// return 0xFF;
// }
// return this->currentDrive->get();
// }
Drive& getDrive(const unsigned char drive) Drive& getDrive(const unsigned char drive)
{ {
return (drive == 0) ? this->drive1 : this->drive2; return (drive == 0) ? this->drive1 : this->drive2;

View File

@ -63,7 +63,7 @@ public:
void unloadDisk() { void unloadDisk() {
this->disk.unload(); this->disk.unload();
} }
bool isLoaded() { bool isLoaded() const {
return this->disk.isLoaded(); return this->disk.isLoaded();
} }
@ -108,7 +108,7 @@ public:
} }
} }
bool readPulse() { bool readPulse() const {
return this->pulse; return this->pulse;
} }
void clearPulse() { void clearPulse() {

View File

@ -58,7 +58,7 @@ static void setbth(std::uint8_t lssrom[], std::uint8_t x, std::uint8_t both) {
//} //}
LSS::LSS(bool use13SectorDos32LSS): LSS::LSS(bool use13SectorDos32LSS):
use13SectorDos32LSS(use13SectorDos32LSS) { use13Sector(use13SectorDos32LSS) {
/* /*
* LSS P6 ROM is stored here with different addressing bits * LSS P6 ROM is stored here with different addressing bits
* than in the original hardware, just for ease of understanding. * than in the original hardware, just for ease of understanding.
@ -175,7 +175,7 @@ LSS::LSS(bool use13SectorDos32LSS):
setseq(lss13rom,0x23u,0x30u); setseq(lss13rom,0x23u,0x30u);
setseq(lss13rom,0x33u,0xD0u); setseq(lss13rom,0x33u,0xD0u);
// if (use13SectorDos32LSS) { // if (use13Sector) {
// for (unsigned int seq = 0; seq < 0x100u; seq += 0x10u) { // for (unsigned int seq = 0; seq < 0x100u; seq += 0x10u) {
// showua2seq(lss13rom,seq); // showua2seq(lss13rom,seq);
// } // }

View File

@ -25,7 +25,7 @@
class LSS class LSS
{ {
private: private:
bool use13SectorDos32LSS; bool use13Sector;
std::uint8_t lssrom[0x100]; std::uint8_t lssrom[0x100];
std::uint8_t lss13rom[0x100]; std::uint8_t lss13rom[0x100];
@ -34,7 +34,7 @@ public:
~LSS(); ~LSS();
std::uint8_t read(const std::uint8_t addr) { std::uint8_t read(const std::uint8_t addr) {
return use13SectorDos32LSS ? lss13rom[addr] : lssrom[addr]; return use13Sector ? lss13rom[addr] : lssrom[addr];
} }
}; };

View File

@ -104,6 +104,8 @@ static int run(const std::string& config_file) {
extern "C" extern "C"
#endif #endif
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
setbuf(stdout, NULL);
if (argc > 2) { if (argc > 2) {
throw std::runtime_error("usage: epple2 [config-file]" ); throw std::runtime_error("usage: epple2 [config-file]" );
} }

View File

@ -63,7 +63,7 @@ undefined
#include <iostream> #include <iostream>
StepperMotor::StepperMotor(): StepperMotor::StepperMotor():
quarterTrack(QTRACK_MAX >> 1), // start in the middle of the disk... just for fun quarterTrack(QTRACKS >> 1), // start in the middle of the disk... just for fun
// TODO if we want to be extremely accurate, we should save each arm's position on shutdown and restore on startup // TODO if we want to be extremely accurate, we should save each arm's position on shutdown and restore on startup
// (because in the real-life Apple ][, the arm stays in the same position when powered off). // (because in the real-life Apple ][, the arm stays in the same position when powered off).
pos(0), pos(0),
@ -83,6 +83,8 @@ void StepperMotor::setMagnet(const unsigned char magnet, const bool on) {
this->mags &= ~mask; this->mags &= ~mask;
} }
// const std::uint8_t oldQT = this->quarterTrack;
const char newPos = mapMagPos[this->mags]; const char newPos = mapMagPos[this->mags];
char d = 0; char d = 0;
if (newPos >= 0) { if (newPos >= 0) {
@ -92,31 +94,22 @@ void StepperMotor::setMagnet(const unsigned char magnet, const bool on) {
this->quarterTrack += d; this->quarterTrack += d;
if (this->quarterTrack < 0) if (this->quarterTrack < 0)
this->quarterTrack = 0; this->quarterTrack = 0;
else if (this->quarterTrack > QTRACK_MAX) else if (QTRACKS <= this->quarterTrack)
this->quarterTrack = QTRACK_MAX; this->quarterTrack = QTRACKS-1;
} }
// std::cout << " ARM: magnet " << (unsigned int)magnet << " " << (on ? "on " : "off" );
// std::cout << " [" <<
// ((mags&1)?"*":".") <<
// ((mags&2)?"*":".") <<
// ((mags&4)?"*":".") <<
// ((mags&8)?"*":".") <<
// "]";
// if (d != 0) {
// std::cout << " track " << std::hex << (unsigned int)(this->quarterTrack >> 2);
// int fract = this->quarterTrack & 3;
// if (fract != 0) {
// std::cout << (fract == 1 ? " +.25" : fract == 2 ? " +.5" : " +.75");
// }
// }
// std::cout << std::endl;
}
//static void dumpQTrack(std::uint8_t currentQuarterTrack) {
// if (currentQuarterTrack % 4) {
// const std::uint8_t hundredths((currentQuarterTrack%4) * 25);
// printf("track 0x%02X +.%02d\n", currentQuarterTrack/4, hundredths);
// } else {
// printf("track 0x%02X\n", currentQuarterTrack/4);
// }
//}
// const std::uint8_t newQT = this->quarterTrack;
// const std::int8_t deltaQT = newQT - oldQT;
// printf("ARM: ph%d %s [%c%c%c%c] T$%02X.%02d %s %+0.2f\n",
// (std::uint8_t)magnet,
// on ? "+" : "-",
// (mags&1)?'*':'.',
// (mags&2)?'*':'.',
// (mags&4)?'*':'.',
// (mags&8)?'*':'.',
// this->quarterTrack / 4,
// (this->quarterTrack % 4) * 25,
// deltaQT>0 ? "-->" : deltaQT<0 ? "<--" : " ",
// (deltaQT % 4) / 4.0);
}

View File

@ -22,12 +22,11 @@
class StepperMotor { class StepperMotor {
private: private:
enum { TRACKS_PER_DISK = 0x23 }; enum { QTRACKS = 141 };
enum { QTRACK_MAX = TRACKS_PER_DISK << 2 };
// quarter track: 0=t0, 1=t0.25, 2=t0.5, 3=t0.75, 4=t1, ... 140=t35.00 // quarter track: 0=t0, 1=t0.25, 2=t0.5, 3=t0.75, 4=t1, ... 140=t35.00
// (see TMAP in WOZ file format) // (see TMAP in WOZ file format spec)
signed short quarterTrack; std::int16_t quarterTrack;
signed char pos; // 0 - 7 signed char pos; // 0 - 7
unsigned char mags; unsigned char mags;

View File

@ -306,7 +306,7 @@ void WozFile::rotateOneBit(std::uint8_t currentQuarterTrack) {
this->byt = 0; this->byt = 0;
this->bit = 0x80u; this->bit = 0x80u;
} }
} }
@ -317,6 +317,7 @@ bool WozFile::getBit(std::uint8_t currentQuarterTrack) {
} }
if (this->tmap[currentQuarterTrack] == 0xFFu) { if (this->tmap[currentQuarterTrack] == 0xFFu) {
// printf("Reading from uninitialized track; will generate random data.\n");
return false; // empty track return false; // empty track
} }