mirror of
https://github.com/cmosher01/Epple-II.git
synced 2024-12-29 00:31:40 +00:00
fix position on track switch; small refactor; comments
This commit is contained in:
parent
8a393af531
commit
745592a68c
@ -4,7 +4,7 @@ METASOURCES=AUTO
|
|||||||
|
|
||||||
bin_PROGRAMS=epple2
|
bin_PROGRAMS=epple2
|
||||||
|
|
||||||
AM_CXXFLAGS=-std=c++14 -Wall -O3
|
AM_CXXFLAGS=-std=c++11 -Wall -O3
|
||||||
AM_CPPFLAGS=$(all_includes)
|
AM_CPPFLAGS=$(all_includes)
|
||||||
epple2_LDFLAGS=$(all_libraries)
|
epple2_LDFLAGS=$(all_libraries)
|
||||||
|
|
||||||
|
@ -58,33 +58,14 @@ unsigned char DiskController::io(const unsigned short addr, const unsigned char
|
|||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
this->load = on;
|
this->load = on;
|
||||||
// TODO use LSS
|
// TODO when to do these GUI updates?
|
||||||
// if (on && this->write && writing) {
|
|
||||||
// set(data);
|
|
||||||
// this->gui.setIO(this->slot,getCurrentDriveNumber(),this->motorOn);
|
// this->gui.setIO(this->slot,getCurrentDriveNumber(),this->motorOn);
|
||||||
// this->gui.setDirty(this->slot,getCurrentDriveNumber(),true);
|
// this->gui.setDirty(this->slot,getCurrentDriveNumber(),true);
|
||||||
// } else if (!(on || this->write)) {
|
|
||||||
// data = get();
|
|
||||||
// }
|
|
||||||
break;
|
break;
|
||||||
case 7:
|
case 7:
|
||||||
this->write = on;
|
this->write = on;
|
||||||
// TODO use LSS
|
|
||||||
// if (this->currentDrive->isWriteProtected()) {
|
|
||||||
// data |= 0x80;
|
|
||||||
// } else {
|
|
||||||
// data &= 0x7F;
|
|
||||||
// }
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// if (this->motorOn) {
|
|
||||||
// if (this->dataRegister == 0xD5) {
|
|
||||||
// printf("\ndata register --> ");
|
|
||||||
// }
|
|
||||||
// if (this->dataRegister & 0x80) {
|
|
||||||
// printf("%02x", this->dataRegister);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
return on ? d : this->dataRegister;
|
return on ? d : this->dataRegister;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,10 +89,10 @@ void DiskController::tick() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void DiskController::rotateCurrentDisk() {
|
void DiskController::rotateCurrentDisk() {
|
||||||
++t;
|
++this->t;
|
||||||
if (t < 0 || 4 <= 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)
|
||||||
t = 0;
|
this->t = 0;
|
||||||
} else {
|
} else {
|
||||||
// clear the read pulse (to make it last only 1us)
|
// clear the read pulse (to make it last only 1us)
|
||||||
this->currentDrive->clearPulse();
|
this->currentDrive->clearPulse();
|
||||||
@ -121,7 +102,6 @@ void DiskController::rotateCurrentDisk() {
|
|||||||
void DiskController::stepLss() {
|
void DiskController::stepLss() {
|
||||||
std::uint8_t adr = this->write<<3 | this->load<<2 | (this->dataRegister>>7)<<1 | this->currentDrive->readPulse();
|
std::uint8_t adr = this->write<<3 | this->load<<2 | (this->dataRegister>>7)<<1 | this->currentDrive->readPulse();
|
||||||
std::uint8_t cmd = this->lssp6rom.read(this->seq|adr);
|
std::uint8_t cmd = this->lssp6rom.read(this->seq|adr);
|
||||||
// if (cmd & 3) printf("LSS ROM command byte: 0x%2x\n", cmd);
|
|
||||||
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)
|
||||||
|
18
src/drive.h
18
src/drive.h
@ -101,7 +101,6 @@ public:
|
|||||||
// we see more than three (emulating the MC3470, see UA2, 9-11)
|
// we see more than three (emulating the MC3470, see UA2, 9-11)
|
||||||
++cContiguousZeroBits;
|
++cContiguousZeroBits;
|
||||||
if (3 < cContiguousZeroBits) {
|
if (3 < cContiguousZeroBits) {
|
||||||
// if (cContiguousZeroBits == 4) printf("\n<GENERATING RANDOM BIT(S).....>\n");
|
|
||||||
if (randomBit()) {
|
if (randomBit()) {
|
||||||
this->pulse = true;
|
this->pulse = true;
|
||||||
}
|
}
|
||||||
@ -117,23 +116,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void writeBit(bool on) {
|
void writeBit(bool on) {
|
||||||
this->disk.setBit(this->arm.getQuarterTrack());
|
this->disk.setBit(this->arm.getQuarterTrack(), on);
|
||||||
}
|
}
|
||||||
// unsigned char get() const
|
|
||||||
// {
|
|
||||||
// return this->disk.get(this->arm.getTrack());
|
|
||||||
// }
|
|
||||||
|
|
||||||
// void set(unsigned char value)
|
|
||||||
// {
|
|
||||||
// this->disk.put(this->arm.getTrack(),value);
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// const WozFile& getDiskBytes() {
|
|
||||||
// return this->disk;
|
|
||||||
// }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
62
src/lss.cpp
62
src/lss.cpp
@ -34,28 +34,28 @@ static void setbth(std::uint8_t lssrom[], std::uint8_t x, std::uint8_t both) {
|
|||||||
lssrom[x] = both;
|
lssrom[x] = both;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void showua2seq(std::uint8_t lssrom[], std::uint8_t seq) {
|
//static void showua2seq(std::uint8_t lssrom[], std::uint8_t seq) {
|
||||||
printf("| %02x %02x %02x %02x | %02x %02x %02x %02x",
|
// printf("| %02x %02x %02x %02x | %02x %02x %02x %02x",
|
||||||
lssrom[seq|0x9],
|
// lssrom[seq|0x9],
|
||||||
lssrom[seq|0xB],
|
// lssrom[seq|0xB],
|
||||||
lssrom[seq|0xD],
|
// lssrom[seq|0xD],
|
||||||
lssrom[seq|0xF],
|
// lssrom[seq|0xF],
|
||||||
lssrom[seq|0x8],
|
// lssrom[seq|0x8],
|
||||||
lssrom[seq|0xA],
|
// lssrom[seq|0xA],
|
||||||
lssrom[seq|0xC],
|
// lssrom[seq|0xC],
|
||||||
lssrom[seq|0xE]
|
// lssrom[seq|0xE]
|
||||||
);
|
// );
|
||||||
printf("| %02x %02x %02x %02x | %02x %02x %02x %02x |\n",
|
// printf("| %02x %02x %02x %02x | %02x %02x %02x %02x |\n",
|
||||||
lssrom[seq|0x1],
|
// lssrom[seq|0x1],
|
||||||
lssrom[seq|0x0],
|
// lssrom[seq|0x0],
|
||||||
lssrom[seq|0x3],
|
// lssrom[seq|0x3],
|
||||||
lssrom[seq|0x2],
|
// lssrom[seq|0x2],
|
||||||
lssrom[seq|0x5],
|
// lssrom[seq|0x5],
|
||||||
lssrom[seq|0x4],
|
// lssrom[seq|0x4],
|
||||||
lssrom[seq|0x7],
|
// lssrom[seq|0x7],
|
||||||
lssrom[seq|0x6]
|
// lssrom[seq|0x6]
|
||||||
);
|
// );
|
||||||
}
|
//}
|
||||||
|
|
||||||
LSS::LSS(bool use13SectorDos32LSS):
|
LSS::LSS(bool use13SectorDos32LSS):
|
||||||
use13SectorDos32LSS(use13SectorDos32LSS) {
|
use13SectorDos32LSS(use13SectorDos32LSS) {
|
||||||
@ -175,15 +175,15 @@ LSS::LSS(bool use13SectorDos32LSS):
|
|||||||
setseq(lss13rom,0x23u,0x30u);
|
setseq(lss13rom,0x23u,0x30u);
|
||||||
setseq(lss13rom,0x33u,0xD0u);
|
setseq(lss13rom,0x33u,0xD0u);
|
||||||
|
|
||||||
if (use13SectorDos32LSS) {
|
// if (use13SectorDos32LSS) {
|
||||||
for (unsigned int seq = 0; seq < 0x100u; seq += 0x10u) {
|
// for (unsigned int seq = 0; seq < 0x100u; seq += 0x10u) {
|
||||||
showua2seq(lss13rom,seq);
|
// showua2seq(lss13rom,seq);
|
||||||
}
|
// }
|
||||||
} else {
|
// } else {
|
||||||
for (unsigned int seq = 0; seq < 0x100u; seq += 0x10u) {
|
// for (unsigned int seq = 0; seq < 0x100u; seq += 0x10u) {
|
||||||
showua2seq(lssrom,seq);
|
// showua2seq(lssrom,seq);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
LSS::~LSS() {
|
LSS::~LSS() {
|
||||||
|
@ -62,7 +62,7 @@ void RAMInitializer::putBytesUntilFull(int bit, int pat)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RAMInitializer::ramPattern1(const int bit) throw (done)
|
void RAMInitializer::ramPattern1(const int bit)
|
||||||
{
|
{
|
||||||
for (int k = 0; k < 2; ++k)
|
for (int k = 0; k < 2; ++k)
|
||||||
{
|
{
|
||||||
@ -100,7 +100,7 @@ void RAMInitializer::ramPattern1(const int bit) throw (done)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RAMInitializer::ramPattern2(const int bit) throw (done)
|
void RAMInitializer::ramPattern2(const int bit)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 0x40; ++i)
|
for (int i = 0; i < 0x40; ++i)
|
||||||
{
|
{
|
||||||
@ -111,7 +111,7 @@ void RAMInitializer::ramPattern2(const int bit) throw (done)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void RAMInitializer::putn(const int c, bool on, const int bit) throw (done)
|
void RAMInitializer::putn(const int c, bool on, const int bit)
|
||||||
{
|
{
|
||||||
if (((rand() >> 9) & 0x1F) == 5)
|
if (((rand() >> 9) & 0x1F) == 5)
|
||||||
on = !on;
|
on = !on;
|
||||||
|
@ -29,9 +29,9 @@ private:
|
|||||||
unsigned short nextinit;
|
unsigned short nextinit;
|
||||||
|
|
||||||
void putBytesUntilFull(int bit, int pat);
|
void putBytesUntilFull(int bit, int pat);
|
||||||
void ramPattern1(const int bit) throw (done);
|
void ramPattern1(const int bit);
|
||||||
void ramPattern2(const int bit) throw (done);
|
void ramPattern2(const int bit);
|
||||||
void putn(const int c, bool on, const int bit) throw (done);
|
void putn(const int c, bool on, const int bit);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RAMInitializer(Memory& mem);
|
RAMInitializer(Memory& mem);
|
||||||
|
@ -26,9 +26,15 @@
|
|||||||
* @author Chris Mosher
|
* @author Chris Mosher
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
|
|
||||||
|
|
||||||
mags ps magval
|
mags ps magval
|
||||||
3210
|
3210
|
||||||
---- -- ------
|
---- -- ------
|
||||||
|
|
||||||
|
Each postition is a quarter track.
|
||||||
|
One complete cycle through the 4 phases will
|
||||||
|
move the arm 2 tracks. (UA2, 9-7.)
|
||||||
0001 0 1
|
0001 0 1
|
||||||
0011 1 3
|
0011 1 3
|
||||||
0010 2 2
|
0010 2 2
|
||||||
@ -38,17 +44,19 @@ mags ps magval
|
|||||||
1000 6 8
|
1000 6 8
|
||||||
1001 7 9
|
1001 7 9
|
||||||
|
|
||||||
(strange, but defined)
|
strange, but still defined
|
||||||
1011 0 B
|
1011 0 B
|
||||||
0111 2 7
|
0111 2 7
|
||||||
1110 4 E
|
1110 4 E
|
||||||
1101 6 D
|
1101 6 D
|
||||||
|
|
||||||
(undefined, i.e., no movement)
|
all off (no movement)
|
||||||
0000 ? 0
|
0000 ? 0
|
||||||
|
|
||||||
|
undefined
|
||||||
0101 ? 5 // <-- TODO pick one at random?
|
0101 ? 5 // <-- TODO pick one at random?
|
||||||
1010 ? A // <-- TODO pick one at random?
|
1010 ? A // <-- TODO pick one at random?
|
||||||
1111 ? F
|
1111 ? F // TODO what to do here?
|
||||||
*/
|
*/
|
||||||
#include "steppermotor.h"
|
#include "steppermotor.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
@ -76,7 +84,7 @@ void StepperMotor::setMagnet(const unsigned char magnet, const bool on) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const char newPos = mapMagPos[this->mags];
|
const char newPos = mapMagPos[this->mags];
|
||||||
char d;
|
char d = 0;
|
||||||
if (newPos >= 0) {
|
if (newPos >= 0) {
|
||||||
d = calcDeltaPos(this->pos,newPos);
|
d = calcDeltaPos(this->pos,newPos);
|
||||||
this->pos = newPos;
|
this->pos = newPos;
|
||||||
@ -87,19 +95,28 @@ void StepperMotor::setMagnet(const unsigned char magnet, const bool on) {
|
|||||||
else if (this->quarterTrack > QTRACK_MAX)
|
else if (this->quarterTrack > QTRACK_MAX)
|
||||||
this->quarterTrack = QTRACK_MAX;
|
this->quarterTrack = QTRACK_MAX;
|
||||||
}
|
}
|
||||||
std::cout << " ARM: magnet " << (unsigned int)magnet << " " << (on ? "on " : "off" );
|
// std::cout << " ARM: magnet " << (unsigned int)magnet << " " << (on ? "on " : "off" );
|
||||||
std::cout << " [" <<
|
// std::cout << " [" <<
|
||||||
((mags&1)?"*":".") <<
|
// ((mags&1)?"*":".") <<
|
||||||
((mags&2)?"*":".") <<
|
// ((mags&2)?"*":".") <<
|
||||||
((mags&4)?"*":".") <<
|
// ((mags&4)?"*":".") <<
|
||||||
((mags&8)?"*":".") <<
|
// ((mags&8)?"*":".") <<
|
||||||
"]";
|
// "]";
|
||||||
if (d != 0) {
|
// if (d != 0) {
|
||||||
std::cout << " track " << std::hex << (unsigned int)(this->quarterTrack >> 2);
|
// std::cout << " track " << std::hex << (unsigned int)(this->quarterTrack >> 2);
|
||||||
int fract = this->quarterTrack & 3;
|
// int fract = this->quarterTrack & 3;
|
||||||
if (fract != 0) {
|
// if (fract != 0) {
|
||||||
std::cout << (fract == 1 ? " +.25" : fract == 2 ? " +.5" : " +.75");
|
// std::cout << (fract == 1 ? " +.25" : fract == 2 ? " +.5" : " +.75");
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
std::cout << std::endl;
|
// 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);
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
102
src/wozfile.cpp
102
src/wozfile.cpp
@ -22,6 +22,7 @@
|
|||||||
#include <istream>
|
#include <istream>
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
WozFile::WozFile() : lastQuarterTrack(0) {
|
WozFile::WozFile() : lastQuarterTrack(0) {
|
||||||
unload();
|
unload();
|
||||||
@ -73,8 +74,8 @@ bool WozFile::load(const std::string& filePath) {
|
|||||||
printf("INFO version %d\n", *buf);
|
printf("INFO version %d\n", *buf);
|
||||||
five_25 = (buf[1]==1);
|
five_25 = (buf[1]==1);
|
||||||
printf("Disk type: %s\n", five_25 ? "5.25" : buf[1]==2 ? "3.5" : "?");
|
printf("Disk type: %s\n", five_25 ? "5.25" : buf[1]==2 ? "3.5" : "?");
|
||||||
writable = !(buf[2]==1);
|
this->writable = !(buf[2]==1);
|
||||||
printf("Write protected?: %s\n", writable ? "No" : "Yes");
|
printf("Write protected?: %s\n", this->writable ? "No" : "Yes");
|
||||||
printf("Imaged with cross-track sync?: %s\n", buf[3]==1 ? "Yes" : "No");
|
printf("Imaged with cross-track sync?: %s\n", buf[3]==1 ? "Yes" : "No");
|
||||||
printf("MC3470 fake bits removed?: %s\n", buf[4]==1 ? "Yes" : "No");
|
printf("MC3470 fake bits removed?: %s\n", buf[4]==1 ? "Yes" : "No");
|
||||||
printf("Creator: \"%.32s\"\n", buf+5);
|
printf("Creator: \"%.32s\"\n", buf+5);
|
||||||
@ -103,7 +104,7 @@ bool WozFile::load(const std::string& filePath) {
|
|||||||
}
|
}
|
||||||
printf("\x1b[31;47m-------------------------------------------\x1b[0m\n");
|
printf("\x1b[31;47m-------------------------------------------\x1b[0m\n");
|
||||||
for (std::uint8_t qt(0); qt <= 140; ++qt) {
|
for (std::uint8_t qt(0); qt <= 140; ++qt) {
|
||||||
tmap[qt] = buf[qt];
|
this->tmap[qt] = buf[qt];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
delete[] buf;
|
delete[] buf;
|
||||||
@ -115,18 +116,18 @@ bool WozFile::load(const std::string& filePath) {
|
|||||||
if (chunk_size % 6656) {
|
if (chunk_size % 6656) {
|
||||||
printf("chunk size is not an even multiple of 6656.");
|
printf("chunk size is not an even multiple of 6656.");
|
||||||
}
|
}
|
||||||
c_trks = chunk_size / 6656;
|
this->c_trks = chunk_size / 6656;
|
||||||
printf("Count of tracks: 0x%02X\n", c_trks);
|
printf("Count of tracks: 0x%02X\n", this->c_trks);
|
||||||
if (c_trks > 141) {
|
if (this->c_trks > 141) {
|
||||||
printf("Error: cannot handle more than 141 tracks.");
|
printf("Error: cannot handle more than 141 tracks.");
|
||||||
throw "Error: cannot handle more than 141 tracks";
|
throw "Error: cannot handle more than 141 tracks";
|
||||||
}
|
}
|
||||||
for (std::uint8_t t(0); t < c_trks; ++t) {
|
for (std::uint8_t t(0); t < this->c_trks; ++t) {
|
||||||
printf("track 0x%02X:\n", t);
|
printf("track 0x%02X:\n", t);
|
||||||
std::uint16_t usedBytes = *(std::uint16_t*)&buf[t*6656+6646+0];
|
std::uint16_t usedBytes = *(std::uint16_t*)&buf[t*6656+6646+0];
|
||||||
printf(" used bytes: 0x%0X\n", usedBytes);
|
printf(" used bytes: 0x%0X\n", usedBytes);
|
||||||
trk_bits[t] = *(std::uint16_t*)&buf[t*6656+6646+2];
|
this->trk_bits[t] = *(std::uint16_t*)&buf[t*6656+6646+2];
|
||||||
printf(" count of bits: 0x%0X\n", trk_bits[t]);
|
printf(" count of bits: 0x%0X\n", this->trk_bits[t]);
|
||||||
std::uint16_t spliceBit = *(std::uint16_t*)&buf[t*6656+6646+4];
|
std::uint16_t spliceBit = *(std::uint16_t*)&buf[t*6656+6646+4];
|
||||||
if (spliceBit == 0xFFFFu) {
|
if (spliceBit == 0xFFFFu) {
|
||||||
printf(" no splice information exists\n");
|
printf(" no splice information exists\n");
|
||||||
@ -146,7 +147,7 @@ bool WozFile::load(const std::string& filePath) {
|
|||||||
}
|
}
|
||||||
printf("\n");
|
printf("\n");
|
||||||
for (int i(0); i < 6646; ++i) {
|
for (int i(0); i < 6646; ++i) {
|
||||||
trks[t][i] = *base++;
|
this->trks[t][i] = *base++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
delete[] buf;
|
delete[] buf;
|
||||||
@ -251,15 +252,6 @@ static std::uint8_t cb(std::uint8_t bit) {
|
|||||||
return 255u; // should never happen
|
return 255u; // should never happen
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dumpQTrack(std::uint8_t currentQuarterTrack) {
|
|
||||||
if (currentQuarterTrack % 4) {
|
|
||||||
const std::uint8_t hundredths((currentQuarterTrack%4) * 25);
|
|
||||||
printf(" Reading from <---------- track 0x%02X +.%02d\n", currentQuarterTrack/4, hundredths);
|
|
||||||
} else {
|
|
||||||
printf(" Reading from <---------- track 0x%02X\n", currentQuarterTrack/4);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Rotate the floppy disk by one bit.
|
* Rotate the floppy disk by one bit.
|
||||||
* In real life we don't care what track we're one, but for the
|
* In real life we don't care what track we're one, but for the
|
||||||
@ -274,14 +266,7 @@ void WozFile::rotateOneBit(std::uint8_t currentQuarterTrack) {
|
|||||||
return; // there's no disk to rotate
|
return; // there's no disk to rotate
|
||||||
}
|
}
|
||||||
|
|
||||||
// In WOZ track image, bits (i.e., magnetic field reversal on disk,
|
// Move to next bit
|
||||||
// or lack thereof) are packed into bytes, high bit to low bit.
|
|
||||||
// Really, it's the stream of bits returned by the MC3470 (but also
|
|
||||||
// possibly with random bits zeroed out).
|
|
||||||
// std::uint16_t before = (this->byt*8+bc(this->bit));
|
|
||||||
// printf("disk at bit: %d\n", this->byt*8+bc(this->bit));
|
|
||||||
|
|
||||||
// Move to next bit:
|
|
||||||
this->bit >>= 1;
|
this->bit >>= 1;
|
||||||
|
|
||||||
// If we hit end of this byte, move on to beginning of next byte
|
// If we hit end of this byte, move on to beginning of next byte
|
||||||
@ -290,78 +275,81 @@ void WozFile::rotateOneBit(std::uint8_t currentQuarterTrack) {
|
|||||||
this->bit = 0x80u;
|
this->bit = 0x80u;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// this is an empty track, so any of the following byte/bit
|
||||||
|
// adjustments don't apply now (they will be handled the
|
||||||
|
// next time we hit a non-empty track)
|
||||||
if (this->tmap[currentQuarterTrack] == 0xFFu) {
|
if (this->tmap[currentQuarterTrack] == 0xFFu) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If we changed tracks since the last time we were called,
|
||||||
|
// we may need to adjust the rotational position. The new
|
||||||
|
// position will be at the same relative position as the
|
||||||
|
// previous, based on each track's length (tracks can be of
|
||||||
|
// different lengths in the WOZ image).
|
||||||
if (currentQuarterTrack != this->lastQuarterTrack) {
|
if (currentQuarterTrack != this->lastQuarterTrack) {
|
||||||
double oldLen = this->trk_bits[this->tmap[this->lastQuarterTrack]];
|
double oldLen = this->trk_bits[this->tmap[this->lastQuarterTrack]];
|
||||||
double newLen = this->trk_bits[this->tmap[currentQuarterTrack]];
|
double newLen = this->trk_bits[this->tmap[currentQuarterTrack]];
|
||||||
double dif = newLen/oldLen;
|
double ratio = newLen/oldLen;
|
||||||
if (dif < -0.000001 || 0.000001 < dif) {
|
if (!(fabs(1-ratio) < 0.0001f)) {
|
||||||
// dumpQTrack(currentQuarterTrack);
|
std::uint16_t newBit = (this->byt*8+bc(this->bit)) * ratio;
|
||||||
// printf(" new track: bit pos: %d ", this->byt*8+bc(this->bit));
|
|
||||||
std::uint16_t newBit = (this->byt*8+bc(this->bit)) * dif;
|
|
||||||
this->byt = newBit / 8;
|
this->byt = newBit / 8;
|
||||||
this->bit = cb(newBit % 8);
|
this->bit = cb(newBit % 8);
|
||||||
// printf("--> %d\n\n", this->byt*8+bc(this->bit));
|
|
||||||
}
|
}
|
||||||
this->lastQuarterTrack = currentQuarterTrack;
|
this->lastQuarterTrack = currentQuarterTrack;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for hitting the end of our track image,
|
// Check for hitting the end of our track,
|
||||||
// and if so, move back to the beginning.
|
// and if so, move back to the beginning.
|
||||||
// This is how we emulate a circular track on the floppy.
|
// This is how we emulate a circular track on the floppy.
|
||||||
if (this->trk_bits[this->tmap[currentQuarterTrack]] <= this->byt*8+bc(this->bit)) {
|
if (this->trk_bits[this->tmap[currentQuarterTrack]] <= this->byt*8+bc(this->bit)) {
|
||||||
// printf("\n<rewinding track here>\n");
|
|
||||||
this->byt = 0;
|
this->byt = 0;
|
||||||
this->bit = 0x80u;
|
this->bit = 0x80u;
|
||||||
}
|
}
|
||||||
|
|
||||||
// std::uint16_t after = (this->byt*8+bc(this->bit));
|
|
||||||
// if (!(after % 0x100u)) {
|
|
||||||
// printf("\nnow at bit %04x\n", after);
|
|
||||||
// }
|
|
||||||
// if (after != before+1) {
|
|
||||||
// printf("\nbit changing from %04x to %04x\n", before, after);
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool WozFile::getBit(std::uint8_t currentQuarterTrack) {
|
bool WozFile::getBit(std::uint8_t currentQuarterTrack) {
|
||||||
if (!isLoaded()) {
|
if (!isLoaded()) {
|
||||||
printf("\nNO DISK TO READ FROM (will generate random data)\n");
|
printf("No disk to read from; will generate random data.\n");
|
||||||
return false; // there's no disk, so no pulse
|
return false; // there's no disk, so no pulse
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->tmap[currentQuarterTrack] == 0xFFu) {
|
if (this->tmap[currentQuarterTrack] == 0xFFu) {
|
||||||
// printf("\nreading (random) from empty q-track: %d\n", currentQuarterTrack);
|
return false; // empty track
|
||||||
return false; // track doesn't exist
|
}
|
||||||
}
|
|
||||||
if (this->c_trks <= this->tmap[currentQuarterTrack]) { // shouldn't happen
|
if (this->c_trks <= this->tmap[currentQuarterTrack]) { // shouldn't happen
|
||||||
printf("\nBAD TRACK quarterTrack %d mapped to TRKS index %d (count of tracks: %d)\n", currentQuarterTrack, this->tmap[currentQuarterTrack], this->c_trks);
|
printf("INVALID quarterTrack %d mapped to TRKS index %d (count of tracks: %d)\n", currentQuarterTrack, this->tmap[currentQuarterTrack], this->c_trks);
|
||||||
return false; // track doesn't exist
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (!(this->byt % 128) && this->bit == 0x01) {
|
|
||||||
// printf("\ngetBit--> ");
|
|
||||||
// }
|
|
||||||
// printf("%02x", this->byt*8+bc(this->bit));
|
|
||||||
return this->trks[this->tmap[currentQuarterTrack]][this->byt] & this->bit;
|
return this->trks[this->tmap[currentQuarterTrack]][this->byt] & this->bit;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WozFile::setBit(std::uint8_t currentQuarterTrack) {
|
void WozFile::setBit(std::uint8_t currentQuarterTrack, bool on) {
|
||||||
if (!isLoaded()) {
|
if (!isLoaded()) {
|
||||||
return; // there's no disk to write data to
|
return; // there's no disk to write data to
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this->writable) {
|
if (!this->writable) {
|
||||||
return; // write-protected
|
return; // write-protected
|
||||||
}
|
}
|
||||||
if (this->c_trks <= this->tmap[currentQuarterTrack]) { // shouldn't happen
|
|
||||||
|
if (this->c_trks <= this->tmap[currentQuarterTrack]) {
|
||||||
return; // TODO track doesn't exist: create a new one
|
return; // TODO track doesn't exist: create a new one
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->tmap[currentQuarterTrack] == 0xFFu) {
|
if (this->tmap[currentQuarterTrack] == 0xFFu) {
|
||||||
// track does not exist, create new one
|
// track does not exist, create new one
|
||||||
}
|
}
|
||||||
// TODO extend track length if needed
|
|
||||||
|
// TODO extend track length if needed????
|
||||||
|
|
||||||
|
if (on) {
|
||||||
this->trks[this->tmap[currentQuarterTrack]][this->byt] |= this->bit;
|
this->trks[this->tmap[currentQuarterTrack]][this->byt] |= this->bit;
|
||||||
|
} else {
|
||||||
|
this->trks[this->tmap[currentQuarterTrack]][this->byt] &= ~this->bit;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -59,6 +59,10 @@ class WozFile {
|
|||||||
std::uint8_t bit;
|
std::uint8_t bit;
|
||||||
std::uint16_t byt;
|
std::uint16_t byt;
|
||||||
|
|
||||||
|
// We need to store which track were on, only so we can detect
|
||||||
|
// a change in tracks, and if so adjust our current byt/bit
|
||||||
|
// to be proportional with the new track. This is discussed
|
||||||
|
// in the WOZ file spec.
|
||||||
std::uint8_t lastQuarterTrack;
|
std::uint8_t lastQuarterTrack;
|
||||||
|
|
||||||
void checkForWriteProtection();
|
void checkForWriteProtection();
|
||||||
@ -89,7 +93,7 @@ public:
|
|||||||
|
|
||||||
void rotateOneBit(std::uint8_t currentQuarterTrack);
|
void rotateOneBit(std::uint8_t currentQuarterTrack);
|
||||||
bool getBit(std::uint8_t currentQuarterTrack);
|
bool getBit(std::uint8_t currentQuarterTrack);
|
||||||
void setBit(std::uint8_t currentQuarterTrack);
|
void setBit(std::uint8_t currentQuarterTrack, bool on);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // WOZFILE_H
|
#endif // WOZFILE_H
|
||||||
|
Loading…
Reference in New Issue
Block a user