diff --git a/README.md b/README.md
index 36619cd..bb7909d 100644
--- a/README.md
+++ b/README.md
@@ -13,11 +13,13 @@ The BKBTL project consists of:
* [**bkbtl-doc**](https://github.com/nzeemin/bkbtl-doc) — documentation and screenshots.
* Project wiki: https://github.com/nzeemin/bkbtl-doc/wiki
+
## Как запустить под Linux
### Собрать из исходников
- 1. Установить пакеты: Qt 5.15.2 + QtScript
+ 1. Установить пакеты: Qt 5 + QtScript
+ `sudo apt install qtbase5-dev qt5-qmake qtscript5-dev`
2. Скачать исходники: либо через
`git clone https://github.com/nzeemin/bkbtl-qt.git`
либо скачать как .zip и распаковать
@@ -25,8 +27,8 @@ The BKBTL project consists of:
`cd emulator`
`qmake "CONFIG+=release" QtBkBtl.pro`
`make`
- 4. Даём права на выполнение: `chmod +x QtBkBtl`
- 5. Запускаем `QtBkBtl`
+ 4. Дать права на выполнение: `chmod +x QtBkBtl`
+ 5. Запустить `QtBkBtl`
6. Если при запуске появилось сообщение вида `Failed to load Monitor ROM file.`, то
скачать .rom файлы от [BKBTL](https://github.com/nzeemin/bkbtl/tree/master/roms), положить в ту же папку где лежит файл `QtBkBtl`, запустить снова
@@ -34,5 +36,6 @@ The BKBTL project consists of:
1. Зайти в [Releases](https://github.com/nzeemin/bkbtl-qt/releases) найти последний AppImage-релиз и скачать `*.AppImage` файл
2. Дать права на выполнение: `chmod +x BKBTL_Qt-9cc9d83-x86_64.AppImage` (подставить тут правильное название AppImage файла)
- 3. Если при запуске появилось сообщение вида `Failed to load Monitor ROM file.`, то
+ 3. Запустить AppImage файл
+ 4. Если при запуске появилось сообщение вида `Failed to load Monitor ROM file.`, то
скачать .rom файлы от [BKBTL](https://github.com/nzeemin/bkbtl/tree/master/roms), положить в ту же папку где лежит AppImage файл, запустить снова
diff --git a/emulator/emubase/Board.cpp b/emulator/emubase/Board.cpp
index 43b8844..eabbfff 100644
--- a/emulator/emubase/Board.cpp
+++ b/emulator/emubase/Board.cpp
@@ -36,7 +36,7 @@ CMotherboard::CMotherboard() :
m_CPUbps = nullptr;
// Allocate memory for RAM and ROM
- m_pRAM = static_cast(::malloc(128 * 1024)); //::memset(m_pRAM, 0, 128 * 1024);
+ m_pRAM = static_cast(::calloc(128 * 1024, 1));
m_pROM = static_cast(::calloc(64 * 1024, 1));
SetConfiguration(BK_CONF_BK0010_BASIC); // Default configuration
@@ -52,8 +52,8 @@ CMotherboard::~CMotherboard()
delete m_pSoundAY;
// Free memory
- ::free(m_pRAM);
- ::free(m_pROM);
+ ::free(m_pRAM); m_pRAM = nullptr;
+ ::free(m_pROM); m_pROM = nullptr;
}
void CMotherboard::SetConfiguration(uint16_t conf)
@@ -192,7 +192,7 @@ void CMotherboard::DetachFloppyImage(int slot)
uint16_t CMotherboard::GetRAMWord(uint16_t offset) const
{
- return *((uint16_t*)(m_pRAM + offset));
+ return *reinterpret_cast(m_pRAM + offset);
}
uint16_t CMotherboard::GetRAMWord(uint8_t chunk, uint16_t offset) const
{
@@ -210,12 +210,12 @@ uint8_t CMotherboard::GetRAMByte(uint8_t chunk, uint16_t offset) const
}
void CMotherboard::SetRAMWord(uint16_t offset, uint16_t word)
{
- *((uint16_t*)(m_pRAM + offset)) = word;
+ *reinterpret_cast(m_pRAM + offset) = word;
}
void CMotherboard::SetRAMWord(uint8_t chunk, uint16_t offset, uint16_t word)
{
uint32_t dwOffset = ((static_cast(chunk) & 7) << 14) + offset;
- *((uint16_t*)(m_pRAM + dwOffset)) = word;
+ *reinterpret_cast(m_pRAM + dwOffset) = word;
}
void CMotherboard::SetRAMByte(uint16_t offset, uint8_t byte)
{
@@ -364,7 +364,7 @@ bool CMotherboard::SystemFrame()
const int audioticks = 20286 / (SOUNDSAMPLERATE / 25);
m_SoundChanges = 0;
const int teletypeTicks = 20000 / (9600 / 25);
- int floppyTicks = (m_Configuration & BK_COPT_BK0011) ? 38 : 44;
+ int floppyTicks = (m_Configuration & BK_COPT_BK0011) ? 38 : 32;
int teletypeTxCount = 0;
int frameTapeTicks = 0, tapeSamplesPerFrame = 0, tapeReadError = 0;
diff --git a/emulator/emubase/Disasm.cpp b/emulator/emubase/Disasm.cpp
index e6dfb42..8034235 100644
--- a/emulator/emubase/Disasm.cpp
+++ b/emulator/emubase/Disasm.cpp
@@ -232,7 +232,7 @@ uint16_t DisassembleInstruction(const uint16_t* pMemory, uint16_t addr, TCHAR* s
}
length = 1;
- _sntprintf(strDst, strDstSize - 1, _T("%06o"), addr + ((short)(char)static_cast(instr & 0xff) * 2) + 2);
+ _sntprintf(strDst, strDstSize - 1, _T("%06ho"), (uint16_t)(addr + ((short)(char)(uint8_t)(instr & 0xff) * 2) + 2));
// Branches & interrupts
switch (instr & ~static_cast(0377))
@@ -713,7 +713,8 @@ void Disasm_InstructionHint(const uint16_t* memory, const CProcessor * pProc, co
// Prepare "Instruction Hint" for a regular instruction (not a branch/jump one)
// buffer, buffer2 - buffers for 1st and 2nd lines of the instruction hint, min size 42
// Returns: number of hint lines; 0 = no hints
-int Disasm_GetInstructionHint(const uint16_t* memory, const CProcessor * pProc, const CMotherboard * pBoard,
+int Disasm_GetInstructionHint(const uint16_t* memory, const CProcessor * pProc,
+ const CMotherboard * pBoard,
LPTSTR buffer, LPTSTR buffer2)
{
const size_t buffersize = 42;
diff --git a/emulator/emubase/Emubase.h b/emulator/emubase/Emubase.h
index 1abff5e..a08ae24 100644
--- a/emulator/emubase/Emubase.h
+++ b/emulator/emubase/Emubase.h
@@ -53,14 +53,14 @@ int Disasm_GetInstructionHint(
#define FLOPPY_FSM_IDLE 0
-#define FLOPPY_CMD_CORRECTION250 04
-#define FLOPPY_CMD_CORRECTION500 010
#define FLOPPY_CMD_ENGINESTART 020
#define FLOPPY_CMD_SIDEUP 040
#define FLOPPY_CMD_DIR 0100
#define FLOPPY_CMD_STEP 0200
-#define FLOPPY_CMD_SEARCHSYNC 0400
-#define FLOPPY_CMD_SKIPSYNC 01000
+#define FLOPPY_CMD_READDATA 0400
+#define FLOPPY_CMD_WRITEMARKER 01000
+#define FLOPPY_CMD_PRECORRECTION 02000
+
//dir == 0 to center (towards trk0)
//dir == 1 from center (towards trk80)
@@ -108,6 +108,7 @@ class CFloppyController
bool m_shiftflag; // Write mode shift register has data
bool m_shiftmarker; // Write marker in m_marker
bool m_writing; // TRUE = write mode, false = read mode
+ bool m_searchsynctrig; // Search for sync trigger
bool m_searchsync; // Read sub-mode: TRUE = search for sync, false = just read
bool m_crccalculus; // TRUE = CRC is calculated now
bool m_trackchanged; // TRUE = m_data was changed - need to save it into the file
@@ -124,8 +125,8 @@ class CFloppyController
bool IsAttached(int drive) const { return (m_drivedata[drive].fpFile != nullptr); }
bool IsReadOnly(int drive) const { return m_drivedata[drive].okReadOnly; } // return (m_status & FLOPPY_STATUS_WRITEPROTECT) != 0; }
bool IsEngineOn() { return (m_flags & FLOPPY_CMD_ENGINESTART) != 0; }
- uint16_t GetData(void); // Reading port 177132 - data
- uint16_t GetState(void); // Reading port 177130 - device status
+ uint16_t GetData(); // Reading port 177132 - data
+ uint16_t GetState(); // Reading port 177130 - device status
uint16_t GetDataView() const { return m_datareg; } // Get port 177132 value for debugger
uint16_t GetStateView() const { return m_status; } // Get port 177130 value for debugger
void SetCommand(uint16_t cmd); // Writing to port 177130 - commands
diff --git a/emulator/emubase/Floppy.cpp b/emulator/emubase/Floppy.cpp
index c7530f5..d425c47 100644
--- a/emulator/emubase/Floppy.cpp
+++ b/emulator/emubase/Floppy.cpp
@@ -22,8 +22,9 @@ BKBTL. If not, see . */
// Маска флагов, сохраняемых в m_flags
const uint16_t FLOPPY_CMD_MASKSTORED =
- FLOPPY_CMD_CORRECTION250 | FLOPPY_CMD_CORRECTION500 | FLOPPY_CMD_SIDEUP | FLOPPY_CMD_DIR | FLOPPY_CMD_SKIPSYNC |
- FLOPPY_CMD_ENGINESTART;
+ 0x000F | // Floppy drive selection bits
+ FLOPPY_CMD_ENGINESTART | FLOPPY_CMD_SIDEUP | FLOPPY_CMD_DIR | FLOPPY_CMD_STEP | FLOPPY_CMD_READDATA |
+ FLOPPY_CMD_WRITEMARKER | FLOPPY_CMD_PRECORRECTION;
static void EncodeTrackData(const uint8_t* pSrc, uint8_t* data, uint8_t* marker, uint16_t track, uint16_t side);
static bool DecodeTrackData(const uint8_t* pRaw, uint8_t* pDest);
@@ -33,7 +34,7 @@ static bool DecodeTrackData(const uint8_t* pRaw, uint8_t* pDest);
CFloppyDrive::CFloppyDrive()
{
- fpFile = NULL;
+ fpFile = nullptr;
okReadOnly = false;
datatrack = dataside = 0;
dataptr = 0;
@@ -53,14 +54,16 @@ void CFloppyDrive::Reset()
CFloppyController::CFloppyController()
{
- m_drive = m_side = m_track = 0;
- m_pDrive = NULL;
+ m_side = m_track = 0;
+ m_drive = -1;
+ m_pDrive = nullptr;
m_datareg = m_writereg = m_shiftreg = 0;
+ m_searchsynctrig = false;
m_writing = m_searchsync = m_writemarker = m_crccalculus = false;
m_writeflag = m_shiftflag = m_shiftmarker = false;
m_trackchanged = false;
- m_status = FLOPPY_STATUS_TRACK0 | FLOPPY_STATUS_WRITEPROTECT;
- m_flags = FLOPPY_CMD_CORRECTION500 | FLOPPY_CMD_SIDEUP | FLOPPY_CMD_DIR | FLOPPY_CMD_SKIPSYNC;
+ m_status = FLOPPY_STATUS_TRACK0;
+ m_flags = FLOPPY_CMD_SIDEUP | FLOPPY_CMD_DIR | FLOPPY_CMD_WRITEMARKER;
m_okTrace = false;
}
@@ -72,37 +75,41 @@ CFloppyController::~CFloppyController()
void CFloppyController::Reset()
{
+ if (m_okTrace) DebugLog(_T("Floppy RESET\r\n"));
+
FlushChanges();
- m_drive = m_side = m_track = 0;
- m_pDrive = NULL;
+ m_side = m_track = 0;
+ m_drive = -1;
+ m_pDrive = nullptr;
m_datareg = m_writereg = m_shiftreg = 0;
+ m_searchsynctrig = false;
m_writing = m_searchsync = m_writemarker = m_crccalculus = false;
m_writeflag = m_shiftflag = false;
m_trackchanged = false;
- m_status = FLOPPY_STATUS_TRACK0 | FLOPPY_STATUS_WRITEPROTECT;
- m_flags = FLOPPY_CMD_CORRECTION500 | FLOPPY_CMD_SIDEUP | FLOPPY_CMD_DIR | FLOPPY_CMD_SKIPSYNC;
+ m_status = FLOPPY_STATUS_TRACK0;
+ m_flags = FLOPPY_CMD_SIDEUP | FLOPPY_CMD_DIR | FLOPPY_CMD_WRITEMARKER;
PrepareTrack();
}
bool CFloppyController::AttachImage(int drive, LPCTSTR sFileName)
{
- ASSERT(sFileName != NULL);
+ ASSERT(sFileName != nullptr);
// If image attached - detach one first
- if (m_drivedata[drive].fpFile != NULL)
+ if (m_drivedata[drive].fpFile != nullptr)
DetachImage(drive);
// Open file
m_drivedata[drive].okReadOnly = false;
m_drivedata[drive].fpFile = ::_tfopen(sFileName, _T("r+b"));
- if (m_drivedata[drive].fpFile == NULL)
+ if (m_drivedata[drive].fpFile == nullptr)
{
m_drivedata[drive].okReadOnly = true;
m_drivedata[drive].fpFile = ::_tfopen(sFileName, _T("rb"));
}
- if (m_drivedata[drive].fpFile == NULL)
+ if (m_drivedata[drive].fpFile == nullptr)
return false;
m_side = m_track = m_drivedata[drive].datatrack = m_drivedata[drive].dataside = 0;
@@ -111,8 +118,8 @@ bool CFloppyController::AttachImage(int drive, LPCTSTR sFileName)
m_writing = m_searchsync = m_writemarker = m_crccalculus = false;
m_writeflag = m_shiftflag = false;
m_trackchanged = false;
- m_status = FLOPPY_STATUS_TRACK0 | FLOPPY_STATUS_WRITEPROTECT;
- m_flags = FLOPPY_CMD_CORRECTION500 | FLOPPY_CMD_SIDEUP | FLOPPY_CMD_DIR | FLOPPY_CMD_SKIPSYNC;
+ m_status = (m_pDrive != nullptr && m_pDrive->okReadOnly) ? FLOPPY_STATUS_TRACK0 | FLOPPY_STATUS_WRITEPROTECT : FLOPPY_STATUS_TRACK0;
+ m_flags = FLOPPY_CMD_SIDEUP | FLOPPY_CMD_DIR | FLOPPY_CMD_WRITEMARKER;
PrepareTrack();
@@ -121,12 +128,12 @@ bool CFloppyController::AttachImage(int drive, LPCTSTR sFileName)
void CFloppyController::DetachImage(int drive)
{
- if (m_drivedata[drive].fpFile == NULL) return;
+ if (m_drivedata[drive].fpFile == nullptr) return;
FlushChanges();
::fclose(m_drivedata[drive].fpFile);
- m_drivedata[drive].fpFile = NULL;
+ m_drivedata[drive].fpFile = nullptr;
m_drivedata[drive].okReadOnly = false;
m_drivedata[drive].Reset();
}
@@ -134,11 +141,11 @@ void CFloppyController::DetachImage(int drive)
//////////////////////////////////////////////////////////////////////
-uint16_t CFloppyController::GetState(void)
+uint16_t CFloppyController::GetState()
{
- if (m_pDrive == NULL)
+ if (m_pDrive == nullptr)
return 0;
- if (m_pDrive->fpFile == NULL)
+ if (m_pDrive->fpFile == nullptr)
return FLOPPY_STATUS_INDEXMARK | (m_track == 0 ? FLOPPY_STATUS_TRACK0 : 0);
if (m_track == 0)
@@ -146,17 +153,17 @@ uint16_t CFloppyController::GetState(void)
else
m_status &= ~FLOPPY_STATUS_TRACK0;
- if (m_pDrive->dataptr >= FLOPPY_RAWTRACKSIZE - FLOPPY_INDEXLENGTH)
+ if (m_pDrive->dataptr < FLOPPY_INDEXLENGTH)
m_status |= FLOPPY_STATUS_INDEXMARK;
else
m_status &= ~FLOPPY_STATUS_INDEXMARK;
- uint16_t res = m_status /*| FLOPPY_STATUS_RDY*/;
-
-// if (res & FLOPPY_STATUS_MOREDATA)
-// DebugLogFormat(_T("Floppy GET STATE %06o\r\n"), res);
+ if (IsEngineOn())
+ m_status |= FLOPPY_STATUS_RDY;
+ else
+ m_status &= ~(FLOPPY_STATUS_RDY | FLOPPY_STATUS_MOREDATA | FLOPPY_STATUS_CHECKSUMOK);
- return res;
+ return m_status;
}
void CFloppyController::SetCommand(uint16_t cmd)
@@ -164,25 +171,23 @@ void CFloppyController::SetCommand(uint16_t cmd)
// if (m_okTrace)
// DebugLogFormat(_T("Floppy COMMAND %06o\r\n"), cmd);
+ // Copy new flags to m_flags
+ m_flags &= ~FLOPPY_CMD_MASKSTORED;
+ m_flags |= cmd & FLOPPY_CMD_MASKSTORED;
+
bool okPrepareTrack = false; // Нужно ли считывать дорожку в буфер
- // Проверить, не сменился ли текущий привод
- int newdrive = -1;
- switch (cmd & 0x0f)
- {
- case 0: newdrive = -1; break;
-case 1: default: newdrive = 0; break;
- case 2: case 6: case 10: case 14: newdrive = 1; break;
- case 4: case 12: newdrive = 2; break;
- case 8: newdrive = 3; break;
- }
+ // Проверить, не сменился ли текущий привод;
+ // тут выбирается текущий привод, чем более младший бит, тем больше приоритет;
+ // если установлено несколько битов - выбирается тот, что младше.
+ int newdrive = (cmd & 1) ? 0 : (cmd & 2) ? 1 : (cmd & 4) ? 2 : (cmd & 8) ? 3 : -1;
if (m_drive != newdrive)
{
FlushChanges();
m_drive = newdrive;
- m_pDrive = (newdrive == -1) ? NULL : m_drivedata + m_drive;
+ m_pDrive = (newdrive == -1) ? nullptr : m_drivedata + m_drive;
okPrepareTrack = true;
if (m_okTrace)
@@ -190,11 +195,6 @@ case 1: default: newdrive = 0; break;
}
if (m_drive == -1)
return;
- cmd &= ~3; // Убираем из команды информацию о текущем приводе
-
- // Copy new flags to m_flags
- m_flags &= ~FLOPPY_CMD_MASKSTORED;
- m_flags |= cmd & FLOPPY_CMD_MASKSTORED;
// Проверяем, не сменилась ли сторона
if (m_flags & FLOPPY_CMD_SIDEUP) // Side selection: 0 - down, 1 - up
@@ -206,13 +206,11 @@ case 1: default: newdrive = 0; break;
if (m_side == 1) { m_side = 0; okPrepareTrack = true; }
}
- if (cmd & FLOPPY_CMD_STEP) // Move head for one track to center or from center
+ if (m_flags & FLOPPY_CMD_STEP) // Move head for one track to center or from center
{
if (m_okTrace)
DebugLogFormat(_T("Floppy STEP %d\r\n"), (m_flags & FLOPPY_CMD_DIR) ? 1 : 0);
- m_side = (m_flags & FLOPPY_CMD_SIDEUP) ? 1 : 0;
-
if (m_flags & FLOPPY_CMD_DIR)
{
if (m_track < 82) { m_track++; okPrepareTrack = true; }
@@ -221,34 +219,40 @@ case 1: default: newdrive = 0; break;
{
if (m_track >= 1) { m_track--; okPrepareTrack = true; }
}
+
+ if (m_track == 0)
+ m_status |= FLOPPY_STATUS_TRACK0;
+ else
+ m_status &= ~FLOPPY_STATUS_TRACK0;
}
if (okPrepareTrack)
PrepareTrack();
- if (cmd & FLOPPY_CMD_SEARCHSYNC) // Search for marker
+ if (m_flags & FLOPPY_CMD_READDATA) // Search for marker
{
if (m_okTrace)
DebugLog(_T("Floppy SEARCHSYNC\r\n"));
- m_flags &= ~FLOPPY_CMD_SEARCHSYNC;
+ m_searchsynctrig = true;
+ }
+ else if (m_searchsynctrig)
+ {
+ m_searchsynctrig = false;
m_searchsync = true;
m_crccalculus = true;
- m_status &= ~FLOPPY_STATUS_CHECKSUMOK;
+ m_status &= ~(FLOPPY_STATUS_CHECKSUMOK | FLOPPY_STATUS_MOREDATA);
}
- if (m_writing && (cmd & FLOPPY_CMD_SKIPSYNC)) // Запись маркера
+ if (m_writing && (cmd & FLOPPY_CMD_WRITEMARKER)) // Запись маркера
{
-
-// DebugLog(_T("Floppy MARKER\r\n")); //DEBUG
-
m_writemarker = true;
- m_status &= ~FLOPPY_STATUS_CHECKSUMOK;
+ m_status &= ~(FLOPPY_STATUS_CHECKSUMOK | FLOPPY_STATUS_MOREDATA);
}
}
uint16_t CFloppyController::GetData(void)
{
- if (m_okTrace && m_pDrive != NULL)
+ if (m_okTrace && m_pDrive != nullptr)
{
uint16_t offset = m_pDrive->dataptr;
if (offset >= 102 && (offset - 102) % 610 == 0)
@@ -259,7 +263,7 @@ uint16_t CFloppyController::GetData(void)
m_writing = m_searchsync = false;
m_writeflag = m_shiftflag = false;
- if (m_pDrive == NULL || m_pDrive->fpFile == NULL)
+ if (m_pDrive == nullptr || m_pDrive->fpFile == nullptr)
return 0;
return m_datareg;
@@ -311,11 +315,11 @@ void CFloppyController::Periodic()
m_drivedata[drive].dataptr = 0;
}
- if (m_okTrace && m_pDrive != NULL && m_pDrive->dataptr == 0)
+ if (m_okTrace && m_pDrive != nullptr && m_pDrive->dataptr == 0)
DebugLogFormat(_T("Floppy Index\n"));
// Далее обрабатываем чтение/запись на текущем драйве
- if (m_pDrive == NULL) return;
+ if (m_pDrive == nullptr) return;
if (!IsAttached(m_drive)) return;
if (!m_writing) // Read mode
@@ -400,7 +404,7 @@ void CFloppyController::PrepareTrack()
{
FlushChanges();
- if (m_pDrive == NULL) return;
+ if (m_pDrive == nullptr) return;
if (m_okTrace)
DebugLogFormat(_T("Floppy Prepare Track\tTRACK %d SIDE %d\r\n"), m_track, m_side);
@@ -419,7 +423,7 @@ void CFloppyController::PrepareTrack()
uint8_t data[5120];
memset(data, 0, 5120);
- if (m_pDrive->fpFile != NULL)
+ if (m_pDrive->fpFile != nullptr)
{
::fseek(m_pDrive->fpFile, foffset, SEEK_SET);
count = (uint32_t) ::fread(data, 1, 5120, m_pDrive->fpFile);
@@ -495,6 +499,22 @@ void CFloppyController::FlushChanges()
//////////////////////////////////////////////////////////////////////
+uint16_t getCrc(const uint8_t *ptr, size_t len)
+{
+ int crc = 0xffff;
+ while (len--)
+ {
+ uint8_t val = *ptr++;
+ crc ^= val << 8;
+ for (int i = 0; i < 8; ++i)
+ {
+ if ((crc <<= 1) & 0x10000)
+ crc ^= 0x1021;
+ }
+ }
+ return (crc & 0xffff);
+}
+
// Fill data array and marker array with marked data
static void EncodeTrackData(const uint8_t* pSrc, uint8_t* data, uint8_t* marker, uint16_t track, uint16_t side)
{
@@ -512,14 +532,15 @@ static void EncodeTrackData(const uint8_t* pSrc, uint8_t* data, uint8_t* marker,
for (count = 0; count < 12; count++) data[ptr++] = 0x00;
// marker
marker[ptr / 2] = true; // ID marker; start CRC calculus
+ uint8_t *pCrcPtr = data + ptr; size_t nCrcPtr = ptr;
data[ptr++] = 0xa1; data[ptr++] = 0xa1; data[ptr++] = 0xa1;
data[ptr++] = 0xfe;
- data[ptr++] = (uint8_t) track; data[ptr++] = (side != 0);
+ data[ptr++] = (uint8_t) track; data[ptr++] = (side == 0) ? 0 : 1;
data[ptr++] = sect + 1; data[ptr++] = 2; // Assume 512 bytes per sector;
// crc
- //TODO: Calculate CRC
- data[ptr++] = 0x12; data[ptr++] = 0x34; // CRC stub
+ uint16_t crc = getCrc(pCrcPtr, ptr - nCrcPtr);
+ data[ptr++] = (uint8_t)(crc & 0xff); data[ptr++] = (uint8_t)(crc >> 8);
// sync
for (count = 0; count < 22; count++) data[ptr++] = 0x4e;
@@ -527,17 +548,19 @@ static void EncodeTrackData(const uint8_t* pSrc, uint8_t* data, uint8_t* marker,
for (count = 0; count < 12; count++) data[ptr++] = 0x00;
// marker
marker[ptr / 2] = true; // Data marker; start CRC calculus
+ pCrcPtr = data + ptr; nCrcPtr = ptr;
data[ptr++] = 0xa1; data[ptr++] = 0xa1; data[ptr++] = 0xa1;
data[ptr++] = 0xfb;
// data
for (count = 0; count < 512; count++)
data[ptr++] = pSrc[(sect * 512) + count];
// crc
- //TODO: Calculate CRC
- data[ptr++] = 0x43; data[ptr++] = 0x21; // CRC stub
+ crc = getCrc(pCrcPtr, ptr - nCrcPtr);
+ data[ptr++] = (uint8_t)(crc & 0xff); data[ptr++] = (uint8_t)(crc >> 8);
gap = 36; // GAP3 length
}
+
// fill GAP4B to the end of the track
while (ptr < FLOPPY_RAWTRACKSIZE) data[ptr++] = 0x4e;
}
diff --git a/emulator/qmemoryview.cpp b/emulator/qmemoryview.cpp
index b788e77..5d5253e 100644
--- a/emulator/qmemoryview.cpp
+++ b/emulator/qmemoryview.cpp
@@ -93,10 +93,10 @@ void QMemoryView::focusOutEvent(QFocusEvent *)
void QMemoryView::contextMenuEvent(QContextMenuEvent *event)
{
QMenu menu(this);
- menu.addAction(tr("Go to Address..."), this, SLOT(gotoAddress()));
+ menu.addAction(QIcon(":/images/iconEditAddress.svg"), tr("Go to Address..."), this, SLOT(gotoAddress()));
menu.addSeparator();
- menu.addAction(tr("Words / Bytes"), this, SLOT(changeWordByteMode()));
- menu.addAction(tr("Octal / Hex"), this, SLOT(changeNumeralMode()));
+ menu.addAction(QIcon(":/images/iconWordByte.svg"), tr("Words / Bytes"), this, SLOT(changeWordByteMode()));
+ menu.addAction(QIcon(":/images/iconHex.svg"), tr("Octal / Hex"), this, SLOT(changeNumeralMode()));
menu.exec(event->globalPos());
}