diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c785403 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +build/osx_clang64 diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..f2587ea --- /dev/null +++ b/.travis.yml @@ -0,0 +1,59 @@ +language: cpp +os: osx +install: +- + brew install qt5 + && chmod -R 755 /usr/local/opt/qt5/* + ; + +script: +- install_name_tool -id @rpath/QtWidgets.framework/Versions/5/QtWidgets /usr/local/opt/qt5/lib/QtWidgets.framework/Versions/5/QtWidgets +- install_name_tool -id @rpath/QtCore.framework/Versions/5/QtCore /usr/local/opt/qt5/lib/QtCore.framework/Versions/5/QtCore +- install_name_tool -id @rpath/QtGui.framework/Versions/5/QtGui /usr/local/opt/qt5/lib/QtGui.framework/Versions/5/QtGui + + + +- install_name_tool -change /usr/local/Cellar/qt5/5.3.2/lib/QtGui.framework/Versions/5/QtGui @rpath/QtGui.framework/Versions/5/QtGui /usr/local/opt/qt5/lib/QtWidgets.framework/Versions/Current/QtWidgets +- install_name_tool -change /usr/local/Cellar/qt5/5.3.2/lib/QtCore.framework/Versions/5/QtCore @rpath/QtCore.framework/Versions/5/QtCore /usr/local/opt/qt5/lib/QtWidgets.framework/Versions/Current/QtWidgets +- install_name_tool -change /usr/local/Cellar/qt5/5.3.2/lib/QtCore.framework/Versions/5/QtCore @rpath/QtCore.framework/Versions/5/QtCore /usr/local/opt/qt5/lib/QtGui.framework/Versions/Current/QtGui + +- install_name_tool -change /usr/local/Cellar/qt5/5.3.2/lib/QtGui.framework/Versions/5/QtGui @rpath/QtGui.framework/Versions/5/QtGui /usr/local/opt/qt5/lib/QtPrintSupport.framework/Versions/Current/QtPrintSupport +- install_name_tool -change /usr/local/Cellar/qt5/5.3.2/lib/QtWidgets.framework/Versions/5/QtWidgets @rpath/QtWidgets.framework/Versions/5/QtWidgets /usr/local/opt/qt5/lib/QtPrintSupport.framework/Versions/Current/QtPrintSupport +- install_name_tool -change /usr/local/Cellar/qt5/5.3.2/lib/QtCore.framework/Versions/5/QtCore @rpath/QtCore.framework/Versions/5/QtCore /usr/local/opt/qt5/lib/QtPrintSupport.framework/Versions/Current/QtPrintSupport + + +- install_name_tool -id @rpath/plugins/platforms/libqcocoa.dylib /usr/local/opt/qt5/plugins/platforms/libqcocoa.dylib + +- install_name_tool -change /usr/local/Cellar/qt5/5.3.2/lib/QtPrintSupport.framework/Versions/5/QtPrintSupport @rpath/QtPrintSupport.framework/Versions/5/QtPrintSupport /usr/local/opt/qt5/plugins/platforms/libqcocoa.dylib +- install_name_tool -change /usr/local/Cellar/qt5/5.3.2/lib/QtWidgets.framework/Versions/5/QtWidgets @rpath/QtWidgets.framework/Versions/5/QtWidgets /usr/local/opt/qt5/plugins/platforms/libqcocoa.dylib +- install_name_tool -change /usr/local/Cellar/qt5/5.3.2/lib/QtGui.framework/Versions/5/QtGui @rpath/QtGui.framework/Versions/5/QtGui /usr/local/opt/qt5/plugins/platforms/libqcocoa.dylib +- install_name_tool -change /usr/local/Cellar/qt5/5.3.2/lib/QtCore.framework/Versions/5/QtCore @rpath/QtCore.framework/Versions/5/QtCore /usr/local/opt/qt5/plugins/platforms/libqcocoa.dylib + + +- /bin/bash ./build_osx_clang_x64.sh + +- install_name_tool -add_rpath @loader_path/ build/osx_clang64/Release/cascade +- install_name_tool -add_rpath @executable_path/ build/osx_clang64/Release/cascade +- install_name_tool -add_rpath . build/osx_clang64/Release/cascade + +- zip -yrXj $TRAVIS_BUILD_DIR/cascade.zip build/osx_clang64/Release/cascade +- cd /usr/local/opt/qt5/lib/ +- zip -qyrX $TRAVIS_BUILD_DIR/cascade.zip QtGui.framework +- zip -qyrX $TRAVIS_BUILD_DIR/cascade.zip QtWidgets.framework +- zip -qyrX $TRAVIS_BUILD_DIR/cascade.zip QtCore.framework +- zip -qyrX $TRAVIS_BUILD_DIR/cascade.zip QtPrintSupport.framework + +- cd .. +- zip -qyrX $TRAVIS_BUILD_DIR/cascade.zip plugins +- cd $TRAVIS_BUILD_DIR +deploy: + provider: releases + api_key: + secure: Y8BQ86C8S6ZQeQ81Gs9hPJGmJEhoIJsC3GWEnOmgHVutY3psmIcOCOznCdViG4NAMX/DukYL3RFP9C3oOrIXUkwD8r/L9SlGVbuwxmxW3IuQsyGy+qHnvwYJHcJsIHM7XWxsYPz2Qe4+rqTN2fxJM/PD8edddVHt5gjI9nMrW2V1ptx+7RfG34/XtaP4EcBCAyNyhTOlNuuh8rimVHxhhM35tHVyO5ct6//TZJp4c93CBZAH/bkxnwys9LRa+Xfdl+sWdFjuKDL2q8McNRSv9vkKaxzjI4b10mKspwk8v2WVg21jeSAv720aJCdumhGxX4Ts2aExlUOkL0MbCMLGL7F+OggNGziFTyKiZGXkGotkbcqSN6+J7Ht16AO7K9ehB9JG3SOdyMn0DOCB92OF7C24T4Knj7ZQnkuz3KTow07pKl3lsbKlywdOINLmYw236n1W5TQmpBufZVUOZZ9LJ12g7zBnmLtfslauUENI8Om4Nubu6dDKteUm4xxd9JG7m35bX5jb5h2cZrVL5yyvTl+NPLCtFCKl9ojE4bjojxpXMSZmDzb4/ji3WMFXkfqUEMpCgogsZ3E3VhwzCWHL4+Tf8s8fWY7vw1dlyRyMNBcUA6gKAb5NIjHKkBhwJACGwtRmYv8jAN8siAxJEDisyzQ5xyDgwOWGmfNbeKNgjLs= + file: + - build/osx_clang64/Release/cascade + - cascade.zip + skip_cleanup: true + on: + repo: shadowsgit/cascade + branch: open_public diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..f7e7a0a --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,75 @@ +cmake_minimum_required(VERSION 2.8) +set (projectName cascade) + +if(DIST_WIN32VS05) +set(QT_QMAKE_EXECUTABLE "c:/Qt/4.8.1-win32vs05/bin/qmake.exe") + +find_package(Qt4 REQUIRED) +include(${QT_USE_FILE}) +endif() + +if(DIST_WIN32VS13) +set(CMAKE_PREFIX_PATH "c:/Qt/5.5/msvc2013") + +find_package (Qt5Widgets REQUIRED) +endif() + +if(DIST_MACOSX) +#set(CMAKE_PREFIX_PATH "/Volumes/developer/Qt/5.5/clang_64/") +set(CMAKE_PREFIX_PATH "/usr/local/opt/qt5/") + +find_package (Qt5Widgets REQUIRED) +endif() + + +if(DIST_WINDOWS) +add_definitions(-DDIST_WINDOWS) +endif() + +include_directories(${CMAKE_CURRENT_SOURCE_DIR} ) +if(DIST_WIN32VS05) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/vs2005) +endif() + +file(GLOB ${projectName}_SRC + "*.h" + "*.h" + "*.cpp" +) + +set(CMAKE_AUTOMOC TRUE) + +if(DIST_WINDOWS) +list(REMOVE_ITEM ${projectName}_SRC ${CMAKE_CURRENT_SOURCE_DIR}/os_sdl.cpp) +list(REMOVE_ITEM ${projectName}_SRC ${CMAKE_CURRENT_SOURCE_DIR}/os_linux.cpp) +list(REMOVE_ITEM ${projectName}_SRC ${CMAKE_CURRENT_SOURCE_DIR}/os_serial_linux.cpp) +list(REMOVE_ITEM ${projectName}_SRC ${CMAKE_CURRENT_SOURCE_DIR}/os_serial_macosx.cpp) +list(REMOVE_ITEM ${projectName}_SRC ${CMAKE_CURRENT_SOURCE_DIR}/iface_kl_ftdi.cpp) +endif() + +if(DIST_MACOSX) +list(REMOVE_ITEM ${projectName}_SRC ${CMAKE_CURRENT_SOURCE_DIR}/os_sdl.cpp) +list(REMOVE_ITEM ${projectName}_SRC ${CMAKE_CURRENT_SOURCE_DIR}/os_serial_win32.cpp) +list(REMOVE_ITEM ${projectName}_SRC ${CMAKE_CURRENT_SOURCE_DIR}/os_win32.cpp) + +#list(REMOVE_ITEM ${projectName}_SRC ${CMAKE_CURRENT_SOURCE_DIR}/os_linux.cpp) +list(REMOVE_ITEM ${projectName}_SRC ${CMAKE_CURRENT_SOURCE_DIR}/os_serial_linux.cpp) +list(REMOVE_ITEM ${projectName}_SRC ${CMAKE_CURRENT_SOURCE_DIR}/iface_kl_ftdi.cpp) +endif() + + +message(${${projectName}_SRC}) +add_executable(${projectName} ${${projectName}_SRC}) + +if(DIST_WINDOWS) + target_link_libraries(${projectName} ${CMAKE_CURRENT_SOURCE_DIR}/ftd2xx_win32/ftd2xx.lib ) + if(DIST_WIN32VS05) + target_link_libraries(${projectName} Qt4::QtGui ) + else() + qt5_use_modules(${projectName} Widgets) + endif() +elseif(DIST_MACOSX) + qt5_use_modules(${projectName} Widgets) +endif() + + diff --git a/autotty.cpp b/autotty.cpp index a6bf698..117aeb2 100644 --- a/autotty.cpp +++ b/autotty.cpp @@ -16,7 +16,7 @@ AutoTTY::AutoTTY(UI *ui, const char *driver) { this->ui = ui; - this->driver = strdup(driver); + this->driver = driver?strdup(driver):NULL; sh = -1; plugged_in = false; ui->setLED(LED_IFACE, false); diff --git a/build_osx_clang_x64.sh b/build_osx_clang_x64.sh new file mode 100755 index 0000000..00148b6 --- /dev/null +++ b/build_osx_clang_x64.sh @@ -0,0 +1,7 @@ +mkdir build +mkdir "build/osx_clang64" +pushd "build/osx_clang64" +cmake -G"Xcode" ../../ -DDIST_MACOSX=1 + +xcodebuild -project Project.xcodeproj -configuration Release +popd \ No newline at end of file diff --git a/build_vs2005.bat b/build_vs2005.bat new file mode 100644 index 0000000..a6c87a9 --- /dev/null +++ b/build_vs2005.bat @@ -0,0 +1,7 @@ +mkdir build +mkdir "build/vs2005" +pushd "build/vs2005" +cmake -G"Visual Studio 8 2005" ../../ -DDIST_WIN32VS05=1 -DDIST_WINDOWS=1 + +"%VS80COMNTOOLS%\..\IDE\devenv.com" Project.sln /build Release +popd \ No newline at end of file diff --git a/build_vs2013.bat b/build_vs2013.bat new file mode 100644 index 0000000..9b98512 --- /dev/null +++ b/build_vs2013.bat @@ -0,0 +1,7 @@ +mkdir build +mkdir "build/vs2013" +pushd "build/vs2013" +cmake -G"Visual Studio 12" ../../ -DDIST_WIN32VS13=1 -DDIST_WINDOWS=1 + +"%VS120COMNTOOLS%\..\IDE\devenv.com" Project.sln /build Release +popd \ No newline at end of file diff --git a/cpu.cpp b/cpu.cpp index 3fa5ca7..ddd167f 100644 --- a/cpu.cpp +++ b/cpu.cpp @@ -19,6 +19,10 @@ #include "hints.h" #include +#ifndef DIST_WINDOWS +#include +#endif //DIST_WINDOWS + Cpu::Cpu(UI *ui) { end_cycles = (uint64_t)-1LL; @@ -286,7 +290,7 @@ uint32_t Cpu::virtToPhysSlow(uint16_t addr, int fetch) else if (map_hi == 8 && map_lo <= 0x1f) { // (map_lo == 0x1e || map_lo == 0x1f || map_lo == 3 || map_lo == 5 || map_lo == 4)) { return 0xcaf00000UL + map_lo * 0x4000 + (addr - 0xc000); } - else if (map_hi == 0x10) { + else if (map_hi == 0x10 ) { if (exrom) return 0xbab00000UL + map_lo * 0x4000 + (addr - 0xc000); else @@ -524,7 +528,7 @@ const char *Cpu::disassemble() case 0x19: OP2SH("SHLB"); break; case 0x1a: OP2SH("SHRAB"); break; case 0x1b: OP2IX("XCHB"); break; - case 0x1c ... 0x1f: OP0("RESERVED"); break; + /* case 0x1c ... 0x1f: OP0("RESERVED"); break; case 0x20 ... 0x27: OPJ11("SJMP"); break; case 0x28 ... 0x2f: OPJ11("SCALL"); break; case 0x30 ... 0x37: OPJBIT("JBC"); break; @@ -560,7 +564,7 @@ const char *Cpu::disassemble() case 0xb0 ... 0xb3: OP2("LDB"); break; case 0xb4 ... 0xb7: OP2("ADDCB"); break; case 0xb8 ... 0xbb: OP2("SUBCB"); break; - case 0xbc ... 0xbf: OP2("LDBSE"); break; + case 0xbc ... 0xbf: OP2("LDBSE"); break;*/ case 0xc0: OP2("ST"); break; case 0xc1: OP2D("BMOV"); break; case 0xc2: OP2("ST"); break; @@ -597,9 +601,9 @@ const char *Cpu::disassemble() case 0xe1: OPDJ8("DJNZW"); break; case 0xe2: OPUNIMP("TIJMP"); break; case 0xe3: sprintf(buf, "BR [%02X]", peek(1)); break; - case 0xe4 ... 0xe6: OP0("RESERVED"); break; + // case 0xe4 ... 0xe6: OP0("RESERVED"); break; case 0xe7: OPJ16("LJMP"); break; - case 0xe8 ... 0xeb: OP0("RESERVED"); break; + // case 0xe8 ... 0xeb: OP0("RESERVED"); break; case 0xec: OPUNIMP("DPTS"); break; case 0xed: OPUNIMP("EPTS"); break; case 0xee: OP0("RESERVED NOP"); break; @@ -739,7 +743,7 @@ bool Cpu::loadRom(const char *name) DEBUG(OS, "extracting RAR file %s\n", rom_name); fclose(fp); sprintf(new_name, "%s.lha", rom_name); - char cmd[strlen(rom_name) + strlen(new_name) + 50]; + char *cmd = (char *)alloca(strlen(rom_name) + strlen(new_name) + 50); sprintf(cmd, "unrar p -inul \"%s\" >\"%s\"", rom_name, new_name); if (system(cmd)) { ERROR("failed to unpack %s to %s\n", rom_name, new_name); @@ -771,7 +775,7 @@ bool Cpu::loadRom(const char *name) *r = 0; sprintf(new_name, "%s.bin", stripname); free(stripname); - char cmd[strlen(rom_name) + strlen(new_name) + 50]; + char *cmd=(char *)alloca(strlen(rom_name) + strlen(new_name) + 50); sprintf(cmd, "lha p -q \"%s\" >\"%s\"", rom_name, new_name); if (system(cmd)) { ERROR("failed to unpack %s to %s\n", rom_name, new_name); @@ -821,7 +825,7 @@ bool Cpu::loadRom(const char *name) memcpy(ram, rom, 0xc000); - char eename[strlen(rom_name) + 4 + 1]; + char *eename=(char *)alloca(strlen(rom_name) + 4 + 1); sprintf(eename, "%s.eep", rom_name); eeprom->setFilename(eename); diff --git a/cpu.h b/cpu.h index c47ec60..1a15fee 100644 --- a/cpu.h +++ b/cpu.h @@ -151,17 +151,15 @@ friend class Keypad; uint8_t memRead8Bus(uint16_t addr, int fetch); typedef uint8_t (Cpu::*memReader)(uint16_t addr); - inline uint8_t memRead8(uint16_t addr) { - switch (addr) { - case 0 ... 1: return 0; - case 0x18 ... 0xff: - case 0x2000 ... 0xbfff: - return memRead8Ram(addr); - case 0xc000 ... 0xffff: - return memRead8Mapped(addr); - default: - return memRead8Slow(addr); - } + inline uint8_t memRead8(uint16_t addr) + { + if (addr == 1 || addr==0) return 0; + if (addr>=0x18 && addr <=0xFF) return memRead8Ram(addr); + if (addr>=0x2000 && addr <=0xbfff) return memRead8Ram(addr); + if (addr>=0xc000 && addr <=0xFFFF) return memRead8Mapped(addr); +//default + return memRead8Slow(addr); + } uint8_t memRead8Ram(uint16_t addr) { @@ -206,24 +204,18 @@ friend class Keypad; } typedef void (Cpu::*memWriter)(uint16_t addr, uint8_t value); - inline void memWrite8(uint16_t addr, uint8_t value) { - switch (addr) { - case 0 ... 0x17: - case 0x200 ... 0x2ff: - ioWrite8(addr, value); - break; - case 0x18 ... 0xff: - case 0x2000 ... 0xbfff: - memWrite8Ram(addr, value); - break; - case 0xc000 ... 0xffff: - memWrite8Mapped(addr, value); - break; - default: - memWrite8Slow(addr, value); - break; - } - } + inline void memWrite8(uint16_t addr, uint8_t value) + { + if (addr >=0x0 && addr <= 0x17) return ioWrite8(addr,value); + if (addr >=0x200 && addr <= 0x2ff) return ioWrite8(addr,value); + if (addr >=0x18 && addr <= 0xff) return memWrite8Ram(addr,value); + if (addr >=0x2000 && addr <= 0xbfff) return memWrite8Ram(addr,value); + + if (addr >=0xc000 && addr <= 0xffff) return memWrite8Mapped(addr,value); +//default + return memWrite8Slow(addr, value);; + } + void memWrite8Slow(uint16_t addr, uint8_t value); void memWrite8Mapped(uint16_t addr, uint8_t value) { DEBUG(MEM, "WRITE %02X -> %04X\n", value, addr); diff --git a/cpu_emu.cpp b/cpu_emu.cpp index 353733e..1f2dcad 100644 --- a/cpu_emu.cpp +++ b/cpu_emu.cpp @@ -573,7 +573,15 @@ int Cpu::emulate(void) psw |= PSW_VT; } break; - case 0x20 ... 0x27: /* sjmp rel11 */ + case 0x20: + case 0x21: + case 0x22: + case 0x23: + case 0x24: + case 0x25: + case 0x26: + case 0x27: + // case 0x20 ... 0x27: /* sjmp rel11 */ rel16 = ((int16_t)((fetch() | ((opcode & 0x7) << 8)) << 5)) >> 5; target = pc + rel16; if (target == pc - 2) { @@ -586,7 +594,15 @@ int Cpu::emulate(void) pc = target; cycle(7); break; - case 0x28 ... 0x2f: /* scall rel11 */ + case 0x28: + case 0x29: + case 0x2A: + case 0x2B: + case 0x2C: + case 0x2D: + case 0x2E: + case 0x2F: + // case 0x28 ... 0x2f: /* scall rel11 */ val8 = fetch(); rel16 = ((int16_t)((val8 | ((opcode & 0x7) << 8)) << 5)) >> 5; target = pc + rel16; @@ -594,7 +610,15 @@ int Cpu::emulate(void) pc = target; cycle(11); break; - case 0x30 ... 0x37: /* jbc rel8 */ + case 0x30: + case 0x31: + case 0x32: + case 0x33: + case 0x34: + case 0x35: + case 0x36: + case 0x37: +// case 0x30 ... 0x37: /* jbc rel8 */ imm8 = 1 << (opcode & 0x7); addr8 = fetch(); sval8 = (int8_t)fetch(); @@ -606,7 +630,15 @@ int Cpu::emulate(void) } cycle(5); break; - case 0x38 ... 0x3f: /* jbs rel8 */ + case 0x38: + case 0x39: + case 0x3A: + case 0x3B: + case 0x3C: + case 0x3D: + case 0x3E: + case 0x3F: + // case 0x38 ... 0x3f: /* jbs rel8 */ imm8 = 1 << (opcode & 0x7); addr8 = fetch(); sval8 = (int8_t)fetch(); diff --git a/cpu_io.cpp b/cpu_io.cpp index e08c69f..2d6994f 100644 --- a/cpu_io.cpp +++ b/cpu_io.cpp @@ -315,25 +315,33 @@ uint8_t Cpu::ioRead8(uint16_t addr) REG("DATAMAP_HI"); ret = data_hi; break; - case 0x203 ... 0x20f: - case 0x211: - case 0x213 ... 0x235: - case 0x237 ... 0x23f: - case 0x241 ... 0x26f: - case 0x274 ... 0x2ff: - REG("IO2XX"); - DEBUG(IO, "%04X: IO2XX from %04X (%02X, '%c')\n", opc, addr, ram[addr], printable_char(ram[addr])); - if (addr == 0x274) - ret = 0x00; - else - ret = ram[addr]; - break; + default: + if ((addr>= 0x203 && addr <= 0x20f) || + (addr>= 0x211 && addr <= 0x211) || + (addr>= 0x213 && addr <= 0x235) || + (addr>= 0x237 && addr <= 0x23f) || + (addr>= 0x241 && addr <= 0x26f) || + (addr>= 0x274 && addr <= 0x2ff) + ) + { + + REG("IO2XX"); + DEBUG(IO, "%04X: IO2XX from %04X (%02X, '%c')\n", opc, addr, ram[addr], printable_char(ram[addr])); + if (addr == 0x274) + ret = 0x00; + else + ret = ram[addr]; + + + goto jump_good; + } fail: ERROR("I/O byte read from 0x%x unimplemented at %04X\n", addr, opc); dumpMem(); exit(1); }; +jump_good: DEBUG(IO, "%04X (%08X/%8lld): IOR %s (%02X): %02X ('%c')\n", opc, virtToPhys(opc, 1), (long long)getCycles(), reg, addr, ret, printable_char(ret)); return ret; } @@ -716,7 +724,7 @@ void Cpu::ioWrite8(uint16_t addr, uint8_t value) break; default: ERROR("unhandled port 254h value\n"); - exit(1); + // exit(1); break; } } @@ -776,25 +784,31 @@ void Cpu::ioWrite8(uint16_t addr, uint8_t value) data_ptr = (uint8_t *)&rom[phys]; } break; - case 0x200: - case 0x201: - case 0x203 ... 0x20f: - case 0x211: - case 0x213 ... 0x24f: - case 0x251 ... 0x253: - case 0x255 ... 0x25d: - case 0x25f ... 0x26f: - case 0x274 ... 0x2ff: - REG("IO2XX"); - DEBUG(IO, "%04X: IO2XX %02X ('%c') to %04X\n", opc, value, printable_char(value), addr); - ram[addr] = value; - break; + default: + if ((addr>= 0x200 && addr <= 0x201) || + (addr>= 0x203 && addr <= 0x20f) || + (addr>= 0x211 && addr <= 0x211) || + (addr>= 0x213 && addr <= 0x24f) || + (addr>= 0x251 && addr <= 0x253) || + (addr>= 0x255 && addr <= 0x25d) || + (addr>= 0x25f && addr <= 0x26f) || + (addr>= 0x274 && addr <= 0x2ff) + ) + { + REG("IO2XX"); + DEBUG(IO, "%04X: IO2XX %02X ('%c') to %04X\n", opc, value, printable_char(value), addr); + ram[addr] = value; + + goto jump_good; + } + fail: ERROR("%04X/%08X: I/O byte write of 0x%x ('%c') to 0x%x (WSR %02X) unimplemented\n", opc, virtToPhys(opc, 1), value, printable_char(value), addr, wsr); dumpMem(); exit(1); }; +jump_good: DEBUG(IO, "%04X (%08X/%8lld): IOW %s (%02X/'%c') -> %02X\n", opc, virtToPhys(opc, 1), (long long)getCycles(), reg, value, printable_char(value), addr); } diff --git a/debug.h b/debug.h index 7894219..0a2bfdb 100644 --- a/debug.h +++ b/debug.h @@ -10,6 +10,13 @@ #include #include +#ifdef DIST_WINDOWS + +#ifdef ERROR +#undef ERROR +#endif // ERROR +#endif //DIST_WINDOW + #define DEBUG_WARN 0x00000010UL #define DEBUG_IO 0x00000100UL @@ -29,30 +36,33 @@ #define DEBUG_UI 0x00000200UL #define DEBUG_DEFAULT (DEBUG_WARN | DEBUG_SERIAL | DEBUG_ABRIDGED | DEBUG_IFACE | DEBUG_OS | DEBUG_KEY | DEBUG_HSIO | DEBUG_HINTS | DEBUG_UI) - +#ifdef _MSC_VER +#define unlikely(x) (x) +#else #define likely(x) __builtin_expect(!!(x), 1) #define unlikely(x) __builtin_expect(!!(x), 0) +#endif // MSVC_VER #ifdef __MINGW32__ extern FILE *win_stderr; #endif #ifdef NDEBUG -#define DEBUG(level, bla...) do {} while(0) +#define DEBUG(level, ...) do {} while(0) #else #ifdef __MINGW32__ -#define DEBUG(level, bla...) \ - do { if (unlikely(debug_level & DEBUG_ ##level)) __mingw_fprintf(win_stderr, bla); /* fflush(win_stderr); */ } while(0) +#define DEBUG(level, ...) \ + do { if (unlikely(debug_level & DEBUG_ ##level)) __mingw_fprintf(win_stderr, __VA_ARGS__); /* fflush(win_stderr); */ } while(0) #else -#define DEBUG(level, bla...) \ - do { if (unlikely(debug_level & DEBUG_ ##level)) fprintf(stderr, bla); } while(0) +#define DEBUG(level, ...) \ + do { if (unlikely(debug_level & DEBUG_ ##level)) fprintf(stderr, __VA_ARGS__); } while(0) #endif #endif #ifdef __MINGW32__ #undef ERROR -#define ERROR(bla...) do { __mingw_fprintf(win_stderr, bla); fflush(win_stderr); } while(0) +#define ERROR(...) do { __mingw_fprintf(win_stderr, __VA_ARGS__); fflush(win_stderr); } while(0) #else -#define ERROR(bla...) fprintf(stderr, bla) +#define ERROR(...) fprintf(stderr, __VA_ARGS__) #endif extern uint32_t debug_level; diff --git a/iface_can.cpp b/iface_can.cpp index d48c024..4963c89 100644 --- a/iface_can.cpp +++ b/iface_can.cpp @@ -175,7 +175,7 @@ void IfaceCAN::msgOut() /* 34 is the length of the longest fixed-size command (set filter), and the rest depends on tx_len, so this ought to be enough. */ - uint8_t out[34 + tx_len]; + uint8_t *out = (uint8_t *)alloca(34 + tx_len); int outp = 0; switch (tx_cmd) { diff --git a/main.cpp b/main.cpp index 6b5e032..5bcdf6c 100644 --- a/main.cpp +++ b/main.cpp @@ -12,7 +12,11 @@ #include #include #include +#ifndef DIST_WINDOWS + #include +#endif //DIST_WINDOWS + #include #include #include @@ -49,13 +53,13 @@ int main(int argc, char **argv) win_stderr = fopen("stderr.out", "w"); #endif - UI::initToolkit(); + UI::initToolkit(argv[0]); UI ui; Cpu cpu(&ui); ui.setCpu(&cpu); - signed char c; + const char *tty = NULL; #define IFACE_ELM 0 @@ -63,7 +67,7 @@ int main(int argc, char **argv) #define IFACE_FTDI 2 #define IFACE_FAKE 3 #define IFACE_KCAN 4 -#if defined(NDEBUG) && defined(__MINGW32__) +#if defined(NDEBUG) && (defined(__MINGW32__)|| defined (DIST_WINDOWS)) int iface_type = IFACE_KCAN; #else int iface_type = IFACE_FAKE; @@ -75,6 +79,8 @@ int main(int argc, char **argv) #ifndef NDEBUG uint32_t trigger = 0; #endif +#if !defined(DIST_WINDOWS) + signed char c; while ((c = getopt (argc, argv, "d:t:w:s:m:r:p:i:ex:v:S")) != -1) { switch (c) { case 'd': @@ -184,7 +190,8 @@ int main(int argc, char **argv) } argc -= optind; argv += optind; - +#endif //DIST_WINDOWS + #ifndef NDEBUG if (trigger) { cpu.setDebugTrigger(trigger, debug_level); @@ -192,13 +199,22 @@ int main(int argc, char **argv) } #endif +#if !defined(DIST_WINDOWS) if (argc >= 1) { if (!cpu.loadRom(argv[0])) { ERROR("failed to load ROM image\n"); exit(1); } } - +#else + if (argc > 1) { + if (!cpu.loadRom(argv[1])) { + ERROR("failed to load ROM image\n"); + exit(1); + } + } +#endif + Interface *iface; switch (iface_type) { case IFACE_KL: diff --git a/os_qt.cpp b/os_qt.cpp index dac20b5..260be7c 100644 --- a/os_qt.cpp +++ b/os_qt.cpp @@ -9,7 +9,7 @@ */ #include "os.h" -#include +#include class OsThread : public QThread { diff --git a/os_serial_macosx.cpp b/os_serial_macosx.cpp new file mode 100755 index 0000000..1816667 --- /dev/null +++ b/os_serial_macosx.cpp @@ -0,0 +1,281 @@ +/* + * os_serial_linux.cpp + * + * (C) Copyright 2014 Ulrich Hecht + * + * This file is part of CASCADE. CASCADE is almost free software; you can + * redistribute it and/or modify it under the terms of the Cascade Public + * License 1.0. Read the file "LICENSE" for details. + */ + +#include "os.h" +#include "debug.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//#define DRYDOCK + +int os_serial_open(const char *tty, bool nonblock) +{ +#ifdef DRYDOCK + return 2; /* stderr */ +#else + int fd; + + if (nonblock) + fd = open(tty, O_RDWR|O_NOCTTY|O_NDELAY); + else + { + fd = open(tty, O_RDWR|O_NOCTTY| O_NDELAY); + + + if (fd < 0) { + ERROR("OS failed to open serial device %s: %s\n", tty, strerror(errno)); + return -1; + } + + } + if (ioctl(fd, TIOCEXCL) == -1) { + close(fd); + return -1; + } + + + if (!nonblock) + { + if (fcntl(fd, F_SETFL, 0) == -1) { + close(fd); + return -1; + } + + } + + /* put TTY in raw mode */ + struct termios tio; + tcgetattr(fd, &tio); + cfmakeraw(&tio); + // CCTS_OFLOW + tio.c_cc[VMIN] =0; + tio.c_cc[VTIME] =1; + tcsetattr(fd, TCSANOW, &tio); + DEBUG(OS, "OS serial flush after open\n"); + tcflush(fd, TCIOFLUSH); /* flush stale serial buffers */ + + return fd; +#endif +} + +int os_serial_close(int handle) +{ + return close(handle); +} + +int os_serial_send(int handle, const char *msg) +{ + DEBUG(OS, "OS serial send %s\n", msg); + return write(handle, msg, strlen(msg)); +} + +int os_serial_send_buf(int handle, const unsigned char *buf, int len) +{ + DEBUG(OS, "OS serial send buffer, length %d\n", len); + return write(handle, buf, len); +} + +int os_serial_send_byte(int handle, char byte) +{ + int m =sizeof(byte); + DEBUG(OS, "OS serial send byte %02X\n", byte); + return write(handle, &byte, 1); +} + +int os_serial_bytes_received(int fd) +{ + int bytes = 0; + ioctl(fd, FIONREAD, &bytes); + return bytes; +} + +int os_serial_read_to_buffer(int fd, void *buf, int count) +{ + return read(fd, buf, count); +} + +int os_serial_flush(int fd) +{ + DEBUG(OS, "OS serial flush\n"); + return tcflush(fd, TCIOFLUSH); +} + + + + + +int os_serial_set_baudrate(int fd, int baudrate) +{ + struct termios tios; + if (tcgetattr(fd, &tios) < 0) { + ERROR("tcgetattr failed\n"); + return -1; + } + + // The IOSSIOSPEED ioctl can be used to set arbitrary baud rates + // other than those specified by POSIX. The driver for the underlying serial hardware + // ultimately determines which baud rates can be used. This ioctl sets both the input + // and output speed. + + speed_t speed = baudrate; // Set 14400 baud + if (ioctl(fd, IOSSIOSPEED, &speed) == -1) { + + ERROR("IOSSIOSPEED failed\n"); + return -1; + + } + + // cfsetispeed + + /* + struct serial_struct ser; + if (ioctl(fd, TIOCGSERIAL, &ser)) { + ERROR("TIOCGSERIAL failed\n"); + return -1; + } + + ser.custom_divisor = ser.baud_base / baudrate; + ser.flags &= ~ASYNC_SPD_MASK; + ser.flags |= ASYNC_SPD_CUST | ASYNC_LOW_LATENCY; + + tios.c_cflag &= ~CBAUD; + tios.c_cflag |= B38400; + + if (ioctl(fd, TIOCSSERIAL, &ser)) { + ERROR("TIOCSSERIAL failed\n"); + return -1; + } + if (ioctl(fd, TIOCGSERIAL, &ser)) { + ERROR("TIOCGSERIAL failed\n"); + return -1; + } + if (ser.custom_divisor != ser.baud_base / baudrate) { + ERROR("failed to set baudrate divisor, is %d, should be %d\n", ser.custom_divisor, ser.baud_base / baudrate); + } + if (tcsetattr(fd, TCSANOW, &tios) < 0) { + ERROR("tcsetattr failed\n"); + return -1; + }*/ + return 0; +} + +int os_serial_clear_break(int fd) +{ + if (ioctl(fd, TIOCCBRK) < 0) { + ERROR("TIOCCBRK failed\n"); + return -1; + } + return 0; +} + +int os_serial_set_break(int fd) +{ + if (ioctl(fd, TIOCSBRK) < 0) { + ERROR("TIOCSBRK failed\n"); + return -1; + } + return 0; +} + +int os_serial_set_rts(int fd) +{ + int flags; + if (ioctl(fd, TIOCMGET, &flags)) { + ERROR("CMBIC: %s\n", strerror(errno)); + return -1; + } + flags |= TIOCM_RTS; + return ioctl(fd, TIOCMSET, &flags); +} + +int os_serial_clear_rts(int fd) +{ + int flags; + if (ioctl(fd, TIOCMGET, &flags)) { + ERROR("CMBIC: %s\n", strerror(errno)); + return -1; + } + flags &= ~TIOCM_RTS; + return ioctl(fd, TIOCMSET, &flags); +} + +int os_serial_set_dtr(int fd) +{ + int flags; + if (ioctl(fd, TIOCMGET, &flags)) { + ERROR("CMBIC: %s\n", strerror(errno)); + return -1; + } + flags |= TIOCM_DTR; + return ioctl(fd, TIOCMSET, &flags); +} + +int os_serial_clear_dtr(int fd) +{ + int flags; + if (ioctl(fd, TIOCMGET, &flags)) { + ERROR("CMBIC: %s\n", strerror(errno)); + return -1; + } + flags &= ~TIOCM_DTR; + return ioctl(fd, TIOCMSET, &flags); +} + +const char *os_serial_get_error(void) +{ + return strerror(errno); +} + +#define SYS_DRIVER_PATH "/sys/bus/usb-serial/drivers/" + +int os_serial_find_port(const char *driver, char **tty_found) +{ + int sh; + char *sysfs_dir = "/dev/";//new char[sizeof(SYS_DRIVER_PATH) + strlen(driver)]; +// sprintf(sysfs_dir, SYS_DRIVER_PATH "%s", driver); + DEBUG(IFACE, "checking %s for tty\n", sysfs_dir); + + for (;;) { + DIR *dir = opendir(sysfs_dir); + if (!dir) { + os_msleep(300); + continue; + } + + struct dirent *ent; + while ((ent = readdir(dir))) { + //if (!strncmp("tty.usbserial", ent->d_name, strlen("tty.usbserial"))) { + if (!strncmp("cu.usbserial", ent->d_name, strlen("cu.usbserial"))) { + char *tty = new char[sizeof("/dev/") + strlen(ent->d_name)]; + sprintf(tty, "/dev/%s", ent->d_name); + DEBUG(IFACE, "trying to open %s\n", tty); + sh = os_serial_open(tty, false); + if (sh >= 0 && tty_found) + *tty_found = strdup(tty); + delete tty; + if (sh >= 0) { + closedir(dir); + //delete sysfs_dir; + return sh; + } + } + } + closedir(dir); + os_msleep(300); + } +} diff --git a/os_serial_win32.cpp b/os_serial_win32.cpp index aabdc4f..80a2463 100644 --- a/os_serial_win32.cpp +++ b/os_serial_win32.cpp @@ -18,15 +18,21 @@ #include #include #include + +#ifndef DIST_WINDOWS + #include #include +#endif //DIST_WINDOW + + //#define DRYDOCK -#define CHECK(fun, args...) { \ +#define CHECK(fun, ...) { \ FT_STATUS ret; \ /* DEBUG(OS, "doing " #fun " now\n"); */ \ - if ((ret = fun(args)) != FT_OK) { \ + if ((ret = fun(__VA_ARGS__)) != FT_OK) { \ DEBUG(OS, #fun " failed: %ld\n", ret); \ return -1; \ } \ diff --git a/serial.cpp b/serial.cpp index 39517b5..450bf3e 100644 --- a/serial.cpp +++ b/serial.cpp @@ -434,7 +434,16 @@ int Serial::getRxState(void) case 0: /* start bit */ serial_bitbang_last_bit_sent = 0; break; - case 1 ... 8: /* data bits */ +// case 1 ... 8: /* data bits */ + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + /* data bits */ byte = snoopByte(); serial_bitbang_last_bit_sent = (byte >> (serial_bitbang_bit_pos - 1)) & 1; DEBUG(SERIAL, "issuing bit %d of %02X at %llu\n", diff --git a/state.h b/state.h index be33c62..ccbc3a5 100644 --- a/state.h +++ b/state.h @@ -35,7 +35,7 @@ typedef FILE* statefile_t; #define state_tell ftell #define state_seek fseek #define state_eof feof -#define state_close gzclose +#define state_close fclose #define STATE_RW(x) write ? fwrite(&x, sizeof(x), 1, fp) : fread(&x, sizeof(x), 1, fp) #define STATE_RWBUF(x, n) write ? fwrite(x, n, 1, fp) : fread(x, n, 1, fp) #endif diff --git a/ui.cpp b/ui.cpp index 3d0a685..d0b1d70 100755 --- a/ui.cpp +++ b/ui.cpp @@ -8,17 +8,23 @@ * License 1.0. Read the file "LICENSE" for details. */ -#include "ui.h" -#include "lcd.h" -#include "serial.h" + #include #ifdef Q_WS_QWS #include #endif #include +#include +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) +# include +#else +# include +#endif #include "version.h" - +#include "ui.h" +#include "lcd.h" +#include "serial.h" class KeypadButton : public QPushButton { public: KeypadButton(UI *ui, QString text, UIKey key) : QPushButton(text, ui) { @@ -32,7 +38,12 @@ class KeypadButton : public QPushButton { }; /* Don't forget to update enum in ui.h! */ +#ifdef _MSC_VER +static const char *led_names[] = { +#else static const char *led_names[] __attribute__((used)) = { +#endif // _MCVC_VER + "serial", "data rx", "data tx", @@ -652,8 +663,22 @@ void UI::keypadUpSlot() key_up[b->key] = true; } -void UI::initToolkit() +void UI::initToolkit(char *appPath) { + + QDir dir(appPath); // e.g. appdir/Contents/MacOS/appname + + + dir.cdUp(); + if(!dir.cd("plugins")) + { + dir.cdUp(); + dir.cd("plugins"); + }; // e.g. appdir/Contents/PlugIns + //std::string dirr = dir.dirName().toStdString(); + ERROR("\n\n path %s path\n", dir.absolutePath().toStdString().c_str()); + QCoreApplication::setLibraryPaths(QStringList(dir.absolutePath())); + int qt_argc = 2; static char *qt_argv[] = {(char *)"emu", (char *)"-qws"}; new QApplication(qt_argc, qt_argv); @@ -752,9 +777,27 @@ void UI::keyEvent(QKeyEvent *event, bool *key_event) key_event[UIKEY_y] = true; break; case Qt::Key_N: key_event[UIKEY_n] = true; break; - case Qt::Key_0 ... Qt::Key_9: + case Qt::Key_0: + case Qt::Key_1: + case Qt::Key_2: + case Qt::Key_3: + case Qt::Key_4: + case Qt::Key_5: + case Qt::Key_6: + case Qt::Key_7: + case Qt::Key_8: + case Qt::Key_9: key_event[event->key() - Qt::Key_0 + UIKEY_0] = true; break; - case Qt::Key_F1 ... Qt::Key_F9: + case Qt::Key_F1: + case Qt::Key_F2: + case Qt::Key_F3: + case Qt::Key_F4: + case Qt::Key_F5: + case Qt::Key_F6: + case Qt::Key_F7: + case Qt::Key_F8: + case Qt::Key_F9: + key_event[event->key() - Qt::Key_F1 + UIKEY_F1] = true; break; case Qt::Key_F12: key_event[UIKEY_F12] = true; break; diff --git a/ui.h b/ui.h index d92c280..97f242c 100755 --- a/ui.h +++ b/ui.h @@ -21,7 +21,7 @@ #include #endif #include -#include +//#include /* host display size */ #define DISPLAY_X 800 @@ -193,7 +193,7 @@ class UI : public QWidget { Q_OBJECT public: - static void initToolkit(); + static void initToolkit(char *appPath); UI(QWidget *parent = 0); ~UI(); diff --git a/vs2005/stdint.h b/vs2005/stdint.h new file mode 100644 index 0000000..019b9e2 --- /dev/null +++ b/vs2005/stdint.h @@ -0,0 +1,52 @@ + + +#ifndef _MSC_STDINT_H_ // [ +#define _MSC_STDINT_H_ + + +#pragma once + +#include + +// For Visual Studio 6 in C++ mode and for many Visual Studio versions when +// compiling for ARM we should wrap include with 'extern "C++" {}' +// or compiler give many errors like this: +// error C2733: second C linkage of overloaded function 'wmemchr' not allowed +#ifdef __cplusplus +extern "C" { +#endif +# include +#ifdef __cplusplus +} +#endif + +// Define _W64 macros to mark types changing their size, like intptr_t. +#ifndef _W64 +# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) +# define _W64 __w64 +# else +# define _W64 +# endif +#endif + + + typedef signed __int8 int8_t; + typedef signed __int16 int16_t; + typedef signed __int32 int32_t; + typedef unsigned __int8 uint8_t; + typedef unsigned __int16 uint16_t; + typedef unsigned __int32 uint32_t; + +typedef signed __int64 int64_t; +typedef unsigned __int64 uint64_t; + +#ifdef _WIN64 // [ + typedef signed __int64 intptr_t; + typedef unsigned __int64 uintptr_t; +#else // _WIN64 ][ + typedef _W64 signed int intptr_t; + typedef _W64 unsigned int uintptr_t; +#endif // _WIN64 ] + + +#endif // _MSC_STDINT_H_ ]