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()); }