diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 00000000..2e859f8a Binary files /dev/null and b/.DS_Store differ diff --git a/.gitattributes b/.gitattributes index 3cc9650a..a1bbea9a 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,2 +1,2 @@ -*.vcxproj text eol=crlf -*.sln text eol=crlf +*.vcxproj text eol=crlf +*.sln text eol=crlf diff --git a/.github/workflows/cmake-sdl1-win64.yml b/.github/workflows/cmake-sdl1-win64.yml new file mode 100644 index 00000000..e29b739c --- /dev/null +++ b/.github/workflows/cmake-sdl1-win64.yml @@ -0,0 +1,56 @@ +name: Oricutron Release on windows-latest - cmake SDL1 + +on: workflow_dispatch + +env: + # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.) + BUILD_TYPE: Release + +jobs: + build: + # The CMake configure and build commands are platform agnostic and should work equally + # well on Windows or Mac. You can convert this to a matrix build if you need + # cross-platform coverage. + # See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix + runs-on: windows-latest + + steps: + - uses: actions/checkout@v2 + + - name: Install SDL1 + run: pushd ${{github.workspace}}/msvc && git clone -q --depth 1 --single-branch https://github.com/Microsoft/vcpkg.git && .\vcpkg\bootstrap-vcpkg.bat && .\vcpkg\vcpkg.exe install sdl1:x64-windows && popd + + - name: Create Build Environment + # Some projects don't allow in-source building, so create a separate build directory + # We'll use this as our working directory for all subsequent commands + run: cmake -E make_directory ${{github.workspace}}/build + + - name: Configure CMake + # Use a bash shell so we can use the same syntax for environment variable + # access regardless of the host operating system + shell: bash + working-directory: ${{github.workspace}}/build + # Note the current convention is to use the -S and -B options here to specify source + # and build directories, but this is only available with CMake 3.13 and higher. + # The CMake binaries on the Github Actions machines are (as of this writing) 3.12 + run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE + + - name: Build + working-directory: ${{github.workspace}}/build + shell: bash + # Execute the build. You can specify a specific target with "--target " + run: cmake --build . --config $BUILD_TYPE + + - name: Upload Build Artifacts + uses: actions/upload-artifact@v4 + with: + name: build-artifacts + path: ${{github.workspace}}/build + +# We have no tests at the moment +# - name: Test +# working-directory: ${{github.workspace}}/build +# shell: bash +# # Execute tests defined by the CMake configuration. +# # See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail +# run: ctest -C $BUILD_TYPE diff --git a/.github/workflows/cmake-sdl1.yml b/.github/workflows/cmake-sdl1.yml new file mode 100644 index 00000000..b41cc81e --- /dev/null +++ b/.github/workflows/cmake-sdl1.yml @@ -0,0 +1,55 @@ +name: Oricutron Release on ubuntu-latest - cmake SDL1 GTK3 + +on: [push] + +env: + # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.) + BUILD_TYPE: Release + +jobs: + build: + # The CMake configure and build commands are platform agnostic and should work equally + # well on Windows or Mac. You can convert this to a matrix build if you need + # cross-platform coverage. + # See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + + - name: Install SDL1 GTK3 + run: sudo apt-get update -qq && sudo apt-get install libsdl1.2-dev -y && sudo apt-get install libgtk-3-dev -y + + - name: Create Build Environment + # Some projects don't allow in-source building, so create a separate build directory + # We'll use this as our working directory for all subsequent commands + run: cmake -E make_directory ${{github.workspace}}/build + + - name: Configure CMake + # Use a bash shell so we can use the same syntax for environment variable + # access regardless of the host operating system + shell: bash + working-directory: ${{github.workspace}}/build + # Note the current convention is to use the -S and -B options here to specify source + # and build directories, but this is only available with CMake 3.13 and higher. + # The CMake binaries on the Github Actions machines are (as of this writing) 3.12 + run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE + + - name: Build + working-directory: ${{github.workspace}}/build + shell: bash + # Execute the build. You can specify a specific target with "--target " + run: cmake --build . --config $BUILD_TYPE + + - name: Upload Build Artifacts + uses: actions/upload-artifact@v4 + with: + name: build-artifacts + path: ${{github.workspace}}/build +# We have no tests at the moment +# - name: Test +# working-directory: ${{github.workspace}}/build +# shell: bash +# # Execute tests defined by the CMake configuration. +# # See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail +# run: ctest -C $BUILD_TYPE diff --git a/.github/workflows/cmake-win64.yml b/.github/workflows/cmake-win64.yml new file mode 100644 index 00000000..1e466d78 --- /dev/null +++ b/.github/workflows/cmake-win64.yml @@ -0,0 +1,55 @@ +name: Oricutron Release on windows-latest - cmake SDL2 GTK3 (x64) + +on: [push] + +env: + # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.) + BUILD_TYPE: Release + +jobs: + build: + # The CMake configure and build commands are platform agnostic and should work equally + # well on Windows or Mac. You can convert this to a matrix build if you need + # cross-platform coverage. + # See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix + runs-on: windows-latest + + steps: + - uses: actions/checkout@v2 + + - name: Install SDL2 and GTK3 + run: pushd ${{github.workspace}}/msvc && git clone -q --depth 1 --single-branch https://github.com/Microsoft/vcpkg.git && .\vcpkg\bootstrap-vcpkg.bat && .\vcpkg\vcpkg.exe install sdl2:x64-windows && popd + + - name: Create Build Environment + # Some projects don't allow in-source building, so create a separate build directory + # We'll use this as our working directory for all subsequent commands + run: cmake -E make_directory ${{github.workspace}}/build + + - name: Configure CMake + # Use a bash shell so we can use the same syntax for environment variable + # access regardless of the host operating system + shell: bash + working-directory: ${{github.workspace}}/build + # Note the current convention is to use the -S and -B options here to specify source + # and build directories, but this is only available with CMake 3.13 and higher. + # The CMake binaries on the Github Actions machines are (as of this writing) 3.12 + run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DUSE_SDL2:BOOL=ON + + - name: Build + working-directory: ${{github.workspace}}/build + shell: bash + # Execute the build. You can specify a specific target with "--target " + run: cmake --build . --config $BUILD_TYPE + + - name: Upload Build Artifacts + uses: actions/upload-artifact@v4 + with: + name: build-artifacts + path: ${{github.workspace}}/build +# We have no tests at the moment +# - name: Test +# working-directory: ${{github.workspace}}/build +# shell: bash +# # Execute tests defined by the CMake configuration. +# # See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail +# run: ctest -C $BUILD_TYPE diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml new file mode 100644 index 00000000..980337a6 --- /dev/null +++ b/.github/workflows/cmake.yml @@ -0,0 +1,56 @@ +name: Oricutron Release on ubuntu-latest - cmake SDL2 GTK3 + +on: [push] + +env: + # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.) + BUILD_TYPE: Release + +jobs: + build: + # The CMake configure and build commands are platform agnostic and should work equally + # well on Windows or Mac. You can convert this to a matrix build if you need + # cross-platform coverage. + # See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + + - name: Install SDL2 and GTK3 + run: sudo apt-get update -qq && sudo apt-get install libsdl2-dev -y --force-yes && sudo apt-get install libgtk-3-dev -y --force-yes + + - name: Create Build Environment + # Some projects don't allow in-source building, so create a separate build directory + # We'll use this as our working directory for all subsequent commands + run: cmake -E make_directory ${{github.workspace}}/build + + - name: Configure CMake + # Use a bash shell so we can use the same syntax for environment variable + # access regardless of the host operating system + shell: bash + working-directory: ${{github.workspace}}/build + # Note the current convention is to use the -S and -B options here to specify source + # and build directories, but this is only available with CMake 3.13 and higher. + # The CMake binaries on the Github Actions machines are (as of this writing) 3.12 + run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DUSE_SDL2:BOOL=ON + + - name: Build + working-directory: ${{github.workspace}}/build + shell: bash + # Execute the build. You can specify a specific target with "--target " + run: cmake --build . --config $BUILD_TYPE + + - name: Upload Build Artifacts + uses: actions/upload-artifact@v4 + with: + name: build-artifacts + path: ${{github.workspace}}/build + +# We have no tests at the moment +# - name: Test +# working-directory: ${{github.workspace}}/build +# shell: bash +# # Execute tests defined by the CMake configuration. +# # See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail +# run: ctest -C $BUILD_TYPE diff --git a/.gitignore b/.gitignore index 89855478..73a9b211 100644 --- a/.gitignore +++ b/.gitignore @@ -4,17 +4,27 @@ Release/ x64/ *.d *.o -/msvc/**/Debug clang -/msvc/**/Release clang -/msvc/**/images -/msvc/**/oricutron.cfg -/msvc/**/roms -/msvc/**/sdl -/msvc/**/sdl2 -/roms/*.rom -!/roms/orix*.rom -/oricutron.aps -/msvc/**/Oricutron.psess -/msvc/**/*.user -/msvc/**/vcpkg -build +msvc/**/Debug clang +msvc/**/Release clang +msvc/**/images +msvc/**/oricutron.cfg +msvc/**/roms +msvc/**/sdl +msvc/**/sdl2 +roms/*.rom +roms/orix*.rom +oricutron.aps +msvc/**/Oricutron.psess +msvc/**/*.user +msvc/**/vcpkg +build/** +SDL.dll +SDL2.dll +disks/*.dsk +pravdisks/*.dsk +teledisks/*.dsk +oricutron +Oricutron +Oricutron-sdl2 +Oricutron.exe +Oricutron-sdl2.exe diff --git a/6502.c b/6502.c index 104b27bb..cd1df949 100644 --- a/6502.c +++ b/6502.c @@ -28,7 +28,7 @@ #define ILLEGALS -void dbg_printf( char *fmt, ... ); +void dbg_printf(char* fmt, ...); #if defined(DEBUG_CPU_TRACE) && DEBUG_CPU_TRACE > 0 void mon_traceinst(struct m6502 *cpu); @@ -38,11 +38,11 @@ void mon_traceinst(struct m6502 *cpu); // You need to overwrite these with your own ones if you want // the CPU to do anything other than constantly execute brk // instructions :-) -static void nullwrite( struct m6502 *cpu, unsigned short addr, unsigned char data ) +static void nullwrite(struct m6502 *cpu, unsigned short addr, unsigned char data) { } -static unsigned char nullread( struct m6502 *cpu, unsigned short addr ) +static unsigned char nullread(struct m6502 *cpu, unsigned short addr) { return 0; } @@ -52,7 +52,7 @@ static unsigned char nullread( struct m6502 *cpu, unsigned short addr ) ** The userdata param is just used to fill in the ** cpu->userdata field. */ -void m6502_init( struct m6502 *cpu, void *userdata, SDL_bool nukebreakpoints ) +void m6502_init(struct m6502 *cpu, void* userdata, SDL_bool nukebreakpoints) { int i; cpu->rastercycles = 0; @@ -61,9 +61,9 @@ void m6502_init( struct m6502 *cpu, void *userdata, SDL_bool nukebreakpoints ) cpu->write = nullwrite; cpu->read = nullread; - if( nukebreakpoints ) + if(nukebreakpoints) { - for( i=0; i<16; i++ ) + for(i=0; i<16; i++) { cpu->breakpoints[i] = -1; cpu->membreakpoints[i].flags = 0; @@ -76,7 +76,7 @@ void m6502_init( struct m6502 *cpu, void *userdata, SDL_bool nukebreakpoints ) /* ** Resets the 6502 cpu to powerup state */ -void m6502_reset( struct m6502 *cpu ) +void m6502_reset(struct m6502 *cpu) { cpu->a = cpu->x = cpu->y = 0; cpu->sp = 0xff; @@ -87,7 +87,7 @@ void m6502_reset( struct m6502 *cpu ) cpu->f_b = 0; cpu->f_v = 0; cpu->f_n = 0; - cpu->pc = (cpu->read( cpu, 0xfffd )<<8) | cpu->read( cpu, 0xfffc ); + cpu->pc = (cpu->read(cpu, 0xfffd)<<8) | cpu->read(cpu, 0xfffc); cpu->lastpc = 0; cpu->nmi = SDL_FALSE; cpu->irq = 0; @@ -110,14 +110,16 @@ void m6502_reset( struct m6502 *cpu ) // Macro to perform ADC logic #define DO_ADC if( cpu->f_d )\ {\ + r = cpu->a + v + cpu->f_c;\ + cpu->f_z = (r & 0xff)==0;\ r = (cpu->a&0xf)+(v&0xf)+cpu->f_c;\ - if( r > 9 ) r += 6;\ - t = (cpu->a>>4)+(v>>4)+(r>15?1:0);\ - if( t > 9 ) t += 6;\ - cpu->a = (r&0xf)|(t<<4);\ - cpu->f_c = t>15 ? 1 : 0;\ - cpu->f_z = cpu->a==0;\ - cpu->f_n = cpu->a&0x80;\ + if( r > 9 ) r = ((r+6)& 0xf)+0x10;\ + t = (cpu->a & 0xf0)+(v & 0xf0)+r;\ + cpu->f_v = (~(cpu->a^v)&(cpu->a^t)) & FF_N ? 1 : 0;\ + cpu->f_n = (t&0x80) ? 1 : 0;\ + if (t >= 0xa0) t += 0x60;\ + cpu->a = t;\ + cpu->f_c = t>=0x100 ? 1 : 0;\ } else {\ r = cpu->a + v + cpu->f_c;\ cpu->f_v = (~(cpu->a^v)&(cpu->a^r)) & FF_N ? 1 : 0;\ @@ -162,14 +164,17 @@ void m6502_reset( struct m6502 *cpu ) // Macro to perform SBC logic #define DO_SBC if( cpu->f_d )\ {\ - r = (cpu->a&0xf) - (v&0xf) - (cpu->f_c^1);\ - if( r&0x10 ) r -= 6;\ - t = (cpu->a>>4) - (v>>4) - ((r&0x10)>>4);\ - if( t&0x10 ) t -= 6;\ - cpu->a = (r&0xf)|(t<<4);\ - cpu->f_c = (t>15) ? 0 : 1;\ - cpu->f_z = cpu->a==0;\ - cpu->f_n = cpu->a&0x80;\ + r = (cpu->a - v) - (cpu->f_c^1);\ + cpu->f_v = ((cpu->a^v)&(cpu->a^r)) & FF_N ? 1 : 0;\ + cpu->f_z = (r & 0xff) == 0;\ + cpu->f_n = (r & 0x80) != 0;\ + t = v& 0xf0;\ + r = (cpu->a & 0xf) - (v & 0xf) - (cpu->f_c^1);\ + if( r & 0x80 ) {r = (r-6) & 0x0f; t += 0x10;};\ + r = r + (cpu->a & 0xf0);\ + if (t > r) t += 0x60;\ + cpu->f_c = (cpu->a >= (v+(cpu->f_c^1))) ? 1 : 0;\ + cpu->a = r-t;\ } else {\ r = (cpu->a - v) - (cpu->f_c^1);\ cpu->f_v = ((cpu->a^v)&(cpu->a^r)) & FF_N ? 1 : 0;\ @@ -276,27 +281,29 @@ void m6502_reset( struct m6502 *cpu ) // Get the number of cycles the NEXT cpu instruction will take // Returns TRUE if we've hit some kind of breakpoint -SDL_bool m6502_set_icycles( struct m6502 *cpu, SDL_bool dobp, char *bpmsg ) +SDL_bool m6502_set_icycles(struct m6502 *cpu, SDL_bool dobp, char* bpmsg) { unsigned short baddr; unsigned int extra = 0; int i; - if( cpu->nmicount > 0 ) + if(cpu->nmicount > 0) { cpu->nmicount--; - if( !cpu->nmicount ) + if(!cpu->nmicount) cpu->nmi = SDL_FALSE; } - if( cpu->nmi ) + if(cpu->nmi) { extra = 7; - cpu->calcpc = (cpu->read( cpu, 0xfffb )<<8)|cpu->read( cpu, 0xfffa ); + cpu->calcpc = (cpu->read(cpu, 0xfffb)<<8)|cpu->read(cpu, 0xfffa); cpu->calcint = 2; - } else if( ( cpu->irq ) && ( cpu->f_i == 0 ) ) { + } + else if((cpu->irq) && (cpu->f_i == 0)) + { extra = 7; - cpu->calcpc = (cpu->read( cpu, 0xffff )<<8)|cpu->read( cpu, 0xfffe ); + cpu->calcpc = (cpu->read(cpu, 0xffff)<<8)|cpu->read(cpu, 0xfffe); cpu->calcint = 1; } else @@ -305,22 +312,28 @@ SDL_bool m6502_set_icycles( struct m6502 *cpu, SDL_bool dobp, char *bpmsg ) cpu->calcint = 0; } - cpu->calcop = cpu->read( cpu, cpu->calcpc ); - if( dobp ) + cpu->calcop = cpu->read(cpu, cpu->calcpc); + if(dobp) { - if( cpu->anybp ) + if(cpu->anybp) { - for( i=0; i<16; i++ ) + for(i=0; i<16; i++) { - if( ( cpu->breakpoints[i] != -1 ) && ( cpu->calcpc == cpu->breakpoints[i] ) ) + if((cpu->breakpoints[i] != -1) && (cpu->calcpc == cpu->breakpoints[i])) { - if( (cpu->breakpoint_flags[i] & MBPF_RESETCYCLES) == MBPF_RESETCYCLES ) cpu->cycles = 0; - if( (cpu->breakpoint_flags[i] & MBPF_RESETCYCLESCONTINUE) != MBPF_RESETCYCLESCONTINUE ) return SDL_TRUE; + if((cpu->breakpoint_flags[i] & MBPF_RESETCYCLESPRINT) == MBPF_RESETCYCLESPRINT) + printf("%.4X: %d\n", cpu->breakpoints[i], cpu->cycles); + + if((cpu->breakpoint_flags[i] & MBPF_RESETCYCLES) == MBPF_RESETCYCLES) + cpu->cycles = 0; + + if((cpu->breakpoint_flags[i] & MBPF_RESETCYCLESCONTINUE) != MBPF_RESETCYCLESCONTINUE) + return SDL_TRUE; } } } - if( cpu->anymbp ) + if(cpu->anymbp) { unsigned short waddr, raddr, wlen, rlen; @@ -328,7 +341,7 @@ SDL_bool m6502_set_icycles( struct m6502 *cpu, SDL_bool dobp, char *bpmsg ) wlen = rlen = 0; // Going to read or write? - switch( cpu->calcop ) + switch(cpu->calcop) { case 0x00: // { "BRK", AM_IMP }, // 00 waddr = (cpu->sp+0x100)-3; @@ -376,7 +389,7 @@ SDL_bool m6502_set_icycles( struct m6502 *cpu, SDL_bool dobp, char *bpmsg ) case 0x07: // { "SLO", AM_ZP }, // 07 (illegal) case 0x47: // { "SRE", AM_ZP }, // 47 (illegal) #endif - RW_BADDR_ZP; + RW_BADDR_ZP; break; case 0x0E: // { "ASL", AM_ABS }, // 0E @@ -393,7 +406,7 @@ SDL_bool m6502_set_icycles( struct m6502 *cpu, SDL_bool dobp, char *bpmsg ) case 0x0F: // { "SLO", AM_ABS }, // 0F (illegal) case 0x4F: // { "SRE", AM_ABS }, // 4F (illegal) #endif - RW_BADDR_ABS; + RW_BADDR_ABS; break; case 0x1E: // { "ASL", AM_ABX }, // 1E @@ -410,7 +423,7 @@ SDL_bool m6502_set_icycles( struct m6502 *cpu, SDL_bool dobp, char *bpmsg ) case 0x1F: // { "SLO", AM_ABX }, // 1F (illegal) case 0x5F: // { "SRE", AM_ABX }, // 5F (illegal) #endif - RW_BADDR_ABX; + RW_BADDR_ABX; break; case 0x16: // { "ASL", AM_ZPX }, // 16 @@ -427,7 +440,7 @@ SDL_bool m6502_set_icycles( struct m6502 *cpu, SDL_bool dobp, char *bpmsg ) case 0x17: // { "SLO", AM_ZPX }, // 17 (illegal) case 0x57: // { "SRE", AM_ZPX }, // 57 (illegal) #endif - RW_BADDR_ZPX; + RW_BADDR_ZPX; break; #ifdef ILLEGALS @@ -469,7 +482,7 @@ SDL_bool m6502_set_icycles( struct m6502 *cpu, SDL_bool dobp, char *bpmsg ) #ifdef ILLEGALS case 0xA3: // { "LAX", AM_ZIX }, // A3 (illegal) #endif - R_BADDR_ZIX; + R_BADDR_ZIX; break; case 0x11: // { "ORA", AM_ZIY }, // 11 @@ -483,7 +496,7 @@ SDL_bool m6502_set_icycles( struct m6502 *cpu, SDL_bool dobp, char *bpmsg ) #ifdef ILLEGALS case 0xB3: // { "LAX", AM_ZIY }, // B3 (illegal) #endif - R_BADDR_ZIY; + R_BADDR_ZIY; break; case 0x05: // { "ORA", AM_ZP }, // 05 @@ -501,7 +514,7 @@ SDL_bool m6502_set_icycles( struct m6502 *cpu, SDL_bool dobp, char *bpmsg ) #ifdef ILLEGALS case 0xA7: // { "LAX", AM_ZP }, // A7 (illegal) #endif - R_BADDR_ZP; + R_BADDR_ZP; break; case 0x0D: // { "ORA", AM_ABS }, // 0D @@ -519,7 +532,7 @@ SDL_bool m6502_set_icycles( struct m6502 *cpu, SDL_bool dobp, char *bpmsg ) #ifdef ILLEGALS case 0xAF: // { "LAX", AM_ABS }, // AF (illegal) #endif - R_BADDR_ABS; + R_BADDR_ABS; break; case 0x15: // { "ORA", AM_ZPX }, // 15 @@ -544,7 +557,7 @@ SDL_bool m6502_set_icycles( struct m6502 *cpu, SDL_bool dobp, char *bpmsg ) #ifdef ILLEGALS case 0xBF: // { "LAX", AM_ABY }, // BF (illegal) #endif - R_BADDR_ABY; + R_BADDR_ABY; break; case 0x1D: // { "ORA", AM_ABX }, // 1D @@ -560,13 +573,13 @@ SDL_bool m6502_set_icycles( struct m6502 *cpu, SDL_bool dobp, char *bpmsg ) case 0xB6: // { "LDX", AM_ZPY }, // B6 #ifdef ILLEGALS - case 0xB7: // { "LAX", AM_ZPY }, // B7 (illegal) + case 0xB7: // { "LAX", AM_ZPY }, // B7 (illegal) #endif - R_BADDR_ZPY; + R_BADDR_ZPY; break; case 0x6C: // { "JMP", AM_IND }, // 6C - raddr = (cpu->read( cpu, cpu->calcpc+2 )<<8)|cpu->read( cpu, cpu->calcpc+1 ); + raddr = (cpu->read(cpu, cpu->calcpc+2)<<8)|cpu->read(cpu, cpu->calcpc+1); rlen = 2; break; @@ -574,7 +587,7 @@ SDL_bool m6502_set_icycles( struct m6502 *cpu, SDL_bool dobp, char *bpmsg ) #ifdef ILLEGALS case 0x83: // { "SAX", AM_ZIX }, // 83 (illegal) #endif - W_BADDR_ZIX; + W_BADDR_ZIX; break; case 0x84: // { "STY", AM_ZP }, // 84 @@ -583,7 +596,7 @@ SDL_bool m6502_set_icycles( struct m6502 *cpu, SDL_bool dobp, char *bpmsg ) #ifdef ILLEGALS case 0x87: // { "SAX", AM_ZP }, // 87 (illegal) #endif - W_BADDR_ZP; + W_BADDR_ZP; break; case 0x8C: // { "STY", AM_ABS }, // 8C @@ -592,7 +605,7 @@ SDL_bool m6502_set_icycles( struct m6502 *cpu, SDL_bool dobp, char *bpmsg ) #ifdef ILLEGALS case 0x8F: // { "SAX", AM_ABS }, // 8F (illegal) #endif - W_BADDR_ABS; + W_BADDR_ABS; break; case 0x91: // { "STA", AM_ZIY }, // 91 @@ -608,7 +621,7 @@ SDL_bool m6502_set_icycles( struct m6502 *cpu, SDL_bool dobp, char *bpmsg ) #ifdef ILLEGALS case 0x97: // { "SAX", AM_ZPY }, // 97 (illegal) #endif - W_BADDR_ZPY; + W_BADDR_ZPY; break; case 0x99: // { "STA", AM_ABY }, // 99 @@ -616,7 +629,7 @@ SDL_bool m6502_set_icycles( struct m6502 *cpu, SDL_bool dobp, char *bpmsg ) case 0x9F: // { "AHX", AM_ABY }, // 9F (illegal, unstable) case 0x9B: // { "TAS", AM_ABY }, // 9B (illegal, unstable) #endif - W_BADDR_ABY; + W_BADDR_ABY; break; case 0x9D: // { "STA", AM_ABX }, // 9D @@ -624,34 +637,34 @@ SDL_bool m6502_set_icycles( struct m6502 *cpu, SDL_bool dobp, char *bpmsg ) break; } - for( i=0; i<16; i++ ) + for(i=0; i<16; i++) { - if( ( wlen != 0 ) && ( cpu->membreakpoints[i].flags & MBPF_WRITE ) ) + if((wlen != 0) && (cpu->membreakpoints[i].flags & MBPF_WRITE)) { - if( ( cpu->membreakpoints[i].addr >= waddr ) && - ( cpu->membreakpoints[i].addr < (waddr+wlen) ) ) + if((cpu->membreakpoints[i].addr >= waddr) && + (cpu->membreakpoints[i].addr < (waddr+wlen))) { - sprintf( bpmsg, "Break on WRITE to $%04X", cpu->membreakpoints[i].addr ); + sprintf(bpmsg, "Break on WRITE to $%04X", cpu->membreakpoints[i].addr); return SDL_TRUE; } } - if( ( rlen != 0 ) && ( cpu->membreakpoints[i].flags & MBPF_READ ) ) + if((rlen != 0) && (cpu->membreakpoints[i].flags & MBPF_READ)) { - if( ( cpu->membreakpoints[i].addr >= raddr ) && - ( cpu->membreakpoints[i].addr < (raddr+rlen) ) ) + if((cpu->membreakpoints[i].addr >= raddr) && + (cpu->membreakpoints[i].addr < (raddr+rlen))) { - sprintf( bpmsg, "Break on READ from $%04X", cpu->membreakpoints[i].addr ); + sprintf(bpmsg, "Break on READ from $%04X", cpu->membreakpoints[i].addr); return SDL_TRUE; } } - if( cpu->membreakpoints[i].flags & MBPF_CHANGE ) + if(cpu->membreakpoints[i].flags & MBPF_CHANGE) { - if( cpu->membreakpoints[i].lastval != cpu->read( cpu, cpu->membreakpoints[i].addr ) ) + if(cpu->membreakpoints[i].lastval != cpu->read(cpu, cpu->membreakpoints[i].addr)) { - cpu->membreakpoints[i].lastval = cpu->read( cpu, cpu->membreakpoints[i].addr ); - sprintf( bpmsg, "Break after $%04X changed", cpu->membreakpoints[i].addr ); + cpu->membreakpoints[i].lastval = cpu->read(cpu, cpu->membreakpoints[i].addr); + sprintf(bpmsg, "Break after $%04X changed", cpu->membreakpoints[i].addr); return SDL_TRUE; } } @@ -660,7 +673,7 @@ SDL_bool m6502_set_icycles( struct m6502 *cpu, SDL_bool dobp, char *bpmsg ) } - switch( cpu->calcop ) + switch(cpu->calcop) { case 0x00: // { "BRK", AM_IMP }, // 00 case 0x1E: // { "ASL", AM_ABX }, // 1E @@ -881,7 +894,7 @@ SDL_bool m6502_set_icycles( struct m6502 *cpu, SDL_bool dobp, char *bpmsg ) break; case 0x10: // { "BPL", AM_REL }, // 10 - IBRANCH( !cpu->f_n ); + IBRANCH(!cpu->f_n); break; case 0x11: // { "ORA", AM_ZIY }, // 11 @@ -892,19 +905,19 @@ SDL_bool m6502_set_icycles( struct m6502 *cpu, SDL_bool dobp, char *bpmsg ) case 0xD1: // { "CMP", AM_ZIY }, // D1 case 0xF1: // { "SBC", AM_ZIY }, // F1 case 0xB3: // { "LAX", AM_ZIY }, // B3 (illegal) - baddr = cpu->read( cpu, cpu->calcpc+1 ); - baddr = ((cpu->read( cpu, baddr+1 )<<8) | cpu->read( cpu, baddr )); + baddr = cpu->read(cpu, cpu->calcpc+1); + baddr = ((cpu->read(cpu, baddr+1)<<8) | cpu->read(cpu, baddr)); cpu->icycles = 5; cpu->baddr = baddr+cpu->y; - if( CPAGECHECK ) cpu->icycles++; + if(CPAGECHECK) cpu->icycles++; break; case 0xBB: // { "LAS", AM_ZIY }, // BB - baddr = cpu->read( cpu, cpu->calcpc+1 ); - baddr = ((cpu->read( cpu, baddr+1 )<<8) | cpu->read( cpu, baddr )); + baddr = cpu->read(cpu, cpu->calcpc+1); + baddr = ((cpu->read(cpu, baddr+1)<<8) | cpu->read(cpu, baddr)); cpu->icycles = 4; cpu->baddr = baddr+cpu->y; - if( CPAGECHECK ) cpu->icycles++; + if(CPAGECHECK) cpu->icycles++; break; case 0x19: // { "ORA", AM_ABY }, // 19 @@ -919,7 +932,7 @@ SDL_bool m6502_set_icycles( struct m6502 *cpu, SDL_bool dobp, char *bpmsg ) NBADDR_ABS; cpu->icycles = 4; cpu->baddr = baddr+cpu->y; - if( CPAGECHECK ) cpu->icycles++; + if(CPAGECHECK) cpu->icycles++; break; case 0x1D: // { "ORA", AM_ABX }, // 1D @@ -939,35 +952,35 @@ SDL_bool m6502_set_icycles( struct m6502 *cpu, SDL_bool dobp, char *bpmsg ) NBADDR_ABS; cpu->icycles = 4; cpu->baddr = baddr+cpu->x; - if( CPAGECHECK ) cpu->icycles++; + if(CPAGECHECK) cpu->icycles++; break; case 0x30: // { "BMI", AM_REL }, // 30 - IBRANCH( cpu->f_n ); + IBRANCH(cpu->f_n); break; case 0x50: // { "BVC", AM_REL }, // 50 - IBRANCH( !cpu->f_v ); + IBRANCH(!cpu->f_v); break; case 0x70: // { "BVS", AM_REL }, // 70 - IBRANCH( cpu->f_v ); + IBRANCH(cpu->f_v); break; case 0x90: // { "BCC", AM_REL }, // 90 - IBRANCH( !cpu->f_c ); + IBRANCH(!cpu->f_c); break; case 0xB0: // { "BCS", AM_REL }, // B0 - IBRANCH( cpu->f_c ); + IBRANCH(cpu->f_c); break; case 0xD0: // { "BNE", AM_REL }, // D0 - IBRANCH( !cpu->f_z ); + IBRANCH(!cpu->f_z); break; case 0xF0: // { "BEQ", AM_REL }, // F0 - IBRANCH( cpu->f_z ); + IBRANCH(cpu->f_z); break; default: @@ -980,7 +993,7 @@ SDL_bool m6502_set_icycles( struct m6502 *cpu, SDL_bool dobp, char *bpmsg ) } // Execute one 6502 instruction -SDL_bool m6502_inst( struct m6502 *cpu ) +SDL_bool m6502_inst(struct m6502 *cpu) { unsigned char v; unsigned short r, t, baddr; @@ -988,15 +1001,17 @@ SDL_bool m6502_inst( struct m6502 *cpu ) // Make sure you call set_icycles before this routine! cpu->cycles += cpu->icycles; - if( cpu->calcint > 0 ) + if(cpu->calcint > 0) { - PUSHW( cpu->pc ); - PUSHB( MAKEFLAGSBC ); + PUSHW(cpu->pc); + PUSHB(MAKEFLAGSBC); cpu->f_d = 0; - if( cpu->calcint == 2 ) + if(cpu->calcint == 2) { cpu->nmi = SDL_FALSE; - } else { + } + else + { cpu->f_i = 1; } } @@ -1007,14 +1022,14 @@ SDL_bool m6502_inst( struct m6502 *cpu ) cpu->lastpc = cpu->pc = cpu->calcpc; cpu->pc++; - switch( cpu->calcop ) + switch(cpu->calcop) { case 0x00: // { "BRK", AM_IMP }, // 00 - PUSHW( (cpu->pc+1) ); - PUSHB( MAKEFLAGS | (1<<4) ); // Set B on the stack + PUSHW((cpu->pc+1)); + PUSHB(MAKEFLAGS | (1<<4)); // Set B on the stack cpu->f_i = 1; cpu->f_d = 0; - cpu->pc = (cpu->read( cpu, 0xffff )<<8) | cpu->read( cpu, 0xfffe ); + cpu->pc = (cpu->read(cpu, 0xffff)<<8) | cpu->read(cpu, 0xfffe); break; case 0x01: // { "ORA", AM_ZIX }, // 01 @@ -1030,11 +1045,11 @@ SDL_bool m6502_inst( struct m6502 *cpu ) case 0x06: // { "ASL", AM_ZP }, // 06 KREAD_ZP; DO_ASL(v); - cpu->write( cpu, baddr, v ); + cpu->write(cpu, baddr, v); break; case 0x08: // { "PHP", AM_IMP }, // 08 - PUSHB( MAKEFLAGS ); + PUSHB(MAKEFLAGS); break; case 0x09: // { "ORA", AM_IMM }, // 09 @@ -1054,15 +1069,15 @@ SDL_bool m6502_inst( struct m6502 *cpu ) case 0x0E: // { "ASL", AM_ABS }, // 0E KREAD_ABS; DO_ASL(v); - cpu->write( cpu, baddr, v ); + cpu->write(cpu, baddr, v); break; case 0x10: // { "BPL", AM_REL }, // 10 - BRANCH( !cpu->f_n ); + BRANCH(!cpu->f_n); break; case 0x11: // { "ORA", AM_ZIY }, // 11 - v = cpu->read( cpu, cpu->baddr ); // baddr is already calculated for this case + v = cpu->read(cpu, cpu->baddr); // baddr is already calculated for this case cpu->pc++; DO_ORA; break; @@ -1075,7 +1090,7 @@ SDL_bool m6502_inst( struct m6502 *cpu ) case 0x16: // { "ASL", AM_ZPX }, // 16 KREAD_ZPX; DO_ASL(v); - cpu->write( cpu, baddr, v ); + cpu->write(cpu, baddr, v); break; case 0x18: // { "CLC", AM_IMP }, // 18 @@ -1084,7 +1099,7 @@ SDL_bool m6502_inst( struct m6502 *cpu ) case 0x19: // { "ORA", AM_ABY }, // 19 case 0x1D: // { "ORA", AM_ABX }, // 1D - v = cpu->read( cpu, cpu->baddr ); // baddr is already calculated for this case + v = cpu->read(cpu, cpu->baddr); // baddr is already calculated for this case cpu->pc+=2; DO_ORA; break; @@ -1092,12 +1107,12 @@ SDL_bool m6502_inst( struct m6502 *cpu ) case 0x1E: // { "ASL", AM_ABX }, // 1E READ_ABX; DO_ASL(v); - cpu->write( cpu, baddr, v ); + cpu->write(cpu, baddr, v); break; case 0x20: // { "JSR", AM_ABS }, // 20 - baddr = (cpu->read( cpu, cpu->pc+1 )<<8) | cpu->read( cpu, cpu->pc ); - PUSHW( (cpu->pc+1) ); + baddr = (cpu->read(cpu, cpu->pc+1)<<8) | cpu->read(cpu, cpu->pc); + PUSHW((cpu->pc+1)); cpu->pc = baddr; break; @@ -1121,7 +1136,7 @@ SDL_bool m6502_inst( struct m6502 *cpu ) case 0x26: // { "ROL", AM_ZP }, // 26 KREAD_ZP; DO_ROL(v); - cpu->write( cpu, baddr, v ); + cpu->write(cpu, baddr, v); break; case 0x28: // { "PLP", AM_IMP }, // 28 @@ -1153,15 +1168,15 @@ SDL_bool m6502_inst( struct m6502 *cpu ) case 0x2E: // { "ROL", AM_ABS }, // 2E KREAD_ABS; DO_ROL(v); - cpu->write( cpu, baddr, v ); + cpu->write(cpu, baddr, v); break; case 0x30: // { "BMI", AM_REL }, // 30 - BRANCH( cpu->f_n ); + BRANCH(cpu->f_n); break; case 0x31: // { "AND", AM_ZIY }, // 31 - v = cpu->read( cpu, cpu->baddr ); // baddr is already calculated for this case + v = cpu->read(cpu, cpu->baddr); // baddr is already calculated for this case cpu->pc++; DO_AND; break; @@ -1174,7 +1189,7 @@ SDL_bool m6502_inst( struct m6502 *cpu ) case 0x36: // { "ROL", AM_ZPX }, // 36 KREAD_ZPX; DO_ROL(v); - cpu->write( cpu, baddr, v ); + cpu->write(cpu, baddr, v); break; case 0x38: // { "SEC", AM_IMP }, // 38 @@ -1183,7 +1198,7 @@ SDL_bool m6502_inst( struct m6502 *cpu ) case 0x39: // { "AND", AM_ABY }, // 39 case 0x3D: // { "AND", AM_ABX }, // 3D - v = cpu->read( cpu, cpu->baddr ); // baddr is already calculated for this case + v = cpu->read(cpu, cpu->baddr); // baddr is already calculated for this case cpu->pc+=2; DO_AND; break; @@ -1191,13 +1206,13 @@ SDL_bool m6502_inst( struct m6502 *cpu ) case 0x3E: // { "ROL", AM_ABX }, // 3E READ_ABX; DO_ROL(v); - cpu->write( cpu, baddr, v ); + cpu->write(cpu, baddr, v); break; case 0x40: // { "RTI", AM_IMP }, // 40 v = POPB; SETFLAGS(v); - POPW( cpu->pc ); + POPW(cpu->pc); break; case 0x41: // { "EOR", AM_ZIX }, // 41 @@ -1213,11 +1228,11 @@ SDL_bool m6502_inst( struct m6502 *cpu ) case 0x46: // { "LSR", AM_ZP }, // 46 KREAD_ZP; DO_LSR(v); - cpu->write( cpu, baddr, v ); + cpu->write(cpu, baddr, v); break; case 0x48: // { "PHA", AM_IMP }, // 48 - PUSHB( cpu->a ); + PUSHB(cpu->a); break; case 0x49: // { "EOR", AM_IMM }, // 49 @@ -1230,7 +1245,7 @@ SDL_bool m6502_inst( struct m6502 *cpu ) break; case 0x4C: // { "JMP", AM_ABS }, // 4C - cpu->pc = (cpu->read( cpu, cpu->pc+1 )<<8)|cpu->read( cpu, cpu->pc ); + cpu->pc = (cpu->read(cpu, cpu->pc+1)<<8)|cpu->read(cpu, cpu->pc); break; case 0x4D: // { "EOR", AM_ABS }, // 4D @@ -1241,15 +1256,15 @@ SDL_bool m6502_inst( struct m6502 *cpu ) case 0x4E: // { "LSR", AM_ABS }, // 4E KREAD_ABS; DO_LSR(v); - cpu->write( cpu, baddr, v ); + cpu->write(cpu, baddr, v); break; case 0x50: // { "BVC", AM_REL }, // 50 - BRANCH( !cpu->f_v ); + BRANCH(!cpu->f_v); break; case 0x51: // { "EOR", AM_ZIY }, // 51 - v = cpu->read( cpu, cpu->baddr ); // baddr is already calculated for this case + v = cpu->read(cpu, cpu->baddr); // baddr is already calculated for this case cpu->pc++; DO_EOR; break; @@ -1262,7 +1277,7 @@ SDL_bool m6502_inst( struct m6502 *cpu ) case 0x56: // { "LSR", AM_ZPX }, // 56 KREAD_ZPX; DO_LSR(v); - cpu->write( cpu, baddr, v ); + cpu->write(cpu, baddr, v); break; case 0x58: // { "CLI", AM_IMP }, // 58 @@ -1271,7 +1286,7 @@ SDL_bool m6502_inst( struct m6502 *cpu ) case 0x59: // { "EOR", AM_ABY }, // 59 case 0x5D: // { "EOR", AM_ABX }, // 5D - v = cpu->read( cpu, cpu->baddr ); // baddr is already calculated for this case + v = cpu->read(cpu, cpu->baddr); // baddr is already calculated for this case cpu->pc+=2; DO_EOR; break; @@ -1279,11 +1294,11 @@ SDL_bool m6502_inst( struct m6502 *cpu ) case 0x5E: // { "LSR", AM_ABX }, // 5E READ_ABX; DO_LSR(v); - cpu->write( cpu, baddr, v ); + cpu->write(cpu, baddr, v); break; case 0x60: // { "RTS", AM_IMP }, // 60 - POPW( cpu->pc ); + POPW(cpu->pc); cpu->pc++; break; @@ -1300,7 +1315,7 @@ SDL_bool m6502_inst( struct m6502 *cpu ) case 0x66: // { "ROR", AM_ZP }, // 66 KREAD_ZP; DO_ROR(v); - cpu->write( cpu, baddr, v ); + cpu->write(cpu, baddr, v); break; case 0x68: // { "PLA", AM_IMP }, // 68 @@ -1318,8 +1333,8 @@ SDL_bool m6502_inst( struct m6502 *cpu ) break; case 0x6C: // { "JMP", AM_IND }, // 6C - baddr = (cpu->read( cpu, cpu->pc+1 )<<8)|cpu->read( cpu, cpu->pc ); - cpu->pc = (cpu->read( cpu, baddr+1 )<<8)|cpu->read( cpu, baddr ); + baddr = (cpu->read(cpu, cpu->pc+1)<<8)|cpu->read(cpu, cpu->pc); + cpu->pc = (cpu->read(cpu, baddr+1)<<8)|cpu->read(cpu, baddr); break; case 0x6D: // { "ADC", AM_ABS }, // 6D @@ -1330,15 +1345,15 @@ SDL_bool m6502_inst( struct m6502 *cpu ) case 0x6E: // { "ROR", AM_ABS }, // 6E KREAD_ABS; DO_ROR(v); - cpu->write( cpu, baddr, v ); + cpu->write(cpu, baddr, v); break; case 0x70: // { "BVS", AM_REL }, // 70 - BRANCH( cpu->f_v ); + BRANCH(cpu->f_v); break; case 0x71: // { "ADC", AM_ZIY }, // 71 - v = cpu->read( cpu, cpu->baddr ); // baddr is already calculated for this case + v = cpu->read(cpu, cpu->baddr); // baddr is already calculated for this case cpu->pc++; DO_ADC; break; @@ -1351,7 +1366,7 @@ SDL_bool m6502_inst( struct m6502 *cpu ) case 0x76: // { "ROR", AM_ZPX }, // 76 KREAD_ZPX; DO_ROR(v); - cpu->write( cpu, baddr, v ); + cpu->write(cpu, baddr, v); break; case 0x78: // { "SEI", AM_IMP }, // 78 @@ -1360,7 +1375,7 @@ SDL_bool m6502_inst( struct m6502 *cpu ) case 0x79: // { "ADC", AM_ABY }, // 79 case 0x7D: // { "ADC", AM_ABX }, // 7D - v = cpu->read( cpu, cpu->baddr ); // baddr is already calculated for this case + v = cpu->read(cpu, cpu->baddr); // baddr is already calculated for this case cpu->pc+=2; DO_ADC; break; @@ -1368,7 +1383,7 @@ SDL_bool m6502_inst( struct m6502 *cpu ) case 0x7E: // { "ROR", AM_ABX }, // 7E READ_ABX; DO_ROR(v); - cpu->write( cpu, baddr, v ); + cpu->write(cpu, baddr, v); break; case 0x81: // { "STA", AM_ZIX }, // 81 @@ -1410,7 +1425,7 @@ SDL_bool m6502_inst( struct m6502 *cpu ) break; case 0x90: // { "BCC", AM_REL }, // 90 - BRANCH( !cpu->f_c ); + BRANCH(!cpu->f_c); break; case 0x91: // { "STA", AM_ZIY }, // 91 @@ -1517,11 +1532,11 @@ SDL_bool m6502_inst( struct m6502 *cpu ) break; case 0xB0: // { "BCS", AM_REL }, // B0 - BRANCH( cpu->f_c ); + BRANCH(cpu->f_c); break; case 0xB1: // { "LDA", AM_ZIY }, // B1 - cpu->a = cpu->read( cpu, cpu->baddr ); // baddr is already calculated for this case + cpu->a = cpu->read(cpu, cpu->baddr); // baddr is already calculated for this case cpu->pc++; FLAG_ZN(cpu->a); break; @@ -1550,7 +1565,7 @@ SDL_bool m6502_inst( struct m6502 *cpu ) case 0xB9: // { "LDA", AM_ABY }, // B9 case 0xBD: // { "LDA", AM_ABX }, // BD - cpu->a = cpu->read( cpu, cpu->baddr ); // baddr is already calculated for this case + cpu->a = cpu->read(cpu, cpu->baddr); // baddr is already calculated for this case cpu->pc+=2; FLAG_ZN(cpu->a); break; @@ -1561,13 +1576,13 @@ SDL_bool m6502_inst( struct m6502 *cpu ) break; case 0xBC: // { "LDY", AM_ABX }, // BC - cpu->y = cpu->read( cpu, cpu->baddr ); // baddr is already calculated for this case + cpu->y = cpu->read(cpu, cpu->baddr); // baddr is already calculated for this case cpu->pc+=2; FLAG_ZN(cpu->y); break; case 0xBE: // { "LDX", AM_ABY }, // BE - cpu->x = cpu->read( cpu, cpu->baddr ); // baddr is already calculated for this case + cpu->x = cpu->read(cpu, cpu->baddr); // baddr is already calculated for this case cpu->pc+=2; FLAG_ZN(cpu->x); break; @@ -1598,7 +1613,7 @@ SDL_bool m6502_inst( struct m6502 *cpu ) case 0xC6: // { "DEC", AM_ZP }, // C6 KREAD_ZP; - cpu->write( cpu, baddr, --v ); + cpu->write(cpu, baddr, --v); FLAG_ZN(v); break; @@ -1632,16 +1647,16 @@ SDL_bool m6502_inst( struct m6502 *cpu ) case 0xCE: // { "DEC", AM_ABS }, // CE KREAD_ABS; - cpu->write( cpu, baddr, --v ); + cpu->write(cpu, baddr, --v); FLAG_ZN(v); break; case 0xD0: // { "BNE", AM_REL }, // D0 - BRANCH( !cpu->f_z ); + BRANCH(!cpu->f_z); break; case 0xD1: // { "CMP", AM_ZIY }, // D1 - r = cpu->a-cpu->read( cpu, cpu->baddr ); // baddr is already calculated for this case + r = cpu->a-cpu->read(cpu, cpu->baddr); // baddr is already calculated for this case cpu->pc++; FLAG_SZCN(r); break; @@ -1654,7 +1669,7 @@ SDL_bool m6502_inst( struct m6502 *cpu ) case 0xD6: // { "DEC", AM_ZPX }, // D6 KREAD_ZPX; - cpu->write( cpu, baddr, --v ); + cpu->write(cpu, baddr, --v); FLAG_ZN(v); break; @@ -1664,14 +1679,14 @@ SDL_bool m6502_inst( struct m6502 *cpu ) case 0xD9: // { "CMP", AM_ABY }, // D9 case 0xDD: // { "CMP", AM_ABX }, // DD - r = cpu->a - cpu->read( cpu, cpu->baddr ); // baddr is already calculated for this case + r = cpu->a - cpu->read(cpu, cpu->baddr); // baddr is already calculated for this case cpu->pc+=2; FLAG_SZCN(r); break; case 0xDE: // { "DEC", AM_ABX }, // DE READ_ABX; - cpu->write( cpu, baddr, --v ); + cpu->write(cpu, baddr, --v); FLAG_ZN(v); break; @@ -1699,7 +1714,7 @@ SDL_bool m6502_inst( struct m6502 *cpu ) case 0xE6: // { "INC", AM_ZP }, // E6 KREAD_ZP; - cpu->write( cpu, baddr, ++v ); + cpu->write(cpu, baddr, ++v); FLAG_ZN(v); break; @@ -1712,7 +1727,7 @@ SDL_bool m6502_inst( struct m6502 *cpu ) #ifdef ILLEGALS case 0xEB: // { "SBC", AM_IMM }, // EB (illegal) #endif - READ_IMM; + READ_IMM; DO_SBC; break; @@ -1732,16 +1747,16 @@ SDL_bool m6502_inst( struct m6502 *cpu ) case 0xEE: // { "INC", AM_ABS }, // EE KREAD_ABS; - cpu->write( cpu, baddr, ++v ); + cpu->write(cpu, baddr, ++v); FLAG_ZN(v); break; case 0xF0: // { "BEQ", AM_REL }, // F0 - BRANCH( cpu->f_z ); + BRANCH(cpu->f_z); break; case 0xF1: // { "SBC", AM_ZIY }, // F1 - v = cpu->read( cpu, cpu->baddr ); // baddr is already calculated for this case + v = cpu->read(cpu, cpu->baddr); // baddr is already calculated for this case cpu->pc++; DO_SBC; break; @@ -1753,7 +1768,7 @@ SDL_bool m6502_inst( struct m6502 *cpu ) case 0xF6: // { "INC", AM_ZPX }, // F6 KREAD_ZPX; - cpu->write( cpu, baddr, ++v ); + cpu->write(cpu, baddr, ++v); FLAG_ZN(v); break; @@ -1763,18 +1778,18 @@ SDL_bool m6502_inst( struct m6502 *cpu ) case 0xF9: // { "SBC", AM_ABY }, // F9 case 0xFD: // { "SBC", AM_ABX }, // FD - v = cpu->read( cpu, cpu->baddr ); // baddr is already calculated for this case + v = cpu->read(cpu, cpu->baddr); // baddr is already calculated for this case cpu->pc+=2; DO_SBC; break; case 0xFE: // { "INC", AM_ABX }, // FE READ_ABX; - cpu->write( cpu, baddr, ++v ); + cpu->write(cpu, baddr, ++v); FLAG_ZN(v); break; - // Illegal opcodes + // Illegal opcodes #ifdef ILLEGALS case 0x0B: // { "ANC", AM_IMM }, // 0B (illegal) case 0x2B: // { "ANC", AM_IMM }, // 2B (illegal) @@ -1816,12 +1831,24 @@ SDL_bool m6502_inst( struct m6502 *cpu ) cpu->a = (cpu->a&v)>>1; cpu->f_n = (cpu->a&0x80) != 0; cpu->f_z = cpu->a != 0; - switch (cpu->a&0x60) + switch(cpu->a&0x60) { - case 0x00: cpu->f_c=0; cpu->f_v=0; break; - case 0x20: cpu->f_c=0; cpu->f_v=1; break; - case 0x60: cpu->f_c=1; cpu->f_v=0; break; - case 0x40: cpu->f_c=1; cpu->f_v=1; break; + case 0x00: + cpu->f_c=0; + cpu->f_v=0; + break; + case 0x20: + cpu->f_c=0; + cpu->f_v=1; + break; + case 0x60: + cpu->f_c=1; + cpu->f_v=0; + break; + case 0x40: + cpu->f_c=1; + cpu->f_v=1; + break; } break; @@ -1842,20 +1869,20 @@ SDL_bool m6502_inst( struct m6502 *cpu ) r = cpu->x; // Instability 1 (sometimes, the &H drops off) - if ((cpu->cycles&7)>2) // pseudorandom 5 in 8 chance of &H + if((cpu->cycles&7)>2) // pseudorandom 5 in 8 chance of &H r &= (cpu->pc>>8)+1; v = cpu->a & r; // Instability 2 (A is input and output, which leads to "bit fight", // but anywhere that X&H=1 will work) - if (((cpu->cycles>>8)&7)<2) // pseudorandom 2 in 8 chance of bit fight + if(((cpu->cycles>>8)&7)<2) // pseudorandom 2 in 8 chance of bit fight { r = (r^0xff)&cpu->a; // inverse R now has 1 for each bit that we can mess with r &= cpu->cycles; // Make some of them 0 (pseudorandomly) v |= r; } - if (cpu->calcop==0x9F) + if(cpu->calcop==0x9F) { WRITE_ABY(v); } @@ -2037,7 +2064,7 @@ SDL_bool m6502_inst( struct m6502 *cpu ) break; case 0xBB: // { "LAS", AM_ZIY }, // BB (illegal) - cpu->sp &= cpu->read( cpu, cpu->baddr ); + cpu->sp &= cpu->read(cpu, cpu->baddr); cpu->pc++; cpu->a = cpu->sp; cpu->x = cpu->sp; @@ -2066,7 +2093,7 @@ SDL_bool m6502_inst( struct m6502 *cpu ) break; case 0xBF: // { "LAX", AM_ABY }, // BF (illegal) - cpu->a = cpu->read( cpu, cpu->baddr ); // baddr is already calculated for this case + cpu->a = cpu->read(cpu, cpu->baddr); // baddr is already calculated for this case cpu->pc+=2; cpu->x = cpu->a; FLAG_ZN(cpu->a); @@ -2080,7 +2107,7 @@ SDL_bool m6502_inst( struct m6502 *cpu ) break; case 0xB3: // { "LAX", AM_ZIY }, // B3 (illegal) - cpu->a = cpu->read( cpu, cpu->baddr ); // baddr is already calculated for this case + cpu->a = cpu->read(cpu, cpu->baddr); // baddr is already calculated for this case cpu->x = cpu->a; cpu->pc++; FLAG_ZN(cpu->a); @@ -2399,7 +2426,7 @@ SDL_bool m6502_inst( struct m6502 *cpu ) v = cpu->x; // Instability (sometimes, the &H drops off) - if ((cpu->cycles&7)>2) // pseudorandom 5 in 8 chance of &H + if((cpu->cycles&7)>2) // pseudorandom 5 in 8 chance of &H v &= (baddr>>8)+1; cpu->write(cpu, baddr, v); @@ -2411,7 +2438,7 @@ SDL_bool m6502_inst( struct m6502 *cpu ) v = cpu->y; // Instability (sometimes, the &H drops off) - if ((cpu->cycles&7)>2) // pseudorandom 5 in 8 chance of &H + if((cpu->cycles&7)>2) // pseudorandom 5 in 8 chance of &H v &= (baddr>>8)+1; cpu->write(cpu, baddr, v); @@ -2424,7 +2451,7 @@ SDL_bool m6502_inst( struct m6502 *cpu ) cpu->a = cpu->x & v; // Instability - if ((cpu->cycles&7)>5) // pseudorandom 6 in 8 chance of instability + if((cpu->cycles&7)>5) // pseudorandom 6 in 8 chance of instability { r = (cpu->x^0xff); r &= cpu->cycles; diff --git a/6502.h b/6502.h index 582c5619..dcc79656 100644 --- a/6502.h +++ b/6502.h @@ -58,12 +58,14 @@ #define MBPF_RESETCYCLES (1<f_n<<7)|(cpu->f_v<<6)|(1<<5)|(cpu->f_b<<4)|(cpu->f_d<<3)|(cpu->f_i<<2)|(cpu->f_z<<1)|cpu->f_c) #define MAKEFLAGSBC ((cpu->f_n<<7)|(cpu->f_v<<6)|(1<<5)|(cpu->f_d<<3)|(cpu->f_i<<2)|(cpu->f_z<<1)|cpu->f_c) -// Set the seperate flag stores from a 6502-format mask +// Set the separate flag stores from a 6502-format mask #define SETFLAGS(n) cpu->f_n=(n&0x80)>>7;\ cpu->f_v=(n&0x40)>>6;\ cpu->f_b=(n&0x10)>>4;\ @@ -92,15 +94,15 @@ struct m6502 Sint32 breakpoints[16]; Uint8 breakpoint_flags[16]; struct membreakpoint membreakpoints[16]; - void *userdata; + void* userdata; Uint8 a, x, y, sp; Uint8 f_c, f_z, f_i, f_d, f_b, f_v, f_n; Uint8 irq, nmicount, calcop; }; -void m6502_init( struct m6502 *cpu, void *userdata, SDL_bool nukebreakpoints ); -void m6502_reset( struct m6502 *cpu ); -SDL_bool m6502_inst( struct m6502 *cpu ); -SDL_bool m6502_set_icycles( struct m6502 *cpu, SDL_bool dobp, char *bpmsg ); +void m6502_init(struct m6502 *cpu, void* userdata, SDL_bool nukebreakpoints); +void m6502_reset(struct m6502 *cpu); +SDL_bool m6502_inst(struct m6502 *cpu); +SDL_bool m6502_set_icycles(struct m6502 *cpu, SDL_bool dobp, char* bpmsg); diff --git a/6551.c b/6551.c index 62545150..44a9ce2b 100644 --- a/6551.c +++ b/6551.c @@ -50,31 +50,40 @@ #endif #if DEBUG_ACIA -static char *writereg_names[] = { "TXDATA", "RESET", "COMMAND", "CONTROL" }; -static char *readreg_names[] = { "RXDATA", "STATUS", "COMMAND", "CONTROL" }; -static char *parity_modes[] = { "NONE", "ODD", "NONE", "EVEN", "NONE", "MARK", "NONE", "SPACE" }; -static char *txcon_modes[] = { "TXIRQ=0,RLEV=H", "TXIRQ=1,RLEV=L", "RXIRQ=0,RLEV=L", "RXIRQ=0,RLEV=L,TXBRK" }; -static char *baud_rates[] = { "EXT", "50", "75", "109.92", "134.58", "150", "300", "600", "1200", "1800", "2400", "3600", "4800", "7200", "9600", "19200" }; -static char *bit_nums[] = { "8", "7", "6", "5" }; +static char* writereg_names[] = { "TXDATA", "RESET", "COMMAND", "CONTROL" }; +static char* readreg_names[] = { "RXDATA", "STATUS", "COMMAND", "CONTROL" }; +static char* parity_modes[] = { "NONE", "ODD", "NONE", "EVEN", "NONE", "MARK", "NONE", "SPACE" }; +static char* txcon_modes[] = { "TXIRQ=0,RLEV=H", "TXIRQ=1,RLEV=L", "RXIRQ=0,RLEV=L", "RXIRQ=0,RLEV=L,TXBRK" }; +static char* baud_rates[] = { "EXT", "50", "75", "109.92", "134.58", "150", "300", "600", "1200", "1800", "2400", "3600", "4800", "7200", "9600", "19200" }; +static char* bit_nums[] = { "8", "7", "6", "5" }; #endif // NOTE: work with integers 109.92 and 134.58 are approximated static Uint32 boudrates[] = { 0, 50, 75, 110, 134, 150, 300, 600, 1200, 1800, 2400, 3600, 4800, 7200, 9600, 19200 }; -static void acia_update_params( struct acia *acia ) +static void acia_update_params(struct acia *acia) { switch(8 - ((acia->regs[ACIA_CONTROL]&ACONF_WLEN)>>5)) { - case 5: acia->bitmask = 0x1f; break; - case 6: acia->bitmask = 0x3f; break; - case 7: acia->bitmask = 0x7f; break; - case 8: default: acia->bitmask = 0xff; break; + case 5: + acia->bitmask = 0x1f; + break; + case 6: + acia->bitmask = 0x3f; + break; + case 7: + acia->bitmask = 0x7f; + break; + case 8: + default: + acia->bitmask = 0xff; + break; } acia->rx = (acia->regs[ACIA_COMMAND] & ACOMF_DTR)? SDL_TRUE : SDL_FALSE; - acia->irqrx = (acia->rx && 0 == ( acia->regs[ACIA_COMMAND] & ACOMF_IRQDIS ))? SDL_TRUE : SDL_FALSE; + acia->irqrx = (acia->rx && 0 == (acia->regs[ACIA_COMMAND] & ACOMF_IRQDIS))? SDL_TRUE : SDL_FALSE; - switch( ( acia->regs[ACIA_COMMAND] & ACOMF_TXCON ) >> 2 ) + switch((acia->regs[ACIA_COMMAND] & ACOMF_TXCON) >> 2) { case 0: acia->tx = SDL_FALSE; @@ -109,15 +118,15 @@ static void acia_update_params( struct acia *acia ) // 1.8432 MHz / 16 (internal divider) = 115,2 kHz // 115,2 kHz => ~ 8.68 usec if(0 < acia->boudrate) - acia->framecycle = ( 115200 * 8680 ) / ( acia->boudrate * 1000 ); + acia->framecycle = (115200 * 8680) / (acia->boudrate * 1000); else acia->framecycle = 0; } -void acia_init( struct acia *acia, struct machine *oric ) +void acia_init(struct acia *acia, struct machine *oric) { - if( acia->done ) - acia->done( acia ); + if(acia->done) + acia->done(acia); acia->oric = oric; acia->regs[ACIA_RXDATA] = 0; @@ -127,60 +136,60 @@ void acia_init( struct acia *acia, struct machine *oric ) acia->regs[ACIA_CONTROL] = 0; acia->cycles = 0; - acia_update_params( acia ); + acia_update_params(acia); switch(oric->aciabackend) { case ACIA_TYPE_LOOPBACK: - acia_init_loopback( acia ); + acia_init_loopback(acia); break; #ifdef BACKEND_MODEM case ACIA_TYPE_MODEM: - acia_init_modem( acia ); + acia_init_modem(acia); break; #endif #ifdef BACKEND_COM case ACIA_TYPE_COM: - acia_init_com( acia ); + acia_init_com(acia); break; #endif case ACIA_TYPE_NONE: default: - if ( oric->type == MACH_TELESTRAT ) + if(oric->type == MACH_TELESTRAT) { oric->aciabackend = ACIA_TYPE_LOOPBACK; - acia_init_loopback( acia ); + acia_init_loopback(acia); } else - acia_init_none( acia ); + acia_init_none(acia); break; } } -void acia_clock( struct acia *acia, unsigned int cycles ) +void acia_clock(struct acia *acia, unsigned int cycles) { // EXT clock used - not implemented - if( 0 == ( acia->regs[ACIA_CONTROL] & ACONF_SRC )) + if(0 == (acia->regs[ACIA_CONTROL] & ACONF_SRC)) return; // INT clock - if( 0 == acia->framecycle ) + if(0 == acia->framecycle) return; acia->cycles += cycles; - while( acia->framecycle <= acia->cycles ) + while(acia->framecycle <= acia->cycles) { acia->cycles -= acia->framecycle; // TX enabled - if( acia->tx && 0 == (acia->regs[ACIA_STATUS] & ASTF_TXEMPTY) ) + if(acia->tx && 0 == (acia->regs[ACIA_STATUS] & ASTF_TXEMPTY)) { - if(!acia->put_byte( acia->regs[ACIA_TXDATA] ) ) + if(!acia->put_byte(acia->regs[ACIA_TXDATA])) acia->regs[ACIA_STATUS] |= ASTF_OVRUNERR; else { acia->regs[ACIA_STATUS] |= ASTF_TXEMPTY; - if( acia->irqtx ) + if(acia->irqtx) { acia->regs[ACIA_STATUS] |= ASTF_IRQ; acia->oric->cpu.irq |= IRQF_ACIA; @@ -191,13 +200,13 @@ void acia_clock( struct acia *acia, unsigned int cycles ) } // RX enabled - if( acia-> rx ) + if(acia-> rx) { Uint8 data = 0; - if( acia->has_byte(&data) ) + if(acia->has_byte(&data)) { acia->regs[ACIA_STATUS] |= ASTF_RXDATA; - if( acia->irqrx ) + if(acia->irqrx) { acia->regs[ACIA_STATUS] |= ASTF_IRQ; acia->oric->cpu.irq |= IRQF_ACIA; @@ -207,18 +216,18 @@ void acia_clock( struct acia *acia, unsigned int cycles ) } // update modem lines status - if( acia->stat ) + if(acia->stat) acia->regs[ACIA_STATUS] = acia->stat(acia->regs[ACIA_STATUS]); else acia->regs[ACIA_STATUS] |= (ASTF_CARRIER|ASTF_DSR); } -void acia_write( struct acia *acia, Uint16 addr, Uint8 data ) +void acia_write(struct acia *acia, Uint16 addr, Uint8 data) { #if DEBUG_ACIA - dbg_printf( "ACIA write: (%04X) %02X to %s", acia->oric->cpu.pc-1, data, writereg_names[addr&3] ); + dbg_printf("ACIA write: (%04X) %02X to %s", acia->oric->cpu.pc-1, data, writereg_names[addr&3]); #endif - switch( addr & 3 ) + switch(addr & 3) { case ACIA_RXDATA: // Data for TX acia->regs[ACIA_TXDATA] = data & acia->bitmask; @@ -229,47 +238,47 @@ void acia_write( struct acia *acia, Uint16 addr, Uint8 data ) acia->regs[ACIA_COMMAND] &= ACOMF_PARITY; acia->regs[ACIA_COMMAND] |= ACOMF_IRQDIS; acia->regs[ACIA_STATUS] &= ~(ASTF_OVRUNERR); - acia_update_params( acia ); + acia_update_params(acia); break; case ACIA_COMMAND: acia->regs[ACIA_COMMAND] = data; - acia_update_params( acia ); + acia_update_params(acia); #if DEBUG_ACIA - dbg_printf( " Parity = %s", parity_modes[data>>5] ); - dbg_printf( " RX Mode = %s", (data&ACOMF_ECHO) ? "ECHO" : "NORMAL" ); - dbg_printf( " TXCon = %s", txcon_modes[(data&ACOMF_TXCON)>>2] ); - dbg_printf( " IRQ = %s", (data&ACOMF_IRQDIS) ? "OFF" : "ON" ); - dbg_printf( " DTR = %s", (data&ACOMF_DTR) ? "ON" : "OFF" ); + dbg_printf(" Parity = %s", parity_modes[data>>5]); + dbg_printf(" RX Mode = %s", (data&ACOMF_ECHO) ? "ECHO" : "NORMAL"); + dbg_printf(" TXCon = %s", txcon_modes[(data&ACOMF_TXCON)>>2]); + dbg_printf(" IRQ = %s", (data&ACOMF_IRQDIS) ? "OFF" : "ON"); + dbg_printf(" DTR = %s", (data&ACOMF_DTR) ? "ON" : "OFF"); #endif break; case ACIA_CONTROL: acia->regs[ACIA_CONTROL] = data; - acia_update_params( acia ); + acia_update_params(acia); #if DEBUG_ACIA - dbg_printf( " Baud = %s", baud_rates[data&ACONF_BAUD] ); - dbg_printf( " RXClock = %s", (data&ACONF_SRC) ? "INT" : "EXT" ); - dbg_printf( " Bits = %s", bit_nums[(data&ACONF_WLEN)>>5] ); - dbg_printf( " Stopbits = %d", (data&ACONF_STOPB) ? 2 : 1 ); + dbg_printf(" Baud = %s", baud_rates[data&ACONF_BAUD]); + dbg_printf(" RXClock = %s", (data&ACONF_SRC) ? "INT" : "EXT"); + dbg_printf(" Bits = %s", bit_nums[(data&ACONF_WLEN)>>5]); + dbg_printf(" Stopbits = %d", (data&ACONF_STOPB) ? 2 : 1); #endif break; } } -Uint8 acia_read( struct acia *acia, Uint16 addr ) +Uint8 acia_read(struct acia *acia, Uint16 addr) { Uint8 data = acia->regs[addr&3]; - switch( addr & 3 ) + switch(addr & 3) { case ACIA_RXDATA: #if DEBUG_ACIA - dbg_printf( "ACIA read: (%04X) from %s (=%02X)", acia->oric->cpu.pc-1, readreg_names[addr&3], data ); + dbg_printf("ACIA read: (%04X) from %s (=%02X)", acia->oric->cpu.pc-1, readreg_names[addr&3], data); #endif - acia->get_byte( &data ); + acia->get_byte(&data); data &= acia->bitmask; acia->regs[ACIA_RXDATA] = data; acia->regs[ACIA_STATUS] &= ~(ASTF_PARITYERR|ASTF_FRAMEERR|ASTF_OVRUNERR); @@ -278,7 +287,7 @@ Uint8 acia_read( struct acia *acia, Uint16 addr ) case ACIA_STATUS: #if DEBUG_ACIA_STATUS - dbg_printf( "ACIA read: (%04X) from %s (=%02X)", acia->oric->cpu.pc-1, readreg_names[addr&3], data ); + dbg_printf("ACIA read: (%04X) from %s (=%02X)", acia->oric->cpu.pc-1, readreg_names[addr&3], data); #endif // clear IRQ flag acia->regs[ACIA_STATUS] &= ~(ASTF_IRQ); @@ -287,7 +296,7 @@ Uint8 acia_read( struct acia *acia, Uint16 addr ) default: #if DEBUG_ACIA - dbg_printf( "ACIA read: (%04X) from %s (=%02X)", acia->oric->cpu.pc-1, readreg_names[addr&3], data ); + dbg_printf("ACIA read: (%04X) from %s (=%02X)", acia->oric->cpu.pc-1, readreg_names[addr&3], data); #endif break; } @@ -296,7 +305,7 @@ Uint8 acia_read( struct acia *acia, Uint16 addr ) } // none - fake back-end, no api function will be called -SDL_bool acia_init_none( struct acia *acia ) +SDL_bool acia_init_none(struct acia *acia) { acia->done = NULL; acia->stat = NULL; diff --git a/6551.h b/6551.h index 67aacdf7..8bd7b814 100644 --- a/6551.h +++ b/6551.h @@ -82,8 +82,10 @@ enum #endif #ifdef __LINUX__ +#ifndef __ANDROID__ #define BACKEND_COM #endif +#endif #ifdef WIN32 #define BACKEND_COM #endif @@ -124,25 +126,25 @@ struct acia SDL_bool echo; // back-end api functions - Uint8 (*stat)(Uint8 stat); - SDL_bool (*has_byte)(Uint8* data); - SDL_bool (*get_byte)(Uint8* data); - SDL_bool (*put_byte)(Uint8 data); + Uint8(*stat)(Uint8 stat); + SDL_bool(*has_byte)(Uint8* data); + SDL_bool(*get_byte)(Uint8* data); + SDL_bool(*put_byte)(Uint8 data); void (*done)(struct acia* acia); }; -void acia_init( struct acia *acia, struct machine *oric ); -void acia_clock( struct acia *acia, unsigned int cycles ); -void acia_write( struct acia *acia, Uint16 addr, Uint8 data ); -Uint8 acia_read( struct acia *acia, Uint16 addr ); +void acia_init(struct acia *acia, struct machine *oric); +void acia_clock(struct acia *acia, unsigned int cycles); +void acia_write(struct acia *acia, Uint16 addr, Uint8 data); +Uint8 acia_read(struct acia *acia, Uint16 addr); // Back-end init functions -SDL_bool acia_init_none( struct acia* acia ); -SDL_bool acia_init_loopback( struct acia* acia ); +SDL_bool acia_init_none(struct acia* acia); +SDL_bool acia_init_loopback(struct acia* acia); #ifdef BACKEND_MODEM -SDL_bool acia_init_modem( struct acia* acia ); +SDL_bool acia_init_modem(struct acia* acia); #endif #ifdef BACKEND_COM -SDL_bool acia_init_com( struct acia* acia ); +SDL_bool acia_init_com(struct acia* acia); #endif diff --git a/6551_com.c b/6551_com.c index bd2b8d94..b88e86c4 100644 --- a/6551_com.c +++ b/6551_com.c @@ -47,10 +47,10 @@ static SDL_bool com_write(Uint8 data); static SDL_bool com_read(Uint8* data); static SDL_bool com_peek(Uint8* data); -static void com_done( struct acia* acia ) +static void com_done(struct acia* acia) { com_close(); - acia_init_none( acia ); + acia_init_none(acia); } static Uint8 com_stat(Uint8 stat) @@ -73,7 +73,7 @@ static SDL_bool com_put_byte(Uint8 data) return com_write(data); } -SDL_bool acia_init_com( struct acia* acia ) +SDL_bool acia_init_com(struct acia* acia) { oric = acia->oric; @@ -85,7 +85,7 @@ SDL_bool acia_init_com( struct acia* acia ) if(5 == sscanf(oric->aciabackendname, "com:%d,%d,%c,%d,%s", - &com_baudrate, &com_bits, &com_parity, &com_stopbits, com_name)) + &com_baudrate, &com_bits, &com_parity, &com_stopbits, com_name)) { //printf("com: %d, %d, %c, %d, %s\n", com_baudrate, com_bits, com_parity, com_stopbits, com_name); if(com_validate_param()) @@ -99,7 +99,7 @@ SDL_bool acia_init_com( struct acia* acia ) } // fall-back to none - acia_init_none( acia ); + acia_init_none(acia); return SDL_FALSE; } @@ -129,51 +129,99 @@ static SDL_bool com_validate_param(void) com_param = 0; switch(com_baudrate) { - case 50: com_param = B50; break; - case 75: com_param = B75; break; - case 110: com_param = B110; break; - case 134: com_param = B134; break; - case 150: com_param = B150; break; - case 300: com_param = B300; break; - case 600: com_param = B600; break; - case 1200: com_param = B1200; break; - case 1800: com_param = B1800; break; - case 2400: com_param = B2400; break; -// case 3600: com_param = B3600; break; - case 4800: com_param = B4800; break; -// case 7200: com_param = B7200; break; - case 9600: com_param = B9600; break; - case 19200: com_param = B19200; break; - case 38400: com_param = B38400; break; - case 57600: com_param = B57600; break; - case 115200: com_param = B115200; break; + case 50: + com_param = B50; + break; + case 75: + com_param = B75; + break; + case 110: + com_param = B110; + break; + case 134: + com_param = B134; + break; + case 150: + com_param = B150; + break; + case 300: + com_param = B300; + break; + case 600: + com_param = B600; + break; + case 1200: + com_param = B1200; + break; + case 1800: + com_param = B1800; + break; + case 2400: + com_param = B2400; + break; + // case 3600: com_param = B3600; break; + case 4800: + com_param = B4800; + break; + // case 7200: com_param = B7200; break; + case 9600: + com_param = B9600; + break; + case 19200: + com_param = B19200; + break; + case 38400: + com_param = B38400; + break; + case 57600: + com_param = B57600; + break; + case 115200: + com_param = B115200; + break; default: return SDL_FALSE; } switch(com_bits) { - case 5: com_param |= CS5; break; - case 6: com_param |= CS6; break; - case 7: com_param |= CS7; break; - case 8: com_param |= CS8; break; + case 5: + com_param |= CS5; + break; + case 6: + com_param |= CS6; + break; + case 7: + com_param |= CS7; + break; + case 8: + com_param |= CS8; + break; default: return SDL_FALSE; } switch(tolower(com_parity)) { - case 'n': /* */ break; - case 'o': com_param |= PARENB|PARODD; break; - case 'e': com_param |= PARENB; break; + case 'n': /* */ + break; + case 'o': + com_param |= PARENB|PARODD; + break; + case 'e': + com_param |= PARENB; + break; default: return SDL_FALSE; } switch(com_stopbits) { - case 2: com_param |= CSTOPB; break; - case 1: /* */ break; + case 2: + com_param |= CSTOPB; + break; + case 1: /* */ + break; default: return SDL_FALSE; } @@ -189,7 +237,7 @@ static SDL_bool com_open(void) com_fifo = 0; com_fd = open(com_name, O_RDWR | O_NOCTTY | O_NDELAY); - if( -1 == com_fd ) + if(-1 == com_fd) { //printf("open failed\n"); return SDL_FALSE; @@ -206,17 +254,17 @@ static SDL_bool com_open(void) static SDL_bool com_close(void) { - if( -1 != com_fd ) - close( com_fd ); + if(-1 != com_fd) + close(com_fd); com_fd = -1; return SDL_TRUE; } static SDL_bool com_write(Uint8 data) { - if( -1 != com_fd ) + if(-1 != com_fd) { - if( 0 < write(com_fd, &data, 1) ) + if(0 < write(com_fd, &data, 1)) return SDL_TRUE; } return SDL_FALSE; @@ -224,13 +272,13 @@ static SDL_bool com_write(Uint8 data) static void com_fill_fifo(void) { - if( com_fifo < COM_FIFO_SIZE ) + if(com_fifo < COM_FIFO_SIZE) { int len = 0; - if( -1 != ioctl(com_fd, FIONREAD, &len) ) + if(-1 != ioctl(com_fd, FIONREAD, &len)) { len = min(len, COM_FIFO_SIZE - com_fifo); - len = (int)read( com_fd, com_fifo_buf + com_fifo, len); + len = (int)read(com_fd, com_fifo_buf + com_fifo, len); com_fifo += len; } } @@ -238,11 +286,11 @@ static void com_fill_fifo(void) static SDL_bool com_read(Uint8* data) { - if( -1 != com_fd ) + if(-1 != com_fd) { com_fill_fifo(); - if( 0 < com_fifo ) + if(0 < com_fifo) { *data = com_fifo_buf[0]; memmove(com_fifo_buf, com_fifo_buf+1, --com_fifo); @@ -254,11 +302,11 @@ static SDL_bool com_read(Uint8* data) static SDL_bool com_peek(Uint8* data) { - if( -1 != com_fd ) + if(-1 != com_fd) { com_fill_fifo(); - if( 0 < com_fifo ) + if(0 < com_fifo) { *data = com_fifo_buf[0]; return SDL_TRUE; @@ -289,24 +337,46 @@ static SDL_bool com_validate_param(void) memset(&com_dcb, 0, sizeof(com_dcb)); switch(com_baudrate) { -// case 50: com_dcb.BaudRate = CBR_50; break; -// case 75: com_dcb.BaudRate = CBR_75; break; - case 110: com_dcb.BaudRate = CBR_110; break; -// case 134: com_dcb.BaudRate = CBR_134; break; -// case 150: com_dcb.BaudRate = CBR_150; break; - case 300: com_dcb.BaudRate = CBR_300; break; - case 600: com_dcb.BaudRate = CBR_600; break; - case 1200: com_dcb.BaudRate = CBR_1200; break; -// case 1800: com_dcb.BaudRate = CBR_1800; break; - case 2400: com_dcb.BaudRate = CBR_2400; break; -// case 3600: com_dcb.BaudRate = CBR_3600; break; - case 4800: com_dcb.BaudRate = CBR_4800; break; -// case 7200: com_dcb.BaudRate = CBR_7200; break; - case 9600: com_dcb.BaudRate = CBR_9600; break; - case 19200: com_dcb.BaudRate = CBR_19200; break; - case 38400: com_dcb.BaudRate = CBR_38400; break; - case 57600: com_dcb.BaudRate = CBR_57600; break; - case 115200: com_dcb.BaudRate = CBR_115200; break; + // case 50: com_dcb.BaudRate = CBR_50; break; + // case 75: com_dcb.BaudRate = CBR_75; break; + case 110: + com_dcb.BaudRate = CBR_110; + break; + // case 134: com_dcb.BaudRate = CBR_134; break; + // case 150: com_dcb.BaudRate = CBR_150; break; + case 300: + com_dcb.BaudRate = CBR_300; + break; + case 600: + com_dcb.BaudRate = CBR_600; + break; + case 1200: + com_dcb.BaudRate = CBR_1200; + break; + // case 1800: com_dcb.BaudRate = CBR_1800; break; + case 2400: + com_dcb.BaudRate = CBR_2400; + break; + // case 3600: com_dcb.BaudRate = CBR_3600; break; + case 4800: + com_dcb.BaudRate = CBR_4800; + break; + // case 7200: com_dcb.BaudRate = CBR_7200; break; + case 9600: + com_dcb.BaudRate = CBR_9600; + break; + case 19200: + com_dcb.BaudRate = CBR_19200; + break; + case 38400: + com_dcb.BaudRate = CBR_38400; + break; + case 57600: + com_dcb.BaudRate = CBR_57600; + break; + case 115200: + com_dcb.BaudRate = CBR_115200; + break; default: return SDL_FALSE; } @@ -316,24 +386,39 @@ static SDL_bool com_validate_param(void) case 5: case 6: case 7: - case 8: com_dcb.ByteSize = com_bits; break; + case 8: + com_dcb.ByteSize = com_bits; + break; default: return SDL_FALSE; } switch(tolower(com_parity)) { - case 'n': com_dcb.fParity = 0; com_dcb.Parity = 0; break; - case 'o': com_dcb.fParity = 1; com_dcb.Parity = 1; break; - case 'e': com_dcb.fParity = 1; com_dcb.Parity = 2; break; + case 'n': + com_dcb.fParity = 0; + com_dcb.Parity = 0; + break; + case 'o': + com_dcb.fParity = 1; + com_dcb.Parity = 1; + break; + case 'e': + com_dcb.fParity = 1; + com_dcb.Parity = 2; + break; default: return SDL_FALSE; } switch(com_stopbits) { - case 2: com_dcb.StopBits = 2; break; - case 1: com_dcb.StopBits = 0; break; + case 2: + com_dcb.StopBits = 2; + break; + case 1: + com_dcb.StopBits = 0; + break; default: return SDL_FALSE; } @@ -347,10 +432,10 @@ static SDL_bool com_open(void) COMMTIMEOUTS com_timeouts; com_fd = CreateFile(com_name, GENERIC_READ|GENERIC_WRITE, 0,0, OPEN_EXISTING, 0,0); - if ( INVALID_HANDLE_VALUE == com_fd ) + if(INVALID_HANDLE_VALUE == com_fd) return SDL_FALSE; - if (!GetCommState(com_fd, &dcb) ) + if(!GetCommState(com_fd, &dcb)) { com_close(); return SDL_FALSE; @@ -369,7 +454,7 @@ static SDL_bool com_open(void) memmove(&com_dcb, &dcb, sizeof(com_dcb)); - if (!SetCommState(com_fd, &com_dcb) ) + if(!SetCommState(com_fd, &com_dcb)) { com_close(); return SDL_FALSE; @@ -380,25 +465,25 @@ static SDL_bool com_open(void) com_timeouts.ReadTotalTimeoutMultiplier=0; com_timeouts.WriteTotalTimeoutConstant=0; com_timeouts.WriteTotalTimeoutMultiplier=0; - SetCommTimeouts( com_fd, &com_timeouts ); + SetCommTimeouts(com_fd, &com_timeouts); return SDL_TRUE; } static SDL_bool com_close(void) { - if ( INVALID_HANDLE_VALUE != com_fd ) - CloseHandle( com_fd ); + if(INVALID_HANDLE_VALUE != com_fd) + CloseHandle(com_fd); com_fd = INVALID_HANDLE_VALUE; return SDL_TRUE; } static SDL_bool com_write(Uint8 data) { - if( INVALID_HANDLE_VALUE != com_fd ) + if(INVALID_HANDLE_VALUE != com_fd) { DWORD len = 0; - if( 0 < WriteFile( com_fd, &data, 1, &len, NULL) ) + if(0 < WriteFile(com_fd, &data, 1, &len, NULL)) return SDL_TRUE; } return SDL_FALSE; @@ -406,15 +491,15 @@ static SDL_bool com_write(Uint8 data) static void com_fill_fifo(void) { - if( com_fifo < COM_FIFO_SIZE ) + if(com_fifo < COM_FIFO_SIZE) { DWORD err; COMSTAT com_st; - ClearCommError( com_fd, &err, &com_st ); - if( 0 < (int) com_st.cbInQue ) + ClearCommError(com_fd, &err, &com_st); + if(0 < (int) com_st.cbInQue) { - DWORD len = min( com_st.cbInQue, COM_FIFO_SIZE - com_fifo ); - if( 0 < ReadFile( com_fd, com_fifo_buf + com_fifo, len, &len, NULL) ) + DWORD len = min(com_st.cbInQue, COM_FIFO_SIZE - com_fifo); + if(0 < ReadFile(com_fd, com_fifo_buf + com_fifo, len, &len, NULL)) { com_fifo += len; } @@ -424,11 +509,11 @@ static void com_fill_fifo(void) static SDL_bool com_read(Uint8* data) { - if( INVALID_HANDLE_VALUE != com_fd ) + if(INVALID_HANDLE_VALUE != com_fd) { com_fill_fifo(); - if( 0 < com_fifo ) + if(0 < com_fifo) { *data = com_fifo_buf[0]; memmove(com_fifo_buf, com_fifo_buf+1, com_fifo-1); @@ -441,11 +526,11 @@ static SDL_bool com_read(Uint8* data) static SDL_bool com_peek(Uint8* data) { - if( INVALID_HANDLE_VALUE != com_fd ) + if(INVALID_HANDLE_VALUE != com_fd) { com_fill_fifo(); - if( 0 < com_fifo ) + if(0 < com_fifo) { *data = com_fifo_buf[0]; return SDL_TRUE; diff --git a/6551_loopback.c b/6551_loopback.c index 4ca15585..46a3dff0 100644 --- a/6551_loopback.c +++ b/6551_loopback.c @@ -34,9 +34,9 @@ static Uint8 loopback_buf[LOOPBACK_BUF_SIZE]; static int loopback_in = 0; static int loopback_out = 0; -static void loopback_done( struct acia* acia ) +static void loopback_done(struct acia* acia) { - acia_init_none( acia ); + acia_init_none(acia); } static Uint8 loopback_stat(Uint8 stat) @@ -87,7 +87,7 @@ static SDL_bool loopback_put_byte(Uint8 data) return SDL_TRUE; } -SDL_bool acia_init_loopback( struct acia* acia ) +SDL_bool acia_init_loopback(struct acia* acia) { loopback_in = 0; loopback_out = 0; @@ -96,7 +96,7 @@ SDL_bool acia_init_loopback( struct acia* acia ) acia->has_byte = loopback_has_byte; acia->get_byte = loopback_get_byte; acia->put_byte = loopback_put_byte; - + acia->oric->aciabackend = ACIA_TYPE_LOOPBACK; return SDL_TRUE; } diff --git a/6551_modem.c b/6551_modem.c index fba4ea93..d8cb66bf 100644 --- a/6551_modem.c +++ b/6551_modem.c @@ -52,10 +52,12 @@ static Uint8 mdm_cmd_buf[CMD_BUF_SIZE]; // happen if you ran Oricutron for ~50 days solid static Uint32 mdm_time_buf[CMD_BUF_SIZE]; -#define DATA_BUF_SIZE 4096 -static int mdm_in = 0; +// FIXME: BUG: drops byte(s)... kind of buffer overflow ??? +#define DATA_BUF_SIZE 0x10000 + +static unsigned int mdm_in = 0; static Uint8 mdm_in_buf[DATA_BUF_SIZE]; -static int mdm_out = 0; +static unsigned int mdm_out = 0; static Uint8 mdm_out_buf[DATA_BUF_SIZE]; static SDL_bool connected = SDL_FALSE; @@ -99,7 +101,7 @@ static void send_str(const char* s) if(mdm_out == DATA_BUF_SIZE) { memmove(mdm_out_buf, mdm_out_buf+1, DATA_BUF_SIZE-1); - mdm_in--; + mdm_out--; } } } @@ -134,7 +136,7 @@ static void mdm_hangup(void) static void mdm_answeroff(void) { - if( listening ) + if(listening) { listening = SDL_FALSE; socket_close(srv_sck); @@ -144,11 +146,11 @@ static void mdm_answeroff(void) static void mdm_answeron(void) { - if( !listening ) + if(!listening) { if(socket_create(&srv_sck, oric->aciabackendcfgdomain) && - socket_bind(srv_sck, oric->aciabackendcfgport, oric->aciabackendcfgdomain) && - socket_listen(srv_sck)) + socket_bind(srv_sck, oric->aciabackendcfgport, oric->aciabackendcfgdomain) && + socket_listen(srv_sck)) listening = SDL_TRUE; } } @@ -158,11 +160,11 @@ static void mdm_connect(const char* s) char ip[1024]; char* p = NULL; int port = 0; - + strcpy(ip, s); trim(ip); p = strrchr(ip, ':'); - + if(p) { port = atoi(p+1); @@ -170,8 +172,8 @@ static void mdm_connect(const char* s) } // default telnet port if(port == 0) port = ACIA_TYPE_MODEM_DEFAULT_PORT; - - if( socket_create(&cnt_sck, oric->aciabackendcfgdomain) ) + + if(socket_create(&cnt_sck, oric->aciabackendcfgdomain)) { if(socket_connect(cnt_sck, ip, port, oric->aciabackendcfgdomain)) { @@ -184,7 +186,7 @@ static void mdm_connect(const char* s) } else send_responce("NO DIALTINE"); - + mdm_hangup(); } @@ -192,8 +194,8 @@ static void parse_command(const char* s) { if(!s) return; - - if( escaped ) + + if(escaped) { if('\0' == s[0]) send_responce(""); @@ -225,7 +227,7 @@ static void parse_command(const char* s) else if(!strcasecmp("ATA", s)) { mdm_answeron(); - if( !listening ) + if(!listening) send_responce_error(); else send_responce("AUTOANSWER ON"); @@ -235,11 +237,11 @@ static void parse_command(const char* s) char* p = trim(strdup(s+5)); int on = atoi(p); free(p); - + if(0oric; - + mdm_in = 0; mdm_out = 0; - + mdm_in_buf[0] = 0x00; mdm_out_buf[0] = 0x00; memset(mdm_cmd_buf, 0, sizeof(Uint8)*CMD_BUF_SIZE); memset(mdm_time_buf, 0, sizeof(Uint32)*CMD_BUF_SIZE); - + acia->done = modem_done; acia->stat = modem_stat; acia->has_byte = modem_has_byte; acia->get_byte = modem_get_byte; acia->put_byte = modem_put_byte; - + srv_sck = -1; cnt_sck = -1; - + connected = SDL_FALSE; listening = SDL_FALSE; escaped = SDL_FALSE; - + if(socket_init()) { oric->aciabackend = ACIA_TYPE_MODEM; return SDL_TRUE; } - + // fall-back to none - acia_init_none( acia ); + acia_init_none(acia); return SDL_FALSE; } @@ -486,11 +488,11 @@ SDL_bool acia_init_modem( struct acia* acia ) #if defined(__MORPHOS__) struct Library *SocketBase; typedef LONG socklen_t; -char *inet_ntoa(struct in_addr n) +char* inet_ntoa(struct in_addr n) { static char a[sizeof "XXX.XXX.XXX.XXX"]; - char *p = (char *)&n; - + char* p = (char*)&n; + snprintf(a, sizeof a, "%d.%d.%d.%d", p[0]&0xff, p[1]&0xff, p[2]&0xff, p[3]&0xff); return a; } @@ -527,12 +529,12 @@ static SDL_bool socket_init(void) { #ifdef WIN32 WSADATA wsadata; - if( (WSAStartup(MAKEWORD(2,2), &wsadata) == SOCKET_ERROR) || - (WSAStartup(MAKEWORD(1,1), &wsadata) == SOCKET_ERROR) ) + if((WSAStartup(MAKEWORD(2,2), &wsadata) == SOCKET_ERROR) || + (WSAStartup(MAKEWORD(1,1), &wsadata) == SOCKET_ERROR)) return SDL_FALSE; #endif #ifdef __MORPHOS__ - if( !(SocketBase = OldOpenLibrary("bsdsocket.library")) ) + if(!(SocketBase = OldOpenLibrary("bsdsocket.library"))) return SDL_FALSE; #endif } @@ -546,7 +548,7 @@ static void socket_done(void) WSACleanup(); #endif #ifdef __MORPHOS__ - if( SocketBase ) + if(SocketBase) CloseLibrary(SocketBase); #endif } @@ -557,7 +559,7 @@ static int socket_create(int* sock, int domain) #if defined(__amigaos4__) || defined(__MORPHOS__) domain = AF_INET; #else - if (domain == 6) + if(domain == 6) domain = AF_INET6; else domain = AF_INET; @@ -565,14 +567,14 @@ static int socket_create(int* sock, int domain) *sock = socket(domain, SOCK_STREAM, 0); if(*sock == -1) return 0; - + if(setsockopt(*sock, SOL_SOCKET, SO_REUSEADDR, (const char*) &on, sizeof(on)) == -1) return 0; #ifdef __APPLE__ if(setsockopt(*sock, SOL_SOCKET, SO_REUSEPORT, (const char*) &on, sizeof(on)) == -1) return 0; #endif - + return 1; } @@ -581,58 +583,63 @@ static int socket_create(int* sock, int domain) static int socket_bind(int sock, int port, int domain) { - + #ifdef NO_GETADDRINFO struct sockaddr_in srv_addr; memset((void*)&srv_addr, 0, sizeof(srv_addr)); srv_addr.sin_family = AF_INET; srv_addr.sin_addr.s_addr = htonl(INADDR_ANY); srv_addr.sin_port = htons(port); - - if(bind(sock, (struct sockaddr*) &srv_addr, sizeof(srv_addr)) == -1) { + + if(bind(sock, (struct sockaddr*) &srv_addr, sizeof(srv_addr)) == -1) + { perror("socket_bind, bind error: "); return 0; } #else - struct addrinfo hints, *res, *ressave; + struct addrinfo hints, *res, *ressave; char service[NI_MAXSERV]; int n; - + memset(&hints, 0, sizeof(hints)); hints.ai_flags = AI_PASSIVE; - if (domain == 6) + if(domain == 6) hints.ai_family = AF_INET6; else hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; - + sprintf(service, "%d", port); - - if ( (n = getaddrinfo(NULL, service, &hints, &res)) != 0) { - printf("socket_bind, getaddrinfo error: %s", gai_strerror(n)); + + if((n = getaddrinfo(NULL, service, &hints, &res)) != 0) + { + fprintf(stderr, "socket_bind, getaddrinfo error: %s\n", gai_strerror(n)); return 0; } ressave = res; - + // loop through all the addresses that we got - do { - if (bind(sock, res->ai_addr, res->ai_addrlen) == 0) - break; /* success */ - } while ( (res = res->ai_next) != NULL); - + do + { + if(bind(sock, res->ai_addr, res->ai_addrlen) == 0) + break; /* success */ + } + while((res = res->ai_next) != NULL); + freeaddrinfo(ressave); - - if (res == NULL) { + + if(res == NULL) + { perror("socket_bind, bind error: "); return 0; } #endif - - + + #if defined(__LINUX__) || defined(__APPLE__) || defined(__amigaos4__) || defined(__MORPHOS__) fcntl(sock, F_SETFL, fcntl(sock, F_GETFL, 0) | O_NONBLOCK); #endif - + #ifdef WIN32 u_long imode = 1; ioctlsocket(sock, FIONBIO, &imode); @@ -644,7 +651,7 @@ static int socket_listen(int sock) { if(listen(sock, 1) == -1) return 0; - + return 1; } @@ -656,7 +663,7 @@ static int socket_accept(int sock, int* sck) struct sockaddr_storage cli_addr; #endif socklen_t cli_addr_len = sizeof(cli_addr); - + *sck = accept(sock, (struct sockaddr*) &cli_addr, (socklen_t*) &cli_addr_len); if(*sck == -1) return 0; @@ -665,13 +672,13 @@ static int socket_accept(int sock, int* sck) #if defined(__LINUX__) || defined(__amigaos4__) || defined(__MORPHOS__) fcntl(*sck, F_SETFL, fcntl(*sck, F_GETFL, 0) | O_NONBLOCK); #endif - + #if defined(WIN32) u_long imode = 1; ioctlsocket(*sck, FIONBIO, &imode); #endif } - + return 1; } @@ -696,11 +703,11 @@ static int socket_read(int sock, unsigned char* data, int* len) #ifdef NO_GETADDRINFO static void hostname_to_ip(const char* host, char* ip, int len) { - struct hostent *he = gethostbyname( (unsigned char*)host ); - if( NULL != he ) + struct hostent *he = gethostbyname((unsigned char*)host); + if(NULL != he) { struct in_addr **addr_list = (struct in_addr **) he->h_addr_list; - if( NULL != addr_list[0] ) + if(NULL != addr_list[0]) { strncpy(ip, inet_ntoa(*addr_list[0]), len); return; @@ -717,57 +724,62 @@ static int socket_connect(int sock, const char* host, int port, int domain) struct sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_port = htons(port); - + hostname_to_ip(host, ip, 64); addr.sin_addr.s_addr = inet_addr((unsigned char*)ip); - - if(connect(sock, (struct sockaddr*) &addr, sizeof(addr)) != 0) { + + if(connect(sock, (struct sockaddr*) &addr, sizeof(addr)) != 0) + { perror("socket_connect, connect error: "); return 0; } #else - struct addrinfo hints, *res, *ressave; + struct addrinfo hints, *res, *ressave; char service[NI_MAXSERV]; int n; - + memset(&hints, 0, sizeof(hints)); - if (domain == 6) + if(domain == 6) hints.ai_family = AF_INET6; else hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; - + sprintf(service, "%d", port); - - if ( (n = getaddrinfo(host, service, &hints, &res)) != 0) { - printf("socket_connect, getaddrinfo error: %s", gai_strerror(n)); + + if((n = getaddrinfo(host, service, &hints, &res)) != 0) + { + fprintf(stderr, "socket_connect, getaddrinfo error: %s\n", gai_strerror(n)); return 0; } ressave = res; - + // loop through all the addresses that we got - do { - if (connect(sock, res->ai_addr, res->ai_addrlen) == 0) - break; /* success */ - } while ( (res = res->ai_next) != NULL); - + do + { + if(connect(sock, res->ai_addr, res->ai_addrlen) == 0) + break; /* success */ + } + while((res = res->ai_next) != NULL); + freeaddrinfo(ressave); - - if (res == NULL) { + + if(res == NULL) + { perror("socket_bind, connect error: "); return 0; } #endif - + #if defined(__LINUX__) || defined(__APPLE__) || defined(__amigaos4__) || defined(__MORPHOS__) fcntl(sock, F_SETFL, fcntl(sock, F_GETFL, 0) | O_NONBLOCK); #endif - + #ifdef WIN32 u_long imode = 1; ioctlsocket(sock, FIONBIO, &imode); #endif - + return 1; } @@ -775,7 +787,7 @@ int socket_close(int sock) { if(_closesocket(sock) == -1) return 0; - + return 1; } diff --git a/8912.c b/8912.c index f23fad74..4e609fed 100644 --- a/8912.c +++ b/8912.c @@ -54,7 +54,7 @@ extern SDL_bool soundavailable, soundon, warpspeed; // Variables used by the queuekeys function // (only works for ROM routines) -static char *keyqueue = NULL; +static char* keyqueue = NULL; static int keysqueued = 0, kqoffs = 0; // Volume levels @@ -72,7 +72,7 @@ unsigned char eshapeC[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15, 128 unsigned char eshapeD[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15, 128+15 }; unsigned char eshapeE[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 128+0 }; -unsigned char *eshapes[] = { eshape0, // 0000 +unsigned char* eshapes[] = { eshape0, // 0000 eshape0, // 0001 eshape0, // 0010 eshape0, // 0011 @@ -87,50 +87,54 @@ unsigned char *eshapes[] = { eshape0, // 0000 eshapeC, // 1100 eshapeD, // 1101 eshapeE, // 1110 - eshape4 };//1111 + eshape4 + };//1111 static SDL_COMPAT_KEY *keytab; // Oric keymap (QWERTY) // FE FD FB F7 EF DF BF 7F -static SDL_COMPAT_KEY qwktab[] = { '7' , 'n' , '5' , 'v' , SDLK_RCTRL , '1' , 'x' , '3' , - 'j' , 't' , 'r' , 'f' , 0 , SDLK_ESCAPE, 'q' , 'd' , - 'm' , '6' , 'b' , '4' , SDLK_LCTRL , 'z' , '2' , 'c' , - 'k' , '9' , ';' , '-' , '#' , 0 , '\\' , '\'' , - SDLK_SPACE , ',' , '.' , SDLK_UP , SDLK_LSHIFT, SDLK_LEFT , SDLK_DOWN , SDLK_RIGHT , - 'u' , 'i' , 'o' , 'p' , SDLK_LALT , SDLK_BACKSPACE, ']' , '[' , - 'y' , 'h' , 'g' , 'e' , SDLK_RALT , 'a' , 's' , 'w' , - '8' , 'l' , '0' , '/' , SDLK_RSHIFT, SDLK_RETURN, '`' , SDLK_EQUALS }; +static SDL_COMPAT_KEY qwktab[] = { '7', 'n', '5', 'v', SDLK_RCTRL, '1', 'x', '3', + 'j', 't', 'r', 'f', 0, SDLK_ESCAPE, 'q', 'd', + 'm', '6', 'b', '4', SDLK_LCTRL, 'z', '2', 'c', + 'k', '9', ';', '-', '#', 0, '\\', '\'', + SDLK_SPACE, ',', '.', SDLK_UP, SDLK_LSHIFT, SDLK_LEFT, SDLK_DOWN, SDLK_RIGHT, + 'u', 'i', 'o', 'p', SDLK_LALT, SDLK_BACKSPACE, ']', '[', + 'y', 'h', 'g', 'e', SDLK_RALT, 'a', 's', 'w', + '8', 'l', '0', '/', SDLK_RSHIFT, SDLK_RETURN, '`', SDLK_EQUALS + }; // AZERTY -static SDL_COMPAT_KEY azktab[] = { '7' , 'n' , '5' , 'v' , SDLK_RCTRL , '1' , 'x' , '3' , - 'j' , 't' , 'r' , 'f' , 0 , SDLK_ESCAPE, 'a' , 'd' , - 'm' , '6' , 'b' , '4' , SDLK_LCTRL , 'w' , '2' , 'c' , - 'k' , '9' , ';' , '-' , '#' , 0 , '\\' , '\'' , - SDLK_SPACE , ',' , '.' , SDLK_UP , SDLK_LSHIFT, SDLK_LEFT , SDLK_DOWN , SDLK_RIGHT , - 'u' , 'i' , 'o' , 'p' , SDLK_LALT , SDLK_BACKSPACE, ']' , '[' , - 'y' , 'h' , 'g' , 'e' , SDLK_RALT , 'q' , 's' , 'z' , - '8' , 'l' , '0' , '/' , SDLK_RSHIFT, SDLK_RETURN, '`' , SDLK_EQUALS }; +static SDL_COMPAT_KEY azktab[] = { '7', 'n', '5', 'v', SDLK_RCTRL, '1', 'x', '3', + 'j', 't', 'r', 'f', 0, SDLK_ESCAPE, 'a', 'd', + 'm', '6', 'b', '4', SDLK_LCTRL, 'w', '2', 'c', + 'k', '9', ';', '-', '#', 0, '\\', '\'', + SDLK_SPACE, ',', '.', SDLK_UP, SDLK_LSHIFT, SDLK_LEFT, SDLK_DOWN, SDLK_RIGHT, + 'u', 'i', 'o', 'p', SDLK_LALT, SDLK_BACKSPACE, ']', '[', + 'y', 'h', 'g', 'e', SDLK_RALT, 'q', 's', 'z', + '8', 'l', '0', '/', SDLK_RSHIFT, SDLK_RETURN, '`', SDLK_EQUALS + }; // QWERTZ -static SDL_COMPAT_KEY qzktab[] = { '7' , 'n' , '5' , 'v' , SDLK_RCTRL , '1' , 'x' , '3' , - 'j' , 't' , 'r' , 'f' , 0 , SDLK_ESCAPE, 'q' , 'd' , - 'm' , '6' , 'b' , '4' , SDLK_LCTRL , 'y' , '2' , 'c' , - 'k' , '9' , ';' , '-' , '#' , 0 , '\\' , '\'' , - SDLK_SPACE , ',' , '.' , SDLK_UP , SDLK_LSHIFT, SDLK_LEFT , SDLK_DOWN , SDLK_RIGHT , - 'u' , 'i' , 'o' , 'p' , SDLK_LALT , SDLK_BACKSPACE, ']' , '[' , - 'z' , 'h' , 'g' , 'e' , SDLK_RALT , 'a' , 's' , 'w' , - '8' , 'l' , '0' , '/' , SDLK_RSHIFT, SDLK_RETURN, '`' , SDLK_EQUALS }; +static SDL_COMPAT_KEY qzktab[] = { '7', 'n', '5', 'v', SDLK_RCTRL, '1', 'x', '3', + 'j', 't', 'r', 'f', 0, SDLK_ESCAPE, 'q', 'd', + 'm', '6', 'b', '4', SDLK_LCTRL, 'y', '2', 'c', + 'k', '9', ';', '-', '#', 0, '\\', '\'', + SDLK_SPACE, ',', '.', SDLK_UP, SDLK_LSHIFT, SDLK_LEFT, SDLK_DOWN, SDLK_RIGHT, + 'u', 'i', 'o', 'p', SDLK_LALT, SDLK_BACKSPACE, ']', '[', + 'z', 'h', 'g', 'e', SDLK_RALT, 'a', 's', 'w', + '8', 'l', '0', '/', SDLK_RSHIFT, SDLK_RETURN, '`', SDLK_EQUALS + }; // Queue up some key presses. These key presses // are only detected by the standard ROM routines. -void queuekeys( char *str ) +void queuekeys(char* str) { - if( str ) + if(str) { - int len = (int)strlen( str ); - if( keyqueue ) + int len = (int)strlen(str); + if(keyqueue) { keyqueue = realloc(keyqueue, strlen(keyqueue) + len + 1); strcat(keyqueue, str); @@ -138,7 +142,7 @@ void queuekeys( char *str ) } else { - keyqueue = strdup( str ); + keyqueue = strdup(str); keysqueued = len; kqoffs = 0; } @@ -148,26 +152,26 @@ void queuekeys( char *str ) /* ** RNG for the AY noise generator */ -static Uint32 ayrand( struct ay8912 *ay ) +static Uint32 ayrand(struct ay8912 *ay) { Uint32 rbit = (ay->rndrack&1) ^ ((ay->rndrack>>2)&1); ay->rndrack = (ay->rndrack>>1)|(rbit<<16); return rbit&1; } -void ay_audioticktock( struct ay8912 *ay, Uint32 cycles ) +void ay_audioticktock(struct ay8912 *ay, Uint32 cycles) { - Sint32 i; + Sint32 t, i, sum = 0; Sint32 output; // For each clock cycle... - while( cycles > 0 ) + for(t=0; tctn) >= ay->noiseper ) + if((++ay->ctn) >= ay->noiseper) { // Noise counter expired, calculate the next noise output level - ay->currnoise ^= ayrand( ay ); + ay->currnoise ^= ayrand(ay); // Reset the noise counter ay->ctn = 0; @@ -177,11 +181,11 @@ void ay_audioticktock( struct ay8912 *ay, Uint32 cycles ) } // For each audio channel... - for( i=0; i<3; i++ ) + for(i=0; i<3; i++) { - if( !ay->toneper[i] ) + if(!ay->toneper[i]) { - if( !ay->sign[i] ) + if(!ay->sign[i]) { ay->sign[i] = 1; ay->newout |= (1<ct[i]) >= ay->toneper[i] ) + if((++ay->ct[i]) >= ay->toneper[i]) { // Square wave counter expired, reset it... ay->ct[i] = 0; @@ -204,12 +208,12 @@ void ay_audioticktock( struct ay8912 *ay, Uint32 cycles ) // If this channel is mixed with noise, and the noise changed, // then so did this channel. - if( ( ay->newnoise ) && ( !ay->noisebit[i] ) ) + if((ay->newnoise) && (!ay->noisebit[i])) ay->newout |= (1<cte) >= ay->envper ) + if((++ay->cte) >= ay->envper) { // Counter expired, so reset it ay->cte = 0; @@ -218,14 +222,14 @@ void ay_audioticktock( struct ay8912 *ay, Uint32 cycles ) ay->envpos++; // Reached the end of the envelope? - if( ay->envtab[ay->envpos]&0x80 ) + if(ay->envtab[ay->envpos]&0x80) ay->envpos = ay->envtab[ay->envpos]&0x7f; // For each channel... - for( i=0; i<3; i++ ) + for(i=0; i<3; i++) { // If the channel is using the envelope generator... - if( ay->regs[AY_CHA_AMP+i]&0x10 ) + if(ay->regs[AY_CHA_AMP+i]&0x10) { // Recalculate its output volume ay->vol[i] = voltab[ay->envtab[ay->envpos]]; @@ -236,39 +240,35 @@ void ay_audioticktock( struct ay8912 *ay, Uint32 cycles ) } } - // Done one cycle! - cycles--; - } - - if( !ay->newout ) return; - - // "Output" accumulates the audio data from all sources - output = soundsilence; - - // Loop through the channels - for( i=0; i<3; i++ ) - { - // Yep, calculate the squarewave signal... - if( ay->newout & (1<out[i] = ((ay->tonebit[i]|ay->sign[i])&(ay->noisebit[i]|ay->currnoise)) * ay->vol[i]; + // Loop through the channels + for(i=0; i<3; i++) + { + // Yep, calculate the squarewave signal... + if(ay->newout & (1<out[i] = ((ay->tonebit[i]|ay->sign[i])&(ay->noisebit[i]|ay->currnoise)) * ay->vol[i]; - // Mix in the output of this channel - output += ay->out[i]; + // Mix in the output of this channel + sum += ay->out[i]; + } + ay->newout = 0; } - ay->newout = 0; + if(!cycles) return; // avoid div by zero + + // Reduce aliasing by averaging over the cycles in the sample interval + output = soundsilence + sum/cycles; // Clamp the output - if( output > 32767 ) output = 32767; -// if( output < -32768 ) output = -32768; + if(output > 32767) output = 32767; + // if( output < -32768 ) output = -32768; ay->output = output; } -void ay_dowrite( struct ay8912 *ay, struct aywrite *aw ) +void ay_dowrite(struct ay8912 *ay, struct aywrite *aw) { Sint32 i; - switch( aw->reg ) + switch(aw->reg) { case AY_CHA_PER_L: // Channel A period case AY_CHA_PER_H: @@ -287,7 +287,7 @@ void ay_dowrite( struct ay8912 *ay, struct aywrite *aw ) ay->regs[aw->reg] = aw->val; ay->toneper[2] = (((ay->regs[AY_CHC_PER_H]&0xf)<<8)|ay->regs[AY_CHC_PER_L]) * TONETIME; break; - + case AY_STATUS: // Status ay->regs[aw->reg] = aw->val; ay->tonebit[0] = (aw->val&0x01)?1:0; @@ -315,7 +315,7 @@ void ay_dowrite( struct ay8912 *ay, struct aywrite *aw ) ay->vol[i] = voltab[aw->val&0xf]; ay->newout |= (1<regs[aw->reg] = aw->val; @@ -323,14 +323,14 @@ void ay_dowrite( struct ay8912 *ay, struct aywrite *aw ) break; case AY_ENV_CYCLE: - if( aw->val != 0xff ) + if(aw->val != 0xff) { ay->regs[aw->reg] = aw->val; ay->envtab = eshapes[aw->val&0xf]; ay->envpos = 0; - for( i=0; i<3; i++ ) + for(i=0; i<3; i++) { - if( ay->regs[AY_CHA_AMP+i]&0x10 ) + if(ay->regs[AY_CHA_AMP+i]&0x10) { ay->vol[i] = voltab[ay->envtab[ay->envpos]]; ay->newout |= (1<logged; i++) - ay_dowrite( ay, &ay->writelog[i] ); + for(i=0; ilogged; i++) + ay_dowrite(ay, &ay->writelog[i]); ay->logged = 0; } @@ -354,7 +354,7 @@ void ay_flushlog( struct ay8912 *ay ) ** This is the SDL audio callback. It is called by SDL ** when it needs a sound buffer to be filled. */ -void ay_callback( void *dummy, Sint8 *stream, int length ) +void ay_callback(void* dummy, Sint8 *stream, int length) { Uint16 *out; Sint16 fout; @@ -369,8 +369,9 @@ void ay_callback( void *dummy, Sint8 *stream, int length ) dcadjustave = 0; dcadjustmax = soundsilence; - tapenoise = ay->oric->tapenoise && ((!ay->oric->tapeturbo)||(ay->oric->rawtape)); - if( !tapenoise ) ay->tapeout = 0; + tapenoise = ay->soundloopon || (ay->oric->tapenoise && ((!ay->oric->tapeturbo)||(ay->oric->rawtape))); + + if(!tapenoise) ay->tapeout = 0; out = (Uint16 *)stream; cvt.buf = (Uint8 *)stream; @@ -378,32 +379,32 @@ void ay_callback( void *dummy, Sint8 *stream, int length ) actual_length = length/(2*sizeof(Uint16)); actual_length = (actual_length < AUDIO_BUFLEN)? actual_length : AUDIO_BUFLEN; actual_length = (actual_length < obtained.samples)? actual_length : obtained.samples; - - for( i=0,j=0; iccyc = ay->ccycle>>FPBITS; - while( ( logc < ay->logged ) && ( ay->ccyc >= ay->writelog[logc].cycle ) ) - ay_dowrite( ay, &ay->writelog[logc++] ); + while((logc < ay->logged) && (ay->ccyc >= ay->writelog[logc].cycle)) + ay_dowrite(ay, &ay->writelog[logc++]); - if( tapenoise ) + if(tapenoise) { - while( ( tlogc < ay->tlogged ) && ( ay->ccyc >= ay->tapelog[tlogc].cycle ) ) + while((tlogc < ay->tlogged) && (ay->ccyc >= ay->tapelog[tlogc].cycle)) ay->tapeout = ay->tapelog[tlogc++].val * 8192; } - if( ay->ccyc > ay->lastcyc ) + if(ay->ccyc > ay->lastcyc) { - ay_audioticktock( ay, ay->ccyc-ay->lastcyc ); + ay_audioticktock(ay, ay->ccyc-ay->lastcyc); ay->lastcyc = ay->ccyc; } fout = ay->output + ay->tapeout; out[j++] = fout; out[j++] = fout; - if( vidcap ) audiocapbuf[i] = fout; + if(vidcap) audiocapbuf[i] = fout; - if( fout > dcadjustmax ) dcadjustmax = fout; + if(fout > dcadjustmax) dcadjustmax = fout; dcadjustave += fout; ay->ccycle += cyclespersample; @@ -411,47 +412,47 @@ void ay_callback( void *dummy, Sint8 *stream, int length ) dcadjustave /= (length/4); - if( (dcadjustmax-dcadjustave) > 32767 ) + if((dcadjustmax-dcadjustave) > 32767) dcadjustave = -(32767-dcadjustmax); - if( dcadjustave ) + if(ay->oric->dcadjust && dcadjustave) { - for( i=0, j=0; ilogged > logc) + if(ay->logged > logc) { memmove(&ay->writelog[0], &ay->writelog[logc], (ay->logged-logc) * sizeof(ay->writelog[0])); ay->logged -= logc; - for (i=0; ilogged; i++) + for(i=0; ilogged; i++) ay->writelog[i].cycle -= ay->lastcyc; /* Got out of sync? */ - if (ay->logged > 150) - ay_flushlog( ay ); + if(ay->logged > 150) + ay_flushlog(ay); } else { ay->logged = 0; } - if( tapenoise ) + if(tapenoise) { - while( tlogc < ay->tlogged ) + while(tlogc < ay->tlogged) ay->tapeout = ay->tapelog[tlogc++].val * 8192; } @@ -461,7 +462,7 @@ void ay_callback( void *dummy, Sint8 *stream, int length ) ay->lastcyc = 0; ay->newlogcycle = ay->ccycle>>FPBITS; ay->do_logcycle_reset = SDL_TRUE; -// ay->logged = 0; + // ay->logged = 0; ay->tlogged = 0; } @@ -469,41 +470,43 @@ void ay_callback( void *dummy, Sint8 *stream, int length ) ** Emulate the AY for some clock cycles ** Output is cycle-exact. */ -void ay_ticktock( struct ay8912 *ay, int cycles ) +void ay_ticktock(struct ay8912 *ay, int cycles) { // Need to do queued keys? - if( ( keyqueue ) && ( keysqueued ) && (!ay->oric->cpu.irq) ) + if((keyqueue) && (keysqueued) && (!ay->oric->cpu.irq)) { - if( kqoffs >= keysqueued ) + if(kqoffs >= keysqueued) { free(keyqueue); keyqueue = NULL; keysqueued = 0; kqoffs = 0; - } else { - switch( ay->oric->type ) + } + else + { + switch(ay->oric->type) { case MACH_ATMOS: case MACH_PRAVETZ: - if( ( ay->oric->cpu.pc == 0xeb78 ) && ( ay->oric->romon ) ) + if((ay->oric->cpu.pc == 0xeb78) && (ay->oric->romon)) { ay->oric->cpu.a = keyqueue[kqoffs++]; - ay->oric->cpu.write( &ay->oric->cpu, 0x2df, 0 ); + ay->oric->cpu.write(&ay->oric->cpu, 0x2df, 0); ay->oric->cpu.f_n = 1; ay->oric->cpu.calcpc = 0xeb88; - ay->oric->cpu.calcop = ay->oric->cpu.read( &ay->oric->cpu, ay->oric->cpu.calcpc ); + ay->oric->cpu.calcop = ay->oric->cpu.read(&ay->oric->cpu, ay->oric->cpu.calcpc); } break; - + case MACH_ORIC1: case MACH_ORIC1_16K: - if( ( ay->oric->cpu.pc == 0xe905 ) && ( ay->oric->romon ) ) + if((ay->oric->cpu.pc == 0xe905) && (ay->oric->romon)) { ay->oric->cpu.a = keyqueue[kqoffs++]; - ay->oric->cpu.write( &ay->oric->cpu, 0x2df, 0 ); + ay->oric->cpu.write(&ay->oric->cpu, 0x2df, 0); ay->oric->cpu.f_n = 1; ay->oric->cpu.calcpc = 0xe915; - ay->oric->cpu.calcop = ay->oric->cpu.read( &ay->oric->cpu, ay->oric->cpu.calcpc ); + ay->oric->cpu.calcop = ay->oric->cpu.read(&ay->oric->cpu, ay->oric->cpu.calcpc); } break; } @@ -511,34 +514,34 @@ void ay_ticktock( struct ay8912 *ay, int cycles ) } // Also use the queuekey location to do the jasmin auto reset - if( ay->oric->auto_jasmin_reset ) + if(ay->oric->auto_jasmin_reset) { - if (ay->oric->drivetype == DRV_JASMIN) + if(ay->oric->drivetype == DRV_JASMIN) { - switch( ay->oric->type ) + switch(ay->oric->type) { case MACH_ATMOS: case MACH_PRAVETZ: - if( ( ay->oric->cpu.pc == 0xeb78 ) && ( ay->oric->romon ) ) + if((ay->oric->cpu.pc == 0xeb78) && (ay->oric->romon)) { - ay->oric->cpu.write( &ay->oric->cpu, 0x3fb, 1 ); // ROMDIS - setromon( ay->oric ); - m6502_reset( &ay->oric->cpu ); - m6502_set_icycles( &ay->oric->cpu, SDL_FALSE, NULL ); - via_init( &ay->oric->via, ay->oric, VIA_MAIN ); + ay->oric->cpu.write(&ay->oric->cpu, 0x3fb, 1); // ROMDIS + setromon(ay->oric); + m6502_reset(&ay->oric->cpu); + m6502_set_icycles(&ay->oric->cpu, SDL_FALSE, NULL); + via_init(&ay->oric->via, ay->oric, VIA_MAIN); ay->oric->auto_jasmin_reset = SDL_FALSE; } break; - + case MACH_ORIC1: case MACH_ORIC1_16K: - if( ( ay->oric->cpu.pc == 0xe905 ) && ( ay->oric->romon ) ) + if((ay->oric->cpu.pc == 0xe905) && (ay->oric->romon)) { - ay->oric->cpu.write( &ay->oric->cpu, 0x3fb, 1 ); // ROMDIS - setromon( ay->oric ); - m6502_reset( &ay->oric->cpu ); - m6502_set_icycles( &ay->oric->cpu, SDL_FALSE, NULL ); - via_init( &ay->oric->via, ay->oric, VIA_MAIN ); + ay->oric->cpu.write(&ay->oric->cpu, 0x3fb, 1); // ROMDIS + setromon(ay->oric); + m6502_reset(&ay->oric->cpu); + m6502_set_icycles(&ay->oric->cpu, SDL_FALSE, NULL); + via_init(&ay->oric->via, ay->oric, VIA_MAIN); ay->oric->auto_jasmin_reset = SDL_FALSE; } break; @@ -550,18 +553,20 @@ void ay_ticktock( struct ay8912 *ay, int cycles ) } } - if( ay->keybitdelay > 0 ) + if(ay->keybitdelay > 0) { - if( cycles >= ay->keybitdelay ) + if(cycles >= ay->keybitdelay) { ay->keybitdelay = 0; - ay_update_keybits( ay ); - } else { + ay_update_keybits(ay); + } + else + { ay->keybitdelay -= cycles; } } - if( ay->do_logcycle_reset ) + if(ay->do_logcycle_reset) { ay->logcycle = ay->newlogcycle; ay->do_logcycle_reset = SDL_FALSE; @@ -569,17 +574,17 @@ void ay_ticktock( struct ay8912 *ay, int cycles ) ay->logcycle += cycles; } -void ay_lockaudio( struct ay8912 *ay ) +void ay_lockaudio(struct ay8912 *ay) { - if( ay->audiolocked ) return; - if( ( ay->oric->emu_mode != EM_RUNNING ) || ( !soundon ) || ( warpspeed ) ) return; + if(ay->audiolocked) return; + if((ay->oric->emu_mode != EM_RUNNING) || (!soundon) || (warpspeed)) return; SDL_LockAudio(); ay->audiolocked = SDL_TRUE; } -void ay_unlockaudio( struct ay8912 *ay ) +void ay_unlockaudio(struct ay8912 *ay) { - if( !ay->audiolocked ) return; + if(!ay->audiolocked) return; SDL_UnlockAudio(); ay->audiolocked = SDL_FALSE; } @@ -588,27 +593,33 @@ void ay_unlockaudio( struct ay8912 *ay ) ** Initialise the AY emulation ** (... and oric keyboard) */ -SDL_bool ay_init( struct ay8912 *ay, struct machine *oric ) +SDL_bool ay_init(struct ay8912 *ay, struct machine *oric) { int i; - switch( oric->keymap ) + switch(oric->keymap) { - case KMAP_AZERTY: keytab = azktab; break; - case KMAP_QWERTZ: keytab = qzktab; break; - default: keytab = qwktab; break; + case KMAP_AZERTY: + keytab = azktab; + break; + case KMAP_QWERTZ: + keytab = qzktab; + break; + default: + keytab = qwktab; + break; } // No oric keys pressed - for( i=0; i<8; i++ ) + for(i=0; i<8; i++) ay->keystates[i] = SDL_FALSE; // Reset all regs to 0 - for( i=0; iregs[i] = 0; // Reset the three audio channels - for( i=0; i<3; i++ ) + for(i=0; i<3; i++) { ay->ct[i] = 0; // Cycle counter to zero ay->out[i] = 0; // 0v output for each channel @@ -629,6 +640,7 @@ SDL_bool ay_init( struct ay8912 *ay, struct machine *oric ) ay->creg = 0; // Current register to 0 ay->oric = oric; ay->soundon = soundavailable && soundon && (!warpspeed); + ay->soundloopon = oric->soundloopon; ay->currnoise = 0; ay->rndrack = 1; ay->logged = 0; @@ -642,8 +654,8 @@ SDL_bool ay_init( struct ay8912 *ay, struct machine *oric ) ay->tapeout = 0; ay->keybitdelay = 0; ay->audiolocked = SDL_FALSE; - if( soundavailable ) - SDL_PauseAudio( 0 ); + if(soundavailable) + SDL_PauseAudio(0); // initialize audio conversion system for SDL2 SDL_BuildAudioCVT(&cvt, AUDIO_S16SYS, 2, AUDIO_FREQ, obtained.format, obtained.channels, obtained.freq); @@ -656,91 +668,91 @@ SDL_bool ay_init( struct ay8912 *ay, struct machine *oric ) /* ** Update the VIA bits when key states change */ -void ay_update_keybits( struct ay8912 *ay ) +void ay_update_keybits(struct ay8912 *ay) { - ay->currkeyoffs = ay->oric->via.read_port_b( &ay->oric->via ) & 0x7; + ay->currkeyoffs = ay->oric->via.read_port_b(&ay->oric->via) & 0x7; - if( (ay->eregs[AY_STATUS]&0x40) == 0 ) + if((ay->eregs[AY_STATUS]&0x40) == 0) { - ay->oric->via.write_port_b( &ay->oric->via, 0x08, 0x00 ); + ay->oric->via.write_port_b(&ay->oric->via, 0x08, 0x00); return; } - if( ay->keystates[ay->currkeyoffs] & (ay->eregs[AY_PORT_A]^0xff) ) - ay->oric->via.write_port_b( &ay->oric->via, 0x08, 0x08 ); + if(ay->keystates[ay->currkeyoffs] & (ay->eregs[AY_PORT_A]^0xff)) + ay->oric->via.write_port_b(&ay->oric->via, 0x08, 0x08); else - ay->oric->via.write_port_b( &ay->oric->via, 0x08, 0x00 ); + ay->oric->via.write_port_b(&ay->oric->via, 0x08, 0x00); } /* ** Handle a key press */ -void ay_keypress( struct ay8912 *ay, SDL_COMPAT_KEY key, SDL_bool down ) +void ay_keypress(struct ay8912 *ay, SDL_COMPAT_KEY key, SDL_bool down) { int i; // No key? - if( key == 0 ) return; + if(key == 0) return; // Does this key exist on the Oric? - for( i=0; i<64; i++ ) - if( keytab[i] == key ) break; + for(i=0; i<64; i++) + if(keytab[i] == key) break; // No... - if( i == 64 ) return; + if(i == 64) return; // Key down event, or key up event? - if( down ) + if(down) ay->keystates[i>>3] |= (1<<(i&7)); // Down, so set the corresponding bit else ay->keystates[i>>3] &= ~(1<<(i&7)); // Up, so clear it // Maybe update the VIA - if( ay->currkeyoffs == (i>>3) ) + if(ay->currkeyoffs == (i>>3)) { - if( ay->keystates[ay->currkeyoffs] & (ay->eregs[AY_PORT_A]^0xff) ) - ay->oric->via.write_port_b( &ay->oric->via, 0x08, 0x08 ); + if(ay->keystates[ay->currkeyoffs] & (ay->eregs[AY_PORT_A]^0xff)) + ay->oric->via.write_port_b(&ay->oric->via, 0x08, 0x08); else - ay->oric->via.write_port_b( &ay->oric->via, 0x08, 0x00 ); + ay->oric->via.write_port_b(&ay->oric->via, 0x08, 0x00); } } /* ** GI addressing */ -void ay_modeset( struct ay8912 *ay ) +void ay_modeset(struct ay8912 *ay) { unsigned char v, lasts6=0; - if( (ay->bmode != AYBMF_BC1) && (ay->oric->porta_ay != 0xff) ) + if((ay->bmode != AYBMF_BC1) && (ay->oric->porta_ay != 0xff)) { ay->oric->porta_ay = 0xff; - if( ay->oric->porta_is_ay ) - ay->oric->via.write_port_a( &ay->oric->via, 0xff, 0xff ); + if(ay->oric->porta_is_ay) + ay->oric->via.write_port_a(&ay->oric->via, 0xff, 0xff); } - switch( ay->bmode ) + switch(ay->bmode) { case AYBMF_BC1: // Read AY register ay->oric->porta_ay = (ay->creg>=NUM_AY_REGS) ? 0 : ay->eregs[ay->creg]; - ay->oric->via.write_port_a( &ay->oric->via, 0xff, ay->oric->porta_ay ); + ay->oric->via.write_port_a(&ay->oric->via, 0xff, ay->oric->porta_ay); ay->oric->porta_is_ay = SDL_TRUE; break; - + case AYBMF_BDIR: // Write AY register - if( ay->creg >= NUM_AY_REGS ) break; - v = ay->oric->via.read_port_a( &ay->oric->via ); + if(ay->creg >= NUM_AY_REGS) break; + v = ay->oric->via.read_port_a(&ay->oric->via); - if( ay->creg == AY_STATUS ) + if(ay->creg == AY_STATUS) lasts6 = ay->eregs[AY_STATUS] & 0x40; - if( ( ay->creg != AY_ENV_CYCLE ) || ( v != 0xff ) ) + if((ay->creg != AY_ENV_CYCLE) || (v != 0xff)) ay->eregs[ay->creg] = v; - switch( ay->creg ) + switch(ay->creg) { case AY_STATUS: - if( (ay->eregs[AY_STATUS]&0x40) != lasts6 ) + if((ay->eregs[AY_STATUS]&0x40) != lasts6) { ay->keybitdelay = 3; } @@ -757,28 +769,28 @@ void ay_modeset( struct ay8912 *ay ) case AY_ENV_PER_L: case AY_ENV_PER_H: case AY_ENV_CYCLE: - if( ( !soundon ) || ( warpspeed ) ) + if((!soundon) || (warpspeed)) { struct aywrite writenow; - ay_flushlog( ay ); + ay_flushlog(ay); writenow.cycle = 0; writenow.reg = ay->creg; writenow.val = v; - ay_dowrite( ay, &writenow ); + ay_dowrite(ay, &writenow); break; } - ay_lockaudio( ay ); // Gets unlocked at the end of each frame + ay_lockaudio(ay); // Gets unlocked at the end of each frame - if( ay->do_logcycle_reset ) + if(ay->do_logcycle_reset) { ay->logcycle = ay->newlogcycle; ay->do_logcycle_reset = SDL_FALSE; } - if( ay->logged >= WRITELOG_SIZE ) - ay_flushlog( ay ); + if(ay->logged >= WRITELOG_SIZE) + ay_flushlog(ay); ay->writelog[ay->logged ].cycle = ay->logcycle; ay->writelog[ay->logged ].reg = ay->creg; @@ -790,34 +802,58 @@ void ay_modeset( struct ay8912 *ay ) break; } break; - + case AYBMF_BDIR|AYBMF_BC1: // Set register - ay->creg = ay->oric->via.read_port_a( &ay->oric->via ); + ay->creg = ay->oric->via.read_port_a(&ay->oric->via); break; } } -void ay_set_bcmode( struct ay8912 *ay, unsigned char bc1, unsigned char bdir ) +void ay_set_bcmode(struct ay8912 *ay, unsigned char bc1, unsigned char bdir) { ay->bmode = (bc1?AYBMF_BC1:0)|(bdir?AYBMF_BDIR:0); - ay_modeset( ay ); + ay_modeset(ay); } -void ay_set_bc1( struct ay8912 *ay, unsigned char state ) +void ay_set_bc1(struct ay8912 *ay, unsigned char state) { - if( state ) + if(state) ay->bmode |= AYBMF_BC1; else ay->bmode &= ~AYBMF_BC1; - ay_modeset( ay ); + ay_modeset(ay); } -void ay_set_bdir( struct ay8912 *ay, unsigned char state ) +void ay_set_bdir(struct ay8912 *ay, unsigned char state) { - if( state ) + if(state) ay->bmode |= AYBMF_BDIR; else ay->bmode &= ~AYBMF_BDIR; - ay_modeset( ay ); + ay_modeset(ay); } +void ay_soundloop(struct ay8912 *ay, unsigned char oldval, unsigned char newval) +{ + if(!ay->soundloopon) + return; + + oldval &= 0x80; + newval &= 0x80; + + if(oldval == newval) + return; + + ay_lockaudio(ay); + if(ay->do_logcycle_reset) + { + ay->logcycle = ay->newlogcycle; + ay->do_logcycle_reset = SDL_FALSE; + } + if(ay->tlogged < TAPELOG_SIZE) + { + ay->tapelog[ay->tlogged].cycle = ay->logcycle; + ay->tapelog[ay->tlogged++].val = newval? 1 : 0; + } + ay_unlockaudio(ay); +} diff --git a/8912.h b/8912.h index 4dddf061..1732066c 100644 --- a/8912.h +++ b/8912.h @@ -81,13 +81,13 @@ struct ay8912 Uint8 regs[NUM_AY_REGS], eregs[NUM_AY_REGS]; SDL_bool keystates[8], newnoise; SDL_bool soundon; - SDL_bool tapenoiseon; + SDL_bool soundloopon; Uint32 toneper[3], noiseper, envper; Uint16 tonebit[3], noisebit[3], vol[3], newout; Sint32 ct[3], ctn, cte; Uint32 tonepos[3], tonestep[3]; Sint32 sign[3], out[3], envpos; - unsigned char *envtab; + unsigned char* envtab; struct machine *oric; Uint32 currnoise, rndrack; Sint16 output; @@ -103,19 +103,22 @@ struct ay8912 struct tnchange tapelog[TAPELOG_SIZE]; }; -void queuekeys( char *str ); +void queuekeys(char* str); -SDL_bool ay_init( struct ay8912 *ay, struct machine *oric ); -void ay_callback( void *dummy, Sint8 *stream, int length ); -void ay_ticktock( struct ay8912 *ay, int cycles ); -void ay_update_keybits( struct ay8912 *ay ); -void ay_keypress( struct ay8912 *ay, SDL_COMPAT_KEY key, SDL_bool down ); +SDL_bool ay_init(struct ay8912 *ay, struct machine *oric); +void ay_callback(void* dummy, Sint8 *stream, int length); +void ay_ticktock(struct ay8912 *ay, int cycles); +void ay_update_keybits(struct ay8912 *ay); +void ay_keypress(struct ay8912 *ay, SDL_COMPAT_KEY key, SDL_bool down); -void ay_set_bc1( struct ay8912 *ay, unsigned char state ); -void ay_set_bdir( struct ay8912 *ay, unsigned char state ); -void ay_set_bcmode( struct ay8912 *ay, unsigned char bc1, unsigned char bdir ); -void ay_modeset( struct ay8912 *ay ); +void ay_set_bc1(struct ay8912 *ay, unsigned char state); +void ay_set_bdir(struct ay8912 *ay, unsigned char state); +void ay_set_bcmode(struct ay8912 *ay, unsigned char bc1, unsigned char bdir); +void ay_modeset(struct ay8912 *ay); + +void ay_lockaudio(struct ay8912 *ay); +void ay_unlockaudio(struct ay8912 *ay); +void ay_flushlog(struct ay8912 *ay); + +void ay_soundloop(struct ay8912 *ay, unsigned char oldval, unsigned char newval); -void ay_lockaudio( struct ay8912 *ay ); -void ay_unlockaudio( struct ay8912 *ay ); -void ay_flushlog( struct ay8912 *ay ); diff --git a/CMakeLists.txt b/CMakeLists.txt index 9e0b6592..f735eb8e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,43 +3,81 @@ set (CMAKE_C_STANDARD 99) project(Oricutron) +option(USE_SDL2 "Use SDL2 instead of SDL1" OFF) + +set(ORICUTRON_APPNAME Oricutron) +set(ORICUTRON_APPYEAR 2015) +SET(ORICUTRON_VERSION_MAJOR 1) +SET(ORICUTRON_VERSION_MINOR 2) +SET(ORICUTRON_VERSION_PATCH 0) +set(ORICUTRON_COMPANYNAME "pete-gordon/oricutron") +set(ORICUTRON_LINK "https://github.com/pete-gordon/oricutron/") +set(ORICUTRON_VERSION_NUMBER "${ORICUTRON_VERSION_MAJOR}.${ORICUTRON_VERSION_MINOR}") +set(ORICUTRON_VERSION_NUMBER_FULL "${ORICUTRON_VERSION_MAJOR}.${ORICUTRON_VERSION_MINOR}.${ORICUTRON_VERSION_PATCH}") +set(ORICUTRON_APPNAME_FULL "${ORICUTRON_APPNAME} ${ORICUTRON_VERSION_MAJOR}.${ORICUTRON_VERSION_MINOR}") +set(ORICUTRON_VERSION_COPYRIGHTS "${ORICUTRON_APPNAME} ${ORICUTRON_VERSION_MAJOR}.${ORICUTRON_VERSION_MINOR}.${ORICUTRON_VERSION_PATCH} (c)${ORICUTRON_APPYEAR} Peter Gordon (pete@gordon.plus)") + if (WIN32) set(OPENGL_LIBRARY "opengl32.lib") - add_library(SDL2 STATIC IMPORTED) - set_target_properties(SDL2 - PROPERTIES - IMPORTED_LOCATION "${PROJECT_SOURCE_DIR}/msvc/vcpkg/installed/x64-windows/lib/SDL2.lib" - INTERFACE_INCLUDE_DIRECTORIES "${PROJECT_SOURCE_DIR}/msvc/vcpkg/installed/x64-windows/include/SDL2" - ) - - add_definitions(-DSDL_MAIN_HANDLED=1 -D__OPENGL_AVAILABLE__ -D_MBCS -DWIN32 -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_WARNINGS -D__CBCOPY__ -D__CBPASTE__ -DAPP_NAME_FULL="Oricutron 1.2" -DAPP_YEAR="2015" -DVERSION_COPYRIGHTS="Oricutron 1.2.0 2016 Peter Gordon") + if (USE_SDL2) + add_library(SDL2 STATIC IMPORTED) + set_target_properties(SDL2 + PROPERTIES + IMPORTED_LOCATION "${PROJECT_SOURCE_DIR}/msvc/vcpkg/installed/x64-windows/lib/SDL2.lib" + INTERFACE_INCLUDE_DIRECTORIES "${PROJECT_SOURCE_DIR}/msvc/vcpkg/installed/x64-windows/include/SDL2" + ) + add_definitions(-DSDL_MAJOR_VERSION=2 -DSDL_MAIN_HANDLED=1 -D__OPENGL_AVAILABLE__ -D_MBCS -DWIN32 -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_WARNINGS -D__CBCOPY__ -D__CBPASTE__ -DAPP_NAME_FULL="${ORICUTRON_APPNAME_FULL}" -DAPP_YEAR="${ORICUTRON_APPYEAR}" -DVERSION_COPYRIGHTS="${ORICUTRON_VERSION_COPYRIGHTS}") + else() + add_library(SDL STATIC IMPORTED) + set_target_properties(SDL + PROPERTIES + IMPORTED_LOCATION "${PROJECT_SOURCE_DIR}/msvc/vcpkg/installed/x64-windows/lib/SDL.lib" + INTERFACE_INCLUDE_DIRECTORIES "${PROJECT_SOURCE_DIR}/msvc/vcpkg/installed/x64-windows/include/SDL" + ) + add_definitions(-DSDL_MAJOR_VERSION=1 -DSDL_MAIN_HANDLED=1 -D__OPENGL_AVAILABLE__ -D_MBCS -DWIN32 -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_WARNINGS -D__CBCOPY__ -D__CBPASTE__ -DAPP_NAME_FULL="${ORICUTRON_APPNAME_FULL}" -DAPP_YEAR="${ORICUTRON_APPYEAR}" -DVERSION_COPYRIGHTS="${ORICUTRON_VERSION_COPYRIGHTS}") + endif (USE_SDL2) endif (WIN32) if (UNIX) - # Use the package PkgConfig to detect GTK+ headers/library files - find_package(PkgConfig REQUIRED) - PKG_CHECK_MODULES(GTK3 REQUIRED gtk+-3.0) - - find_package(SDL2 REQUIRED) - # Setup CMake to use GTK+ and SDL2, tell the compiler where to look for headers - # and to the linker where to look for libraries - include_directories(${GTK3_INCLUDE_DIRS} ${SDL2_INCLUDE_DIRS}) - link_directories(${GTK3_LIBRARY_DIRS}) - - add_definitions(${GTK3_CFLAGS_OTHER} -D__SPECIFY_SDL_DIR__=1 -DAPP_NAME_FULL="Oricutron 1.2" -DAPP_YEAR="2015" -DVERSION_COPYRIGHTS="Oricutron 1.2.0 2016 Peter Gordon") + if (USE_SDL2) + find_package(SDL2 REQUIRED) + find_package(OpenGL) + # Setup CMake to use GTK+ and SDL2, tell the compiler where to look for headers + # and to the linker where to look for libraries + include_directories(${GTK3_INCLUDE_DIRS} ${SDL2_INCLUDE_DIRS}) + if (OPENGL_FOUND) + add_definitions(-D__OPENGL_AVAILABLE__) + endif(OPENGL_FOUND) + add_definitions(${GTK3_CFLAGS_OTHER} -DSDL_MAJOR_VERSION=2 -D__SPECIFY_SDL_DIR__=1 -DAPP_NAME_FULL="${ORICUTRON_APPNAME_FULL}" -DAPP_YEAR="${ORICUTRON_APPYEAR}" -DVERSION_COPYRIGHTS="${ORICUTRON_VERSION_COPYRIGHTS}") + else() + # Use the package PkgConfig to detect GTK+ headers/library files + find_package(PkgConfig REQUIRED) + PKG_CHECK_MODULES(GTK3 REQUIRED gtk+-3.0) + find_package(SDL REQUIRED) + + # Setup CMake to use GTK+ and SDL, tell the compiler where to look for headers + # and to the linker where to look for libraries + include_directories(${GTK3_INCLUDE_DIRS} ${SDL_INCLUDE_DIRS}) + link_directories(${GTK3_LIBRARY_DIRS}) + add_definitions(${GTK3_CFLAGS_OTHER} -DSDL_MAJOR_VERSION=1 -D__SPECIFY_SDL_DIR__=1 -DAPP_NAME_FULL="${ORICUTRON_APPNAME_FULL}" -DAPP_YEAR="${ORICUTRON_APPYEAR}" -DVERSION_COPYRIGHTS="${ORICUTRON_VERSION_COPYRIGHTS}") + endif (USE_SDL2) endif (UNIX) include_directories( ${CMAKE_CURRENT_BINARY_DIR} +) + if (WIN32) +include_directories( "${PROJECT_SOURCE_DIR}/msvc" -endif (WIN32) ) +endif (WIN32) SET (SRCAMIGA filereq_amiga.c + msgbox_os4.c ) SET (SRCBEOS @@ -56,9 +94,11 @@ SET (SRCGTK SET (SRCSDL filereq_sdl.c + gui_x11.c msgbox_sdl.c ) + SET (SRCSWIN filereq_win32.c gui_win.c @@ -71,8 +111,6 @@ SET (SRCS 6551_loopback.c 6551_modem.c gui.c -# msgbox_os2.c -# msgbox_os4.c render_gl.c render_null.c render_sw.c @@ -90,6 +128,7 @@ SET (SRCS main.c monitor.c plugins/ch376/oric_ch376_plugin.c + plugins/twilighte_board/oric_twilighte_board_plugin.c snapshot.c system_sdl.c tape.c @@ -97,12 +136,24 @@ SET (SRCS via.c ) +set(ORICUTRON_RC ${PROJECT_SOURCE_DIR}/msvc/Oricutron.rc) + if (WIN32) - add_executable(Oricutron ${SRCS} ${SRCSWIN}) - target_link_libraries(Oricutron SDL2 ${OPENGL_LIBRARY}) + if (USE_SDL2) + add_executable(Oricutron-sdl2 ${SRCS} ${SRCSWIN} ${ORICUTRON_RC}) + target_link_libraries(Oricutron-sdl2 SDL2 ${OPENGL_LIBRARY}) + else() + add_executable(Oricutron ${SRCS} ${SRCSWIN} ${ORICUTRON_RC}) + target_link_libraries(Oricutron SDL ${OPENGL_LIBRARY}) + endif (USE_SDL2) endif (WIN32) if (UNIX) - add_executable(Oricutron ${SRCS} ${SRCGTK}) - target_link_libraries(Oricutron ${GTK3_LIBRARIES} ${SDL2_LIBRARIES}) + if (USE_SDL2) + add_executable(Oricutron-sdl2 ${SRCS} ${SRCSDL}) + target_link_libraries(Oricutron-sdl2 ${OPENGL_LIBRARIES} ${SDL2_LIBRARIES}) + else() + add_executable(Oricutron ${SRCS} ${SRCGTK}) + target_link_libraries(Oricutron ${GTK3_LIBRARIES} SDL GL X11) + endif (USE_SDL2) endif (UNIX) diff --git a/ChangeLog.txt b/ChangeLog.txt index 6f0e66b5..0afe7226 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -3,6 +3,23 @@ Oricutron ChangeLog pre-release changes (work in progress) -------------------------------------- +* New breakpoint flag 't' to print current counter +* Added monitor memory search (#180) (@cedricp) +* Added Sound loopback (useful to simulate speech software) +* Properly #ifdef-ed key_dump routines (define DEBUG_KEY_DUMP when build) +* Added Android target platform +* Updated BD500 for DOS70 +* Added option to disable menu color scheme +* Updated BD500 support +* Fixed crash with visual keyboard on/off +* Added Byte Drive BD-500 support +* Added possibility to load more images from command line +* Fixed memory leaks and improvements in disk support +* Added monitor command 'fr' - fr - Read BIN file to mem +* Changed monitor command 'df' to 'fd' for better consistency +* Changed monitor command 'wm' to 'fw' for better consistency +* Added new 'dcadjust' option in .cfg file - toggles on/off audio DC adjustment +* Added German translation of 'ReadMe.txt' - 'ReadMe-LiesMich_DE.txt' * Fixed issue #116 no ACIA in Telestrat mode * Added read-track and write-track support for FDC (assinie) * Center windows on return from fullscreen mode (rzumer) diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 00000000..1f7c908c --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,86 @@ +GNU GENERAL PUBLIC LICENSE + +Version 2, June 1991 + +Copyright (C) 1989, 1991 Free Software Foundation, Inc. +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + +Everyone is permitted to copy and distribute verbatim copies +of this license document, but changing it is not allowed. +Preamble + +The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. + +When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. + +To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. + +For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. + +We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. + +Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. + +Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. + +The precise terms and conditions for copying, distribution and modification follow. + +TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + +0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. + +1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. + +You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. + +2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: + +a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. +b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. +c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) +These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. + +3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: + +a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, +b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, +c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) +The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. + +If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. + +4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. + +5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. + +6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. + +7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. + +This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. + +8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. + +9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. + +10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. + +NO WARRANTY + +11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +END OF TERMS AND CONDITIONS diff --git a/Makefile b/Makefile index 47ed512f..e4068355 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ -# +# # valid platforms in alphabetical order: -# +# # PLATFORM = aitouchbook # PLATFORM = aros # PLATFORM = beos @@ -10,6 +10,7 @@ # PLATFORM = lin-64 # PLATFORM = linux # PLATFORM = linux-nogl +# PLATFORM = linux-native # PLATFORM = mint # PLATFORM = mint-cf # PLATFORM = morphos @@ -32,17 +33,17 @@ VERSION_MAJ = 1 VERSION_MIN = 2 VERSION_REV = 0 VERSION_FULL = $(VERSION_MAJ).$(VERSION_MIN).$(VERSION_REV) -APP_INFO = -APP_NAME = Oricutron $(APP_INFO) +APP_INFO = +APP_NAME = $(strip Oricutron $(APP_INFO)) APP_YEAR = 2019 -COPYRIGHTS = (c)$(APP_YEAR) Peter Gordon (pete@petergordon.org.uk) +COPYRIGHTS = (c)$(APP_YEAR) Peter Gordon (pete@gordon.plus) VERSION_COPYRIGHTS = "$(APP_NAME) $(VERSION_FULL) $(COPYRIGHTS)" -#COPYRIGHTS = "$(APP_NAME) $(VERSION_FULL) ©$(APP_YEAR) Peter Gordon (pete@petergordon.org.uk)" +#COPYRIGHTS = "$(APP_NAME) $(VERSION_FULL) ©$(APP_YEAR) Peter Gordon (pete@gordon.plus)" ####### DEFAULT SETTINGS HERE ####### SRC_DIR = . -VPATH = $(SRC_DIR) $(SRC_DIR)/plugins/ch376 +VPATH = $(SRC_DIR) $(SRC_DIR)/plugins/ch376 $(SRC_DIR)/plugins/twilighte_board ### extract git/svn revision GITREVISION = $(shell git rev-parse --short HEAD || svnversion -n $(SRC_DIR)) @@ -84,7 +85,7 @@ FILEREQ_OBJ = filereq_sdl.o MSGBOX_OBJ = msgbox_sdl.o EXTRAOBJS = CUSTOMOBJS = -PKGDIR = Oricutron_$(PLATFORM)_v$(VERSION_MAJ)$(VERSION_MIN) +PKGDIR = build/Oricutron_$(PLATFORM)_v$(VERSION_MAJ)$(VERSION_MIN) DOCFILES = ReadMe.txt oricutron.cfg ChangeLog.txt ####### PLATFORM DETECTION HERE ####### @@ -150,7 +151,7 @@ LFLAGS += `$(SDL_LIB)-config --libs` -s FILEREQ_OBJ = filereq_amiga.o MSGBOX_OBJ = msgbox_os2.o AMIGA_ICONS = pngicon -EXTRAOBJS = plugins/ch376/oric_ch376_plugin.o plugins/ch376/ch376.o +EXTRAOBJS = oric_ch376_plugin.o ch376.o oric_twilighte_board_plugin.o endif # AROS @@ -240,7 +241,7 @@ TARGET_DEPS = /usr/$(CROSS_PREFIX)/sys-root/mingw/bin/SDL.dll FILEREQ_OBJ = filereq_win32.o MSGBOX_OBJ = msgbox_win32.o CUSTOMOBJS = gui_win.o winicon.o -EXTRAOBJS = oric_ch376_plugin.o ch376.o +EXTRAOBJS = oric_ch376_plugin.o ch376.o oric_twilighte_board_plugin.o endif # Windows 64bit GCC @@ -287,7 +288,7 @@ TARGET_DEPS = /usr/$(CROSS_PREFIX)/sys-root/mingw/bin/SDL.dll FILEREQ_OBJ = filereq_win32.o MSGBOX_OBJ = msgbox_win32.o CUSTOMOBJS = gui_win.o winicon.o -EXTRAOBJS = oric_ch376_plugin.o ch376.o +EXTRAOBJS = oric_ch376_plugin.o ch376.o oric_twilighte_board_plugin.o endif # BeOS / Haiku @@ -311,7 +312,7 @@ INSTALLDIR = /boot/apps/Oricutron FILEREQ_OBJ = MSGBOX_OBJ = CUSTOMOBJS = gui_beos.o msgbox_beos.o filereq_beos.o -EXTRAOBJS = plugins/ch376/oric_ch376_plugin.o plugins/ch376/ch376.o +EXTRAOBJS = plugins/ch376/oric_ch376_plugin.o plugins/twilighte_board/oric_twilighte_board_plugin.o BEOS_BERES := beres BEOS_RC := rc BEOS_XRES := xres @@ -326,19 +327,19 @@ ifeq ($(PLATFORM),osx) ifneq (,$(CROSS_CFLAGS)) CFLAGS += -D__OPENGL_AVAILABLE__ -D__CBCOPY__ -D__CBPASTE__ $(CROSS_CFLAGS) else -CFLAGS += -D__OPENGL_AVAILABLE__ -D__CBCOPY__ -D__CBPASTE__ $(shell $(SDL_LIB)-config --cflags) +CFLAGS += -D__OPENGL_AVAILABLE__ -D__CBCOPY__ -D__CBPASTE__ -DGL_SILENCE_DEPRECATION $(shell $(SDL_LIB)-config --cflags) endif ifneq (,$(CROSS_LFLAGS)) -LFLAGS += $(CROSS_LFLAGS) -s +LFLAGS += $(CROSS_LFLAGS) else -LFLAGS += $(shell $(SDL_LIB)-config --libs) -s +LFLAGS += $(shell $(SDL_LIB)-config --libs) endif -LFLAGS += -lm -Wl,-framework,OpenGL +LFLAGS += -lm -Wl,-framework,OpenGL -framework CoreFoundation -framework AppKit TARGET = $(TARGET_NAME) FILEREQ_OBJ = MSGBOX_OBJ = CUSTOMOBJS = gui_osx.o filereq_osx.o msgbox_osx.o -EXTRAOBJS = plugins/ch376/oric_ch376_plugin.o plugins/ch376/ch376.o +EXTRAOBJS = oric_ch376_plugin.o ch376.o oric_twilighte_board_plugin.o endif @@ -379,7 +380,26 @@ endif CFLAGS += -g $(shell PKG_CONFIG_PATH=/usr/$(BASELIBDIR)/pkgconfig pkg-config $(SDL_LIB) --cflags) -D__OPENGL_AVAILABLE__ -DAUDIO_BUFLEN=1024 -D__CBCOPY__ -D__CBPASTE__ LFLAGS += -lm -L/usr/$(BASELIBDIR) $(shell PKG_CONFIG_PATH=/usr/$(BASELIBDIR)/pkgconfig pkg-config $(SDL_LIB) --libs) -lGL -lX11 CUSTOMOBJS = gui_x11.o -EXTRAOBJS = oric_ch376_plugin.o ch376.o +EXTRAOBJS = oric_ch376_plugin.o ch376.o oric_twilighte_board_plugin.o +TARGET = oricutron +INSTALLDIR = /usr/local +endif + +# Linux Native +ifeq ($(PLATFORM),linux-native) +CFLAGS += +LFLAGS += +STRIP := $(CROSS_COMPILE)$(STRIP) +ifeq ($(NOGTK),) +CFLAGS += $(shell pkg-config gtk+-3.0 --cflags) +LFLAGS += $(shell pkg-config gtk+-3.0 --libs) +FILEREQ_OBJ = filereq_gtk.o +MSGBOX_OBJ = msgbox_gtk.o +endif +CFLAGS += -g $(shell pkg-config $(SDL_LIB) --cflags) -D__OPENGL_AVAILABLE__ -DAUDIO_BUFLEN=1024 -D__CBCOPY__ -D__CBPASTE__ +LFLAGS += -lm $(shell pkg-config $(SDL_LIB) --libs) -lGL -lX11 +CUSTOMOBJS = gui_x11.o +EXTRAOBJS = oric_ch376_plugin.o ch376.o oric_twilighte_board_plugin.o TARGET = oricutron INSTALLDIR = /usr/local endif @@ -399,7 +419,7 @@ endif CFLAGS += -g $(SDL_CFLAGS) -D__OPENGL_AVAILABLE__ -DAUDIO_BUFLEN=1024 -D__CBCOPY__ -D__CBPASTE__ LFLAGS += -lm -L/usr/$(BASELIBDIR) $(SDL_LFLAGS) -lGL -lX11 CUSTOMOBJS = gui_x11.o -EXTRAOBJS = oric_ch376_plugin.o ch376.o +EXTRAOBJS = oric_ch376_plugin.o ch376.o oric_twilighte_board_plugin.o TARGET = $(TARGET_NAME) INSTALLDIR = /usr/local endif @@ -419,7 +439,7 @@ endif CFLAGS += -g $(SDL_CFLAGS) -D__OPENGL_AVAILABLE__ -DAUDIO_BUFLEN=1024 -D__CBCOPY__ -D__CBPASTE__ LFLAGS += -lm -L/usr/$(BASELIBDIR) $(SDL_LFLAGS) -lGL -lX11 CUSTOMOBJS = gui_x11.o -EXTRAOBJS = oric_ch376_plugin.o ch376.o +EXTRAOBJS = oric_ch376_plugin.o ch376.o oric_twilighte_board_plugin.o TARGET = $(TARGET_NAME) INSTALLDIR = /usr/local endif @@ -440,7 +460,7 @@ STRIP := $(CROSS_COMPILE)$(STRIP) CFLAGS += -g $(shell PKG_CONFIG_PATH=/usr/$(BASELIBDIR)/pkgconfig pkg-config $(SDL_LIB) --cflags) $(shell PKG_CONFIG_PATH=/usr/$(BASELIBDIR)/pkgconfig pkg-config gtk+-3.0 --cflags) -D__CBCOPY__ -D__CBPASTE__ LFLAGS += -lm -L/usr/$(BASELIBDIR) $(shell PKG_CONFIG_PATH=/usr/$(BASELIBDIR)/pkgconfig pkg-config $(SDL_LIB) --libs) $(shell PKG_CONFIG_PATH=/usr/$(BASELIBDIR)/pkgconfig pkg-config gtk+-3.0 --libs) -lX11 CUSTOMOBJS = gui_x11.o -EXTRAOBJS = oric_ch376_plugin.o ch376.o +EXTRAOBJS = oric_ch376_plugin.o ch376.o oric_twilighte_board_plugin.o FILEREQ_OBJ = filereq_gtk.o MSGBOX_OBJ = msgbox_gtk.o TARGET = oricutron @@ -504,7 +524,7 @@ AR = $(SDK_PREFIX)-ar RANLIB = $(SDK_PREFIX)-ranlib CFLAGS += `$(SDK_HOME)/env/bin/$(SDL_LIB)-config --cflags` LFLAGS += -Wl,--stack,256k -Wl,--msuper-memory -lm `$(SDK_HOME)/env/bin/$(SDL_LIB)-config --libs` -EXTRAOBJS = oric_ch376_plugin.o ch376.o +EXTRAOBJS = oric_ch376_plugin.o ch376.o oric_twilighte_board_plugin.o endif ####### SHOULDN'T HAVE TO CHANGE THIS STUFF ####### @@ -573,12 +593,12 @@ $(OBJECTS): %.o: %.c $(CC) -c $(CFLAGS) $< -o $(notdir $@) @$(CC) -MM $(CFLAGS) $< > $(notdir $*).d -# Overide the default C rule for C++ +# Override the default C rule for C++ %.o: %.cpp $(CXX) -c $(CFLAGS) $< -o $(notdir $@) @$(CXX) -MM $(CFLAGS) $< > $(notdir $*).d -# Overide the default C rule for ObjC +# Override the default C rule for ObjC %.o: %.m $(CC) -c $(CFLAGS) $< -o $(notdir $@) @$(CC) -MM $(CFLAGS) $< > $(notdir $*).d @@ -637,7 +657,7 @@ package-beos package-haiku: install -m 644 $(DOCFILES) $(PKGDIR) zip -ry9 $(PKGDIR).zip $(PKGDIR)/ -package-osx: +package-osx: $(TARGET) mkdir -p $(PKGDIR)/Oricutron.app/Contents/MacOS mkdir -p $(PKGDIR)/Oricutron.app/Contents/Resources/images mkdir -p $(PKGDIR)/Oricutron.app/Contents/Resources/roms @@ -706,6 +726,6 @@ package-mint package-mint-cf: .PHONY: mrproper -PLATFORMS := aitouchbook aros beos gphwiz haiku lin-32 lin-64 linux linux-nogl mint mint-cf morphos os4 osx pandora rpi win32 win32-gcc win64-gcc +PLATFORMS := aitouchbook aros beos gphwiz haiku lin-32 lin-64 linux linux-nogl mint mint-cf morphos os4 osx pandora rpi win32 win32-gcc win64-gcc mrproper: @for plat in $(PLATFORMS); do $(MAKE) -f $(SRC_DIR)/Makefile clean PLATFORM=$${plat}; done diff --git a/Oricutron.guide b/Oricutron.guide index 3847bec6..a6d1fbfa 100644 --- a/Oricutron.guide +++ b/Oricutron.guide @@ -396,7 +396,7 @@ Oricutron can emulate ACIA at address #31C (standard address for Telestrat). The emulation works for Oric, Atmos, Telestrat and Pravetz and can be used together with any disk type. -The emulated ACIA communicates with the out-side world trough back-ends. +The emulated ACIA communicates with the out-side world through back-ends. Back-ends can be configured from 'oricutron.cfg' or from command line (see default 'oricutron.cfg' for usage). @@ -406,7 +406,7 @@ Back-ends are: - com - Oricutron uses any real or virtual COM port in the host machine and communicates with the hardware attached to this serial port - modem - unites ACIA with attached modem linked to internet with server and client sockets -In 'modem' mode are available folowing 'AT' commands: +In 'modem' mode are available following 'AT' commands: AT - returns 'OK' ATZ - initialize the modem AT&F - initialize the modem @@ -429,7 +429,7 @@ ROM patch files For detailed usage see included '.pch' files in roms subdirectory. -Additionaly unlimited number of binary patches can be added: +Additionally unlimited number of binary patches can be added: $XXXX:00112233445566778899AABBCCDDEEFF.... $YYYY:AA55AA55.... diff --git a/ReadMe-LiesMich_DE.txt b/ReadMe-LiesMich_DE.txt new file mode 100644 index 00000000..1bccdebf --- /dev/null +++ b/ReadMe-LiesMich_DE.txt @@ -0,0 +1,452 @@ +Oricutron 1.2 +------------- + +(c)2009-2014 Peter Gordon (pete@gordon.plus) + +This is a work in progress. + + +Aktueller status +============== + + 6502: 100% fertig (außer einigen unbekannten Fehlern :) + VIA: 95% fertig. + AY: 99% fertig. + Video: 100% fertig + Tape: 99% fertig (.TAP, .ORT und .WAV werden unterstützt) + Disk: Sektoren Lesen/Schreiben funktioniert. Lesen/Schreiben der Tracks geht nicht. + + + +Credits +======= + + Programmierung + ----------- + + Peter Gordon + + + Zusätzliche Programmierung + -------------------------- + + Francois Revol + Alexandre Devert + Stefan Haubenthal + Ibisum + Kamel Biskri + Iss + Christian from defence-force forum + + + Amiga & Windows Portierungen + ---------------------------- + + Peter Gordon + + + BeOS/Haiku Portierung + --------------------- + + Francois Revol + + + macOS Portierung + ---------------- + + Francois Revol + Kamel Biskri + Patrice Torguet + + + MorphOS & AROS Portierungen + --------------------------- + + Stefan Haubenthal + + + Linux Portierung + ---------------- + + Francois Revol + Ibisum + Alexandre Devert + + + Pandora Portierung + ------------------ + + Ibisum + + + ACIA & Pravetz Disk-Unterstützung + --------------------------------- + + Iss + + + CH376 Unterstützung + ------------------- + + Offset (cpc) & Jede + + +Danksagung +========== + +Danke an DBug und Twilighte, dass sie mich ihre Demos und Spiele mit Oricutron zusammen verteilen lassen. + +Danke an DBug, Twilighte, Chema, kamelito, Yicker, JamesD, Algarbi, ibisum, +jede, thrust26 und alle anderen für Ihre Hilfe und Ihr Feedback! + + + +AVI export notes +================ + +Der AVI Export nutzt den MRLE Codec. Vielleicht unterstützt dein Spieler der Wahl diesen nicht, aber MPlayer spielt ihn, ffmpeg konvertiert es, sodass du es direkt nach Youtube laden kannst. + +Beachte, dass der MRLE Codec bei dem Amiga OS4 Port des MPlayer ein paar Probleme mit Endian hat, sodass der Ton irgendwie schrottig rüberkommt und falsche Farben hat bis das im MPLayer behoben ist. :-( + + +Kommandozeile +============= + +Sie können bestimmte Optionen auf der Befehlszeile angeben. Alle Optionen haben +sowohl kurze als auch lange Versionen. Zum Beispiel: + + -mblah + + oder + + --machine blah + +ist dasselbe. Beachte, dass die Kurzversion kein Leerzeichen, die Lange aber schon eins hat. + +Hier sind alle Optionen: + + + -m / --machine = Lege Systemtyp fest. Diese sind: + + "atmos" oder "a" für Oric atmos + "oric1" oder "1" für Oric-1 + "o16k" für Oric-1 16k + "telestrat" oder "t" für Telestrat + "pravetz", "pravetz8d" oder "p" für Pravetz 8D + + -d / --disk = Wähle ein Disk Image zur Nutzung in Laufwerk 0 + -t / --tape = Wähle ein Tape Image + -k / --drive = Wähle einen Disk Drive Controller. Diese sind: + + "microdisc" oder "m" für Microdisc + "jasmin" oder "j" für Jasmin + "bd500" oder "b" für ByteDrive BD-500 + "pravetz" oder "p" für Pravetz-8D FDC + + -s / --symbols = Lade Symbole aus einer Datei + -f / --fullscreen = Starte Oricutron im Vollbild-Modus + -w / --window = Starte Oricutron in einem Fenster + -R / --rendermode = Rendermodus. Diese sind: + + "soft" Software rendering + "opengl" OpenGL + + -b / --debug = Start Oricutron im Debugger + -r / --breakpoint = Setze einen Breakpoint (Siehe Hinweis 2) + -h / --help = Aktiviere Kommandozeilen-Hilfe und Programm beenden + + --turbotape on|off = Aktiviere oder deaktiviere Turbotape + --lightpen on|off = Aktiviere oder deaktiviere Lichtgriffel + --vsynchack on|off = Aktiviere oder deaktiviere VSync hack + --scanlines on|off = Aktiviere oder deaktiviere Scanline Simulation + + --serial_address N = Setze die Adresse der seriellen Karte auf N (default ist $31C) + N liegt dezimal oder hexadezimal innerhalb des Bereiches $31c..$3fc + (i.e. 796, 0x31c, $31C repräsentiert den gleichen Wert) + + --serial = Set serial card back-end emulation: + 'none' - keine serielle Karte + 'loopback' - zum Testen - alle TX Daten werden an RX zurück gegeben + 'modem[:port]' - emuliert einen Com-Port mit angeschlossenem Modem, nur wenige AT Kommandos werden unterstützt und Daten werden an TCP umgeleitet. Default Port ist 23 (telnet) + + 'com:115200,8,N,1,' - nutzt reale oder virtuelle beim Host als emuliertes ACIA. + Baudrate, data bits, Parität und Stop bits können nach Bedarf verändert werden + Bsp.: Windows: 'com:115200,8,N,1,COM1' + Linux: 'com:19200,8,N,1,/dev/ttyS0' + 'com:115200,8,N,1,/dev/ttyUSB0' + +BEACHTE: Falls Sie nicht sicher sind, welchen Rechner oder welchen Laufwerkstyp ein Disk- oder Tapeimage benötigt, geben Sie den Dateinamen ohne weitere Optionen ein und Oricutron wird es selbst versuchen. + +Beachte 2: Listen mit vielen Breakpoints können von der Kommandozeile geladen werden. Nutze die standardmässigen Schalter -r oder --breakpoint, +aber anstelle einer Adresse gebe Präfixe für die Dateinamen mit ':' an. Die Datei ist eine Textdatei, die notwendige Breakpoint-Adressen enthält - eine pro Zeile, mit der selben Syntax wie am Monitor. Breakpoints können mit absoluten Adressen oder mit Symbolen (-s oder --symbols) geladen werden. + +Beispiele: + +oricutron tapes/tape_image.tap +oricutron disks/disk_image.dsk +oricutron --machine atmos --tape "tape files/foo.tap" --symbols "my files/symbols" +oricutron -m1 -tBUILD/foo.tap -sBUILD/symbols -b +oricutron --drive microdisc --disk demos/barbitoric.dsk --fullscreen +oricutron -ddemos/barbitoric.dsk -f +oricutron --turbotape off tapes/hobbit.tap +oricutron -s myproject.sym -r :myprojectbp.txt + + +Schlüssel +========= + + Im Emulator + ----------- + + F1 - Zeigt Menü + F2 - Gehe zum Debugger/Monitor + F3 - Reset (NMI) + F4 - Harter Reset + Shift+F4 - Jasmin Reset + F5 - Schalte FPS um + F6 - Toggle warp speed + F7 - Speichere alle veränderten Disks + Shift+F7 - Speichere alle veränderten Disks in neuen Disk Images + F8 - Toggle Vollbild + F9 - Speichere Kassettenausgabe + F10 - Start/Stop AVI Aufnahme + F11 - Kopiere Bildschirm in Zwischenablage (BeOS, Linux & Windows) + F12 - Einfügen (BeOS, Linux & Windows) + Help - Zeige Hilfe (Amiga, MorphOS and AROS) + AltGr - Zusätzlicher Modifizierer + + + In Menüs + -------- + + Cursors - Navigiere + Enter - Führe Befehl aus + Backspace - Gehe zurück + Escape - Verlasse Menüs + (oder benutz die Maus) + + + Im Debugger/Monitor + ------------------- + + F1 - Gehe zum Menü + F2 - Zurück zum Emulator + F3 - Wechsle zwischen Konsole/Debug Ausgabe/Speicherbeobachtung + F4 - Wechsle zwischen VIA/AY/Disk-Information + F9 - Setze Zyklus-Zählung neu + F10 - Step over code + F11 - Step over code ohne Rückverfolgung in Unterroutinen. + F12 - Überspringe Instruktion + + + In der Konsole: + --------------- + + Up/Down - Befehls-Historie + + + In memwatch: + ------------ + + Up/Down - Scrollen (+shift zum seitenweisen Scrollen) + Page Up/Page Down - Seite hoch/runter + Hex digits - Gebe Addresse ein + S - Toggle split mode + Tab - Bringe Fenster in split mode + + + +Monitor Instruktionen +===================== + +Im Monitor sind numerische Argumente standardmäßig dezimal, oder haben ein vorangestelltes $ für hex oder % für binär. Fast alles wird in hex ausgegeben. + +Fast immer, wenn eine Zahl oder Adresse eingegeben werden kann, kann auch ein CPU- oder VIA-Register genommen werden. (VIA-Register sind Vordefiniert mit V, Z.B. VDDRA). Überall wo eine Adresse angegeben werden kann, kann auch ein Syymbol verwendet werden. + +Befehle: + + ? - Hilfe + a - Assembliere + bc - Leere Breakpoint + bcm - Leere mem Breakpoint + bl - Liste Breakpoints auf + blm - List mem Breakpoints + bs [zc] - Setze Breakpoint + bsm [rwc] - Setze mem Breakpoint + bz - Zap Breakpoints + bzm - Zap mem Breakpoints + d - Disassembliere + fd - Disassembliere zu Datei + fw - Schreibe Speicher zu Datei + fr - Lese Datei zu Speicher + m - Dump memory + mm - Modifiziere Memory + mw - Beobachte Memory an addr + nl - Lade Snapshot + ns - Speichere Snapshot + r - Setze zu + q, x or qm - Beende Monitor + qe - Beende Emulator + sa - Füge user symbol hinzu oder bewege es + sk - Eliminiere user symbol + sc - Symbole nicht case-sensitive + sC - Symbole case-sensitive + sl - Lade user symbols + sx - Exportiere user symbols + sz - Zap user symbols + + + +Breakpoints +=========== + +Es gibt zwei Arten von Breakpoints. "Normale" Breakpoints werden ausgelöst, wenn die CPU +im Begriff ist, eine Anweisung an der Breakpoint-Adresse auszuführen. "Speicher" Breakpoints. +auslösen, wenn auf die Breakpoint-Adresse zugegriffen oder diese geändert wird. + +Normale Haltepunkte können 'z'- und/oder 'c'-Modifikatoren verwenden. +bs $0c00 <-- Pause, wenn die CPU im Begriff ist, Code bei $0c00 auszuführen. +bs $0c00 z <-- Pause, wenn die CPU im Begriff ist, Code bei $0c00 auszuführen + und setzen Sie den Zykluszähler auf 0 +bs $0c00 zc <-- Setzen Sie den Zykluszähler auf 0 und fahren Sie fort +bs $0c00 c <-- Setzt die Ausführung fort (d.h. deaktivierter Haltepunkt) + +Der Hauptzweck dieser Modifikatoren ist es, das Zählen der Zyklen zu erleichtern. +Wenn Symbole geladen sind, können sie anstelle von absoluten Adressen verwendet werden. + +Es gibt drei Möglichkeiten, wie ein Speicherbreakpoint ausgelöst werden kann; wenn die CPU etwa +um die Adresse (r) zu lesen, und die CPU dabei ist, die Adresse (w) zu schreiben, oder sich der Wert an der Adresse aus irgendeinem Grund ändert (c). + +Sie geben an, auf welche Weise der Breakpoint beim Setzen des Speichers ausgelöst werden soll + +Haltepunkt: + +bsm $0c00 r <-- Pause, wenn die CPU im Begriff ist, von $0c00 zu lesen +bsm $0c00 rw <-- Pause, wenn die CPU im Begriff ist, auf $0c00 zuzugreifen +bsm $0c00 c <-- Pause nach dann Inhalt von $0c00 ändern +bsm $0c00 rwc <-- Pause kurz bevor die CPU auf $0c00 zugreift, oder kurz danach + Änderungen aus irgendeinem Grund. + + +Internationale Tastaturen unter Linux und macOS +=============================================== + +Es gibt viele Probleme mit einigen internationalen Tastaturen unter Linux +und MacOS. Der beste Weg, mit ihnen fertig zu werden, ist die Installation eines UK- oder US Tastaturdefinition und zum Umschalten darauf *vor* dem Start von oricutron. + +Unter MacOS können Sie das in den "Systemeinstellungen", "Tastatur", "Eingabe Quellen". Klicken Sie auf das + und suchen Sie nach der britischen oder US-amerikanischen Tastatur. + +Unter Ubuntu können Sie dies im Menü System tun, indem Sie Präferenzen wählen und dann wählen Sie Tastatur. Wählen Sie im Dialogfeld Tastatureinstellungen die Option Layouts, und klicken Sie auf Hinzufügen. + +Eine bessere Lösung finden Sie unter "Visuelle Tastatur" hier unten. + + + +Virtuelle Tastatur +================== + +Oricutron kann eine visuelle Tastatur anzeigen, die auch eine Funktion zur Neudefinition der Tastaturbelegung enthält. + +Sie ist über ein Untermenü namens "Tastatur-Optionen" zugänglich. + +In diesem Untermenü finden Sie: + +- einen Umschalter, der die visuelle Tastatur ein-/ausblendet (Sie können auf die Tasten der Tastatur klicken, um Tastendrücke/Freigaben einzugeben) ; +- einen Umschalter, der Sie in den Modus zur Definition der Tastenbelegung bringt (Sie können dann auf eine Taste der visuellen Tastatur klicken; drücken Sie eine echte Taste auf Ihrer Tastatur und die Belegung wird funktionieren) ; +- ein Umschalter, der es erlaubt, Mod-Tasten (Strg, Umschalt, Funktion) zu klemmen (d.h. Sie klicken zuerst auf eine Taste, um sie zu drücken, und klicken dann entweder erneut darauf, um sie zu lösen, oder Sie klicken auf eine andere Taste, und es wird ein modifizierter Tastendruck erzeugt - z.B. ein Strg-T statt T - und dann die Taste automatisch loslassen) ; +- eine Option zum Speichern einer Tastaturbelegung (.kma-Datei) ; +- eine Option, um eine Tastaturbelegung zu laden; +- eine Option, die die Tastaturbelegung auf die Standard-Tastaturbelegung zurücksetzt. + +Sie können auch das Folgende in Ihrer oricutron.cfg hinzufügen, um eine Tastatur automatisch zu laden +Mapping (hier Test.kma im Keymap-Verzeichnis, das im Verzeichnis von Oricutron gefunden wurde): + +; lädt automatisch eine Tastaturbelegungsdatei +autoload_keyboard_mapping = 'keymap/Test.kma + +Mit anderen Optionen können Sie die Tastatur anzeigen lassen und automatisch sticky Mod-Tasten aktivieren: +show_keyboard = ja +sticky_mod_keys = ja + + +Emulation der seriellen Karte (ACIA) +==================================== + +Oricutron kann ACIA an der Adresse #31C (Standardadresse für Telestrat) emulieren. +Die Emulation funktioniert für Oric, Atmos, Telestrat und Pravetz und kann zusammen mit einem beliebigen Plattentyp verwendet werden. + +Die emulierte ACIA kommuniziert mit der Außenwelt über Back-Ends. +Back-Ends können in der 'oricutron.cfg' oder über die Befehlszeile konfiguriert werden. +(siehe Standard 'oricutron.cfg' für die Verwendung). + +Back-Ends sind: +- keine - deaktiviert die ACIA-Unterstützung +- Loopback - jedes gesendete Byte wird in den Empfangspuffer zurückgeschickt (zu Testzwecken) +- com - Oricutron verwendet einen beliebigen realen oder virtuellen COM-Port im Host-Rechner und kommuniziert mit der an diesen seriellen Port angeschlossenen Hardware. +- Modem - vereint ACIA mit angeschlossenem Modem, das mit dem Internet verbunden ist, mit Server- und Client-Steckdosen + +Im 'Modem'-Modus sind folgende 'AT'-Befehle verfügbar: +AT - gibt 'OK' zurück +ATZ - das Modem initialisieren +AT&F - das Modem initialisieren +ATS0=0 - automatische Anrufbeantwortung ausschalten (trennende Steckdose schließen) +ATS0=1 - automatische Anrufbeantwortung aktivieren (Öffnen Sie den Socket und beginnen Sie das Abhören auf dem ausgewählten Port (Standard ist Telnet-Port 23)) +ATA - gleich wie 'ATS0=1'. +ATS0? - liefert 'AUTOANSWER OFF' oder 'AUTOANSWER ON' je nach aktuellem Status der einzelnen Sockets +ATH0 - aktuell angeschlossene Steckdosen trennen ++++ - wenn angeschlossen, schaltet in den Befehlsmodus +ATO - kehrt vom Befehlsmodus in den Online-Modus zurück +ATD ip:port - verbindet sich als Client mit ip:port. 'ip' kann ein beliebiger Hostname (z.B.:localhost) oder die echte IP (z.B.:127.0.0.1) im LAN oder im Internet sein. ATDP und ATDT sind aus Kompatibilitätsgründen eine Alternative. + +Emulation der CH376-Karte +========================= + +Oricutron läuft mit dem Chip ch376. Dieser Chip ist in der Lage, eine sdcard und einen usbkey (und USB-Anschluss) zu lesen. Dieser Chip verarbeitet FAT32. usbdrive/ Ordner ist der CH376 Emulationsordner. Das bedeutet, dass, wenn der ch376 usbkey lesen soll, liest er in diesem Ordner. Bitte beachten Sie, dass Lesen/Schreiben emuliert wird (siehe unten für den emulierten Befehl ch376). Bitte beachten Sie zudem, dass die Emulation nur im Telestrat-Modus funktioniert. Unter Atmos läuft dieser Chip zwar, aber die ROMs wurde noch nicht freigegeben (und auch die Karte mit den ROMs noch nicht). + +Orix (http://orix.oric.org) arbeitet hauptsächlich mit diesem Chip. Bitte verändern Sie die ch376-Emulation nicht: Kontaktieren Sie Jede (jede@oric.org), weil diese Emulation auch im ACE-Emulator (cpc-Emulation) verwendet wird. Offset und ich versuchen hier, dieselbe Emulation zu nutzen. Es ist einfacher, zusammen zu arbeiten als allein. + +CH376 Befehl emuliert : +- CH376_CMD_GET_IC_VER +- CH376_CMD_CHECK_EXIST +- CH376_CMD_SET_USB_MODE +- CH376_CMD_GET_STATUS +- CH376_CMD_RD_USB_DATA0 +- CH376_CMD_WR_REQ_DATA +- CH376_CMD_SET_FILE_NAME +- CH376_CMD_DISK_MOUNT +- CH376_CMD_FILE_OPEN +- CH376_CMD_FILE_ENUM_GO +- CH376_CMD_FILE_CREATE +- CH376_CMD_FILE_ERASE (unter Linux nicht emuliert) +- CH376_CMD_DATEI_CLOSE +- CH376_CMD_BYTE_LOCATE +- CH376_CMD_BYTE_READ +- CH376_CMD_BYTE_RD_GO +- CH376_CMD_BYTE_WRITE +- CH376_CMD_BYTE_WR_GO +- CH376_CMD_DISK_QUERY +- CH376_CMD_DIR_CREATE (unter Linux nicht emuliert) +- CH376_CMD_DISK_RD_GO + +Bekannter Fehler : +Unter Windows sendet die API-Datei keine "." und "..."-Einträge, wenn der Inhalt des Ordners gelesen wird. Das ist ein Problem, weil der ch376-Chip diese Einträge sendet, wenn der Chip den Inhalt eines Verzeichnisses lesen soll. + +Wenn jemand CH376_CMD_DIR_CREATE und CH376_CMD_FILE_ERASE emulieren möchte ist das einfach zu machen: man muss nur die WIN32-Funktion kopieren, das DeleteFile ersetzen und CreateDir mit rm() und mkdir(). Aber es wird nicht gemacht, weil wir nicht in der Lage sind, es zu testen. + +CH376-Emulation hinzugefügt für : +CH376_CMD_FILE_ERASE unterdrückt eine Datei +CH376_CMD_DIR_CREATE Ordner erstellen + +ROM-Patch-Dateien +================= + +Für die detaillierte Verwendung siehe die enthaltenen '.pch'-Dateien im Unterverzeichnis roms. + +Zusätzlich kann eine unbegrenzte Anzahl von binären Patches hinzugefügt werden: + +$XXXX:00112233445566778899AABBCCDDEEFF.... +$YYYYY:AA55AA55..... +$ZZZZ:FF00FF00..... + +wobei XXXX,YYYYY,ZZZZ - hexadezimale Adressen relativ zur ROM-Startadresse sind +(d.h. um Byte bei C000 auf 00 zu setzen, verwenden Sie: $0000:00) diff --git a/ReadMe.txt b/ReadMe.txt index a24e8ecd..38a776c4 100644 --- a/ReadMe.txt +++ b/ReadMe.txt @@ -1,7 +1,7 @@ Oricutron 1.2 ------------- -(c)2009-2014 Peter Gordon (pete@petergordon.org.uk) +(c)2009-2014 Peter Gordon (pete@gordon.plus) This is a work in progress. @@ -37,6 +37,7 @@ Credits Kamel Biskri Iss Christian from defence-force forum + Cedric Paille Amiga & Windows ports @@ -146,6 +147,8 @@ Here are all the options: "microdisc" or "m" for Microdisc "jasmin" or "j" for Jasmin + "bd500" or "b" for ByteDrive BD-500 + "pravetz" or "p" for Pravetz-8D FDC -s / --symbols = Load symbols from a file -f / --fullscreen = Run oricutron fullscreen @@ -224,6 +227,7 @@ Keys F12 - Paste (BeOS, Linux & Windows) Help - Show guide (Amiga, MorphOS and AROS) AltGr - Additional modifier + PrtSc - Save screen as BMP In menus @@ -242,7 +246,7 @@ Keys F1 - Go to the menu F2 - Return to the emulator F3 - Toggle console/debug output/memwatch - F4 - Toggle VIA/AY/disk information + F4 - Toggle VIA/AY/disk information/Twilighte board registers F9 - Reset cycle count F10 - Step over code F11 - Step over code without tracing into @@ -285,15 +289,20 @@ Commands: bcm - Clear mem breakpoint bl - List breakpoints blm - List mem breakpoints - bs [zc] - Set breakpoint + bs [zct] - Set breakpoint bsm [rwc] - Set mem breakpoint bz - Zap breakpoints bzm - Zap mem breakpoints d - Disassemble - df - Disassemble to file + fd - Disassemble to file + fw - Write mem to BIN file + fr - Read BIN file to mem m - Dump memory mm - Modify memory mw - Memory watch at addr + ms - Search value in RAM memory + mr - Refine search with new value + mp - Print memory search addresses nl - Load snapshot ns - Save snapshot r - Set to @@ -306,7 +315,6 @@ Commands: sl - Load user symbols sx - Export user symbols sz - Zap user symbols - wm - Write mem to disk @@ -317,12 +325,15 @@ There are two types of breakpoint. "Normal" breakpoints trigger when the CPU is about to execute an instruction at the breakpoint address. "Memory" breakpoints trigger when the breakpoint address is accessed or modified. -Normal breakpoints can use 'z' and/or 'c' modifiers. +Normal breakpoints can use 'z','c' and 't' modifiers. bs $0c00 <-- Break when the CPU is about to execute code at $0c00 bs $0c00 z <-- Break when the CPU is about to execute code at $0c00 and set cycles counter to 0 bs $0c00 zc <-- Set cycles counter to 0 and continues bs $0c00 c <-- Continues execution (i.e. disabled breakpoint) +bs $0c00 zct <-- Prints in console current counter, + set cycles counter to 0 and continues + The main purpose of these modifiers is to make cycle counting easier. If symbols are loaded, they can be used instead of absolute addresses. @@ -404,7 +415,7 @@ Back-ends are: - com - Oricutron uses any real or virtual COM port in the host machine and communicates with the hardware attached to this serial port - modem - unites ACIA with attached modem linked to internet with server and client sockets -In 'modem' mode are available folowing 'AT' commands: +In 'modem' mode are available following 'AT' commands: AT - returns 'OK' ATZ - initialize the modem AT&F - initialize the modem @@ -432,7 +443,7 @@ emulation: contact Jede (jede@oric.org). Because this emulation is used also in ACE emulator (cpc emulation). Offset and me are trying to keep the same emulation. It's easier to work together than alone. -CH376 command emulated : +CH376 command emulated: - CH376_CMD_GET_IC_VER - CH376_CMD_CHECK_EXIST - CH376_CMD_SET_USB_MODE @@ -453,26 +464,67 @@ CH376 command emulated : - CH376_CMD_BYTE_WR_GO - CH376_CMD_DISK_QUERY - CH376_CMD_DIR_CREATE (not emulated under linux) -- CH376_CMD_DISK_RD_GO +- CH376_CMD_DISK_RD_GO -Known bug : -Under windows, API's file does not send "." and ".." entries when we read the content on the folder. It's a problem because ch376 chip send these +Known bug: +Under windows, API's file does not send "." and ".." entries when we read the content on the folder. It's a problem because ch376 chip send these entries, when we ask to this chip to read the content of a directory. -If someone wants to emulate CH376_CMD_DIR_CREATE and CH376_CMD_FILE_ERASE. It's easy to do : it justs need to copy WIN32 function and replace DeleteFile +If someone wants to emulate CH376_CMD_DIR_CREATE and CH376_CMD_FILE_ERASE. It's easy to do: it just needs to copy WIN32 function and replace DeleteFile and CreateDir with rm() and mkdir(). But it's not done because we are not able to test it. -CH376 emulation added for : +CH376 emulation added for: CH376_CMD_FILE_ERASE suppress a file CH376_CMD_DIR_CREATE create folder +Twilighte board emulation +========================= + +The twilighte board is working on atmos (and Oric-1). It disables internal Oric ROM and add 64 banks (by bank switching). +It adds 32 banks of ROM (eeprom) and 32 banks of RAM (Static RAM saved with a battery). +EEprom can be programmed from Orix command line. +The board handles ch376 (sdcard/usbdrive/usb/hid controller). +And the board adds 2 joysticks ports. + +The emulation, for instance, handles 32 ROM banks and 32 RAM banks. It emulates this bank switching. + +Board is working with a cumulus. Anyway, this part is not emulated and you need to switch to Telestrat mode to have this behavior. + +Anyway, on Telestrat, orix can start floppy disk because FDC is present. + +Not emulated parts: +* eeprom programming sequence +* loading ROM into RAM bank (which could emulate RAM saved with battery) +* save on disk any modification into RAM bank (which could emulate RAM saved with battery) +* ch376 is not fully supported in the emulation mode. There is a lot of others functionalities which are missing on ch376 emulation +* firmware 2 of the board. Only firmware 1 of the board is supported + +To activate the plugin, you must activate twilighte_board option in oricutron.cfg + +Update twilighte.cfg plugin in plugins/twilighte_card/twilighte.cfg if you want to load others roms. + +In order to start at least, minimal configuration, kernel.rom must be set in twilbankrom07 and shell.rom in twilbankrom05. + +Last roms can be found here: http://repo.orix.oric.org/dists/official/tgz/6502/ +* kernel.tgz contains kernel.rom +* shell.tgz contains shell.rom + +Under linux, sdcard folder and/or usbdrive folder must have uppercase filenames or else, no binaries can be started. You can mount a fat32 filesystem in sdcard or usbdrive. + +Filenames must be in uppercase, because usb chip manage by default FAT32 filesystem. + +For basic11 rom which handles joysticks and .tap load from sdcard or usbdrive, you have to download basic.tgz here: http://repo.orix.oric.org/dists/official/tgz/6502/ +And you need to replace twilbankrom06 with the rom in basic11.tgz. + +Oricutron is provided with kernel (Orix) and shell (Orix) v2022.1 roms. For updates, see http://repo.orix.oric.org/dists/official/tgz/6502/ + ROM patch files =============== For detailed usage see included '.pch' files in roms subdirectory. -Additionaly unlimited number of binary patches can be added: +Additionally unlimited number of binary patches can be added: $XXXX:00112233445566778899AABBCCDDEEFF.... $YYYY:AA55AA55.... diff --git a/ReadMeNinjaCMakeBuild.md b/ReadMeNinjaCMakeBuild.md index f486934e..4bfefc24 100644 --- a/ReadMeNinjaCMakeBuild.md +++ b/ReadMeNinjaCMakeBuild.md @@ -1,42 +1,84 @@ # Ninja + CMake Buildsystem for Oricutron +## Symbols used in this documentation + +[...] Optional steps + ## Dependencies ### Windows -SDL2, OpenGL +SDL1/2, OpenGL ### Linux -SDL2, GTK-3 +SDL1/2, GTK-3 -## Building - -### Windows +## Preparation the Build System -Open a Visual Studio Developer Command Prompt 2019 +### UBUNTU 18.04 / 20.04 -`mkdir build\windows` -`cd build\windows` -`cmake -GNinja ../..` -`ninja` -`Oricutron.exe` +```shell +sudo apt-get update +sudo apt install build-essential +sudo apt install cmake +sudo apt install ninja-build +sudo apt install libsdl1.2-dev +[sudo apt install libsdl2-dev] +sudo apt install libgtk-3-dev +``` -### Linux +### openSUSE Leap-15-1 -Open a terminal (on Windows you can use WSL + e.g. Ubuntu) +```shell +[sudo zypper refresh] +sudo zypper update +sudo zypper in cmake +sudo zypper in ninja +sudo zypper in libSDL-devel +[sudo zypper in libSDL2-devel] +sudo zypper in gtk3-devel +``` -`mkdir build/linux` -`cd build/linux` -`cmake -GNinja ../..` -`ninja` -`./oricutron` +## Building -### Linux + Windows +### Windows + Visual Studio 2019 + cmake + Ninja -Before starting Oricutron you must copy the roms and images directories and the configuration file +Open a Visual Studio Developer Command Prompt 2019 -to the `build/windows` and/or `build/linux` directory. +```shell +mkdir build\windows +pushd build\windows +cmake -GNinja ..\.. [-DUSE_SDL2:BOOL=ON] +ninja +copy Oricutron.exe ..\.. +[copy Oricutron-sdl2.exe ..\..] +popd +mklink SDL.dll msvc\vcpkg\installed\x64-windows\bin\SDL.dll +[mklink SDL2.dll msvc\vcpkg\installed\x64-windows\bin\SDL2.dll] +Oricutron.exe +[Oricutron-sdl2.exe] +``` + +### Linux + cmake + Ninja + +Open a terminal (on Windows you can use e.g. WSL + Ubuntu) + +```shell +mkdir -p build/linux +pushd build/linux +cmake -GNinja ../.. +[cmake -GNinja ../.. -DUSE_SDL2:BOOL=ON] +ninja +cp Oricutron ../.. +[cp Oricutron-sdl2 ../..] +popd +./Oricutron +[./Oricutron-sdl2] +``` + +## Remarks Linux + Windows + +Before starting Oricutron you must copy your roms, disks and images to the appropriate folders and change the configuration file `oricutron.cfg` to your needs. On Windows with WSL you need VcXsrv X server for Windows to see the output. - diff --git a/XCode/.DS_Store b/XCode/.DS_Store new file mode 100644 index 00000000..4af02b9a Binary files /dev/null and b/XCode/.DS_Store differ diff --git a/XCode/Oricutron/.DS_Store b/XCode/Oricutron/.DS_Store new file mode 100644 index 00000000..c1d36878 Binary files /dev/null and b/XCode/Oricutron/.DS_Store differ diff --git a/XCode/Oricutron/Oricutron.xcodeproj/project.pbxproj b/XCode/Oricutron/Oricutron.xcodeproj/project.pbxproj index f1dc4e37..e112e7c3 100644 --- a/XCode/Oricutron/Oricutron.xcodeproj/project.pbxproj +++ b/XCode/Oricutron/Oricutron.xcodeproj/project.pbxproj @@ -7,6 +7,8 @@ objects = { /* Begin PBXBuildFile section */ + 092FF7F4229BF04200CD20B3 /* ch376.c in Sources */ = {isa = PBXBuildFile; fileRef = 092FF7F0229BF04100CD20B3 /* ch376.c */; }; + 092FF7F5229BF04200CD20B3 /* oric_ch376_plugin.c in Sources */ = {isa = PBXBuildFile; fileRef = 092FF7F1229BF04100CD20B3 /* oric_ch376_plugin.c */; }; 181F128618CA616A009690E0 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 181F128518CA616A009690E0 /* Cocoa.framework */; }; 181F129018CA616A009690E0 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 181F128E18CA616A009690E0 /* InfoPlist.strings */; }; 181F129618CA616A009690E0 /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 181F129418CA616A009690E0 /* Credits.rtf */; }; @@ -40,6 +42,8 @@ 181F131918CA6378009690E0 /* msgbox_osx.m in Sources */ = {isa = PBXBuildFile; fileRef = 181F131618CA6378009690E0 /* msgbox_osx.m */; }; 181F131B18CA63F0009690E0 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 181F131A18CA63F0009690E0 /* OpenGL.framework */; }; 181F131D18CA6505009690E0 /* SDL.framework in Resources */ = {isa = PBXBuildFile; fileRef = 181F131118CA6219009690E0 /* SDL.framework */; }; + 1863CD96255BEA4300B1D09B /* oric_ch376_plugin.c in Sources */ = {isa = PBXBuildFile; fileRef = 1863CD92255BEA4300B1D09B /* oric_ch376_plugin.c */; }; + 1863CD97255BEA4300B1D09B /* ch376.c in Sources */ = {isa = PBXBuildFile; fileRef = 1863CD95255BEA4300B1D09B /* ch376.c */; }; 18A21B171B5CD8EC00B1BF3F /* system_sdl.c in Sources */ = {isa = PBXBuildFile; fileRef = 18A21B161B5CD8EC00B1BF3F /* system_sdl.c */; }; 18D270CA18D7346600467488 /* keyboard.c in Sources */ = {isa = PBXBuildFile; fileRef = 18D270C818D7346600467488 /* keyboard.c */; }; 18DC24B119D010EA00C6BCBE /* 6551_com.c in Sources */ = {isa = PBXBuildFile; fileRef = 18DC24AE19D010EA00C6BCBE /* 6551_com.c */; }; @@ -58,6 +62,10 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 092FF7F0229BF04100CD20B3 /* ch376.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ch376.c; path = ../../../plugins/ch376/ch376.c; sourceTree = ""; }; + 092FF7F1229BF04100CD20B3 /* oric_ch376_plugin.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = oric_ch376_plugin.c; path = ../../../plugins/ch376/oric_ch376_plugin.c; sourceTree = ""; }; + 092FF7F2229BF04100CD20B3 /* ch376.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ch376.h; path = ../../../plugins/ch376/ch376.h; sourceTree = ""; }; + 092FF7F3229BF04200CD20B3 /* oric_ch376_plugin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = oric_ch376_plugin.h; path = ../../../plugins/ch376/oric_ch376_plugin.h; sourceTree = ""; }; 181F128218CA616A009690E0 /* Oricutron.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Oricutron.app; sourceTree = BUILT_PRODUCTS_DIR; }; 181F128518CA616A009690E0 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; 181F128818CA616A009690E0 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; }; @@ -65,7 +73,6 @@ 181F128A18CA616A009690E0 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 181F128D18CA616A009690E0 /* Oricutron-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Oricutron-Info.plist"; sourceTree = ""; }; 181F128F18CA616A009690E0 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; - 181F129318CA616A009690E0 /* Oricutron-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Oricutron-Prefix.pch"; sourceTree = ""; }; 181F129518CA616A009690E0 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; name = en; path = en.lproj/Credits.rtf; sourceTree = ""; }; 181F129D18CA616A009690E0 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 181F12A318CA616A009690E0 /* OricutronTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = OricutronTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -119,6 +126,11 @@ 181F131518CA6378009690E0 /* gui_osx.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = gui_osx.m; path = ../../../gui_osx.m; sourceTree = ""; }; 181F131618CA6378009690E0 /* msgbox_osx.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = msgbox_osx.m; path = ../../../msgbox_osx.m; sourceTree = ""; }; 181F131A18CA63F0009690E0 /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = ../../../../../../../System/Library/Frameworks/OpenGL.framework; sourceTree = ""; }; + 1863CD8B255BE39500B1D09B /* Oricutron-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Oricutron-Prefix.pch"; sourceTree = ""; }; + 1863CD92255BEA4300B1D09B /* oric_ch376_plugin.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = oric_ch376_plugin.c; path = ../../../plugins/ch376/oric_ch376_plugin.c; sourceTree = ""; }; + 1863CD93255BEA4300B1D09B /* ch376.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ch376.h; path = ../../../plugins/ch376/ch376.h; sourceTree = ""; }; + 1863CD94255BEA4300B1D09B /* oric_ch376_plugin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = oric_ch376_plugin.h; path = ../../../plugins/ch376/oric_ch376_plugin.h; sourceTree = ""; }; + 1863CD95255BEA4300B1D09B /* ch376.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ch376.c; path = ../../../plugins/ch376/ch376.c; sourceTree = ""; }; 18A21B161B5CD8EC00B1BF3F /* system_sdl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = system_sdl.c; path = ../../../system_sdl.c; sourceTree = ""; }; 18A21B181B5CDAD100B1BF3F /* system_sdl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = system_sdl.h; path = ../../../system_sdl.h; sourceTree = ""; }; 18D270C818D7346600467488 /* keyboard.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = keyboard.c; path = ../../../keyboard.c; sourceTree = ""; }; @@ -194,6 +206,10 @@ 181F128B18CA616A009690E0 /* Oricutron */ = { isa = PBXGroup; children = ( + 1863CD95255BEA4300B1D09B /* ch376.c */, + 1863CD93255BEA4300B1D09B /* ch376.h */, + 1863CD92255BEA4300B1D09B /* oric_ch376_plugin.c */, + 1863CD94255BEA4300B1D09B /* oric_ch376_plugin.h */, 18A21B181B5CDAD100B1BF3F /* system_sdl.h */, 18A21B161B5CD8EC00B1BF3F /* system_sdl.c */, 18D270C818D7346600467488 /* keyboard.c */, @@ -259,8 +275,8 @@ children = ( 181F128D18CA616A009690E0 /* Oricutron-Info.plist */, 181F128E18CA616A009690E0 /* InfoPlist.strings */, - 181F129318CA616A009690E0 /* Oricutron-Prefix.pch */, 181F129418CA616A009690E0 /* Credits.rtf */, + 1863CD8B255BE39500B1D09B /* Oricutron-Prefix.pch */, ); name = "Supporting Files"; sourceTree = ""; @@ -309,7 +325,7 @@ 181F127A18CA616A009690E0 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0500; + LastUpgradeCheck = 1210; ORGANIZATIONNAME = "Peter Gordon"; TargetAttributes = { 181F12A218CA616A009690E0 = { @@ -319,9 +335,10 @@ }; buildConfigurationList = 181F127D18CA616A009690E0 /* Build configuration list for PBXProject "Oricutron" */; compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; + developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( + English, en, Base, ); @@ -365,11 +382,13 @@ 181F130B18CA61C6009690E0 /* ula.c in Sources */, 181F130618CA61C6009690E0 /* render_null.c in Sources */, 181F130C18CA61C6009690E0 /* via.c in Sources */, + 092FF7F4229BF04200CD20B3 /* ch376.c in Sources */, 181F12FF18CA61C6009690E0 /* monitor.c in Sources */, 181F131718CA6378009690E0 /* filereq_osx.m in Sources */, 181F12FC18CA61C6009690E0 /* joystick.c in Sources */, 181F130818CA61C6009690E0 /* render_sw8.c in Sources */, 181F12EF18CA61C6009690E0 /* 6551.c in Sources */, + 092FF7F5229BF04200CD20B3 /* oric_ch376_plugin.c in Sources */, 181F12F218CA61C6009690E0 /* disk_pravetz.c in Sources */, 181F12FE18CA61C6009690E0 /* main.c in Sources */, 181F130518CA61C6009690E0 /* render_gl.c in Sources */, @@ -377,6 +396,7 @@ 181F130A18CA61C6009690E0 /* tape.c in Sources */, 18DC24B219D010EA00C6BCBE /* 6551_loopback.c in Sources */, 181F12EE18CA61C6009690E0 /* 6502.c in Sources */, + 1863CD96255BEA4300B1D09B /* oric_ch376_plugin.c in Sources */, 18DC24B119D010EA00C6BCBE /* 6551_com.c in Sources */, 181F131918CA6378009690E0 /* msgbox_osx.m in Sources */, 181F12F118CA61C6009690E0 /* avi.c in Sources */, @@ -386,6 +406,7 @@ 181F131818CA6378009690E0 /* gui_osx.m in Sources */, 181F130918CA61C6009690E0 /* snapshot.c in Sources */, 18D270CA18D7346600467488 /* keyboard.c in Sources */, + 1863CD97255BEA4300B1D09B /* ch376.c in Sources */, 181F12F318CA61C6009690E0 /* disk.c in Sources */, 181F12F018CA61C6009690E0 /* 8912.c in Sources */, 181F12FB18CA61C6009690E0 /* gui.c in Sources */, @@ -435,21 +456,37 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_OBJC_EXCEPTIONS = YES; + GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", @@ -464,6 +501,7 @@ GCC_WARN_UNUSED_VARIABLE = YES; MACOSX_DEPLOYMENT_TARGET = 10.9; ONLY_ACTIVE_ARCH = YES; + PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = YES; SDKROOT = macosx; }; name = Debug; @@ -472,22 +510,37 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_ENABLE_OBJC_EXCEPTIONS = YES; + GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; @@ -496,6 +549,7 @@ GCC_WARN_UNUSED_VARIABLE = YES; MACOSX_DEPLOYMENT_TARGET = 10.9; ONLY_ACTIVE_ARCH = YES; + PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = YES; SDKROOT = macosx; }; name = Release; @@ -504,14 +558,20 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = NO; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO; + CODE_SIGN_IDENTITY = "-"; COMBINE_HIDPI_IMAGES = YES; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(LOCAL_LIBRARY_DIR)/Frameworks", ); + GCC_INCREASE_PRECOMPILED_HEADER_SHARING = YES; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "Oricutron/Oricutron-Prefix.pch"; + HEADER_SEARCH_PATHS = /opt/X11/include; INFOPLIST_FILE = "Oricutron/Oricutron-Info.plist"; LD_RUNPATH_SEARCH_PATHS = "@loader_path/../Resources/"; OTHER_CFLAGS = ""; @@ -521,12 +581,13 @@ "-D__SPECIFY_SDL_DIR__", "-DAPP_NAME_FULL='\"Oricutron 1.2\"'", "-DAPP_YEAR='\"2014\"'", - "-DVERSION_COPYRIGHTS='\"Oricutron 1.2.0 (c)2014 Peter Gordon (pete@petergordon.org.uk)\"'", + "-DVERSION_COPYRIGHTS='\"Oricutron 1.2.0 (c)2014 Peter Gordon (pete@gordon.plus)\"'", "-DBACKEND_COM", "-DBACKEND_MODEM", "-D__OPENGL_AVAILABLE__", "-DSDL_MAJOR_VERSION=1", ); + PRODUCT_BUNDLE_IDENTIFIER = "uk.org.petergordon.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = app; }; @@ -536,14 +597,20 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = NO; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO; + CODE_SIGN_IDENTITY = "-"; COMBINE_HIDPI_IMAGES = YES; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(LOCAL_LIBRARY_DIR)/Frameworks", ); + GCC_INCREASE_PRECOMPILED_HEADER_SHARING = YES; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "Oricutron/Oricutron-Prefix.pch"; + HEADER_SEARCH_PATHS = /opt/X11/include; INFOPLIST_FILE = "Oricutron/Oricutron-Info.plist"; LD_RUNPATH_SEARCH_PATHS = "@loader_path/../Resources/"; OTHER_CFLAGS = ""; @@ -554,11 +621,12 @@ "-DSDL_MAJOR_VERSION=1", "-DAPP_NAME_FULL='\"Oricutron 1.2\"'", "-DAPP_YEAR='\"2014\"'", - "-DVERSION_COPYRIGHTS='\"Oricutron 1.2.0 (c)2014 Peter Gordon (pete@petergordon.org.uk)\"'", + "-DVERSION_COPYRIGHTS='\"Oricutron 1.2.0 (c)2014 Peter Gordon (pete@gordon.plus)\"'", "-D__OPENGL_AVAILABLE__", "-DBACKEND_COM", "-DBACKEND_MODEM", ); + PRODUCT_BUNDLE_IDENTIFIER = "uk.org.petergordon.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = app; }; @@ -580,6 +648,7 @@ "$(inherited)", ); INFOPLIST_FILE = "OricutronTests/OricutronTests-Info.plist"; + PRODUCT_BUNDLE_IDENTIFIER = "uk.org.petergordon.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; TEST_HOST = "$(BUNDLE_LOADER)"; WRAPPER_EXTENSION = xctest; @@ -598,6 +667,7 @@ GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "Oricutron/Oricutron-Prefix.pch"; INFOPLIST_FILE = "OricutronTests/OricutronTests-Info.plist"; + PRODUCT_BUNDLE_IDENTIFIER = "uk.org.petergordon.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; TEST_HOST = "$(BUNDLE_LOADER)"; WRAPPER_EXTENSION = xctest; diff --git a/XCode/Oricutron/Oricutron.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/XCode/Oricutron/Oricutron.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 00000000..18d98100 --- /dev/null +++ b/XCode/Oricutron/Oricutron.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/XCode/Oricutron/Oricutron.xcodeproj/project.xcworkspace/xcuserdata/j.xcuserdatad/UserInterfaceState.xcuserstate b/XCode/Oricutron/Oricutron.xcodeproj/project.xcworkspace/xcuserdata/j.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 00000000..5c9f55f7 Binary files /dev/null and b/XCode/Oricutron/Oricutron.xcodeproj/project.xcworkspace/xcuserdata/j.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/XCode/Oricutron/Oricutron.xcodeproj/project.xcworkspace/xcuserdata/torguet.xcuserdatad/UserInterfaceState.xcuserstate b/XCode/Oricutron/Oricutron.xcodeproj/project.xcworkspace/xcuserdata/torguet.xcuserdatad/UserInterfaceState.xcuserstate index 31cc5640..3a0c0179 100644 Binary files a/XCode/Oricutron/Oricutron.xcodeproj/project.xcworkspace/xcuserdata/torguet.xcuserdatad/UserInterfaceState.xcuserstate and b/XCode/Oricutron/Oricutron.xcodeproj/project.xcworkspace/xcuserdata/torguet.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/XCode/Oricutron/Oricutron.xcodeproj/xcshareddata/xcschemes/Oricutron.xcscheme b/XCode/Oricutron/Oricutron.xcodeproj/xcshareddata/xcschemes/Oricutron.xcscheme new file mode 100644 index 00000000..101afcff --- /dev/null +++ b/XCode/Oricutron/Oricutron.xcodeproj/xcshareddata/xcschemes/Oricutron.xcscheme @@ -0,0 +1,107 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/XCode/Oricutron/Oricutron.xcodeproj/xcuserdata/j.xcuserdatad/xcschemes/xcschememanagement.plist b/XCode/Oricutron/Oricutron.xcodeproj/xcuserdata/j.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 00000000..42cd8712 --- /dev/null +++ b/XCode/Oricutron/Oricutron.xcodeproj/xcuserdata/j.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,27 @@ + + + + + SchemeUserState + + Oricutron.xcscheme_^#shared#^_ + + orderHint + 0 + + + SuppressBuildableAutocreation + + 181F128118CA616A009690E0 + + primary + + + 181F12A218CA616A009690E0 + + primary + + + + + diff --git a/XCode/Oricutron/Oricutron.xcodeproj/xcuserdata/torguet.xcuserdatad/xcschemes/Oricutron.xcscheme b/XCode/Oricutron/Oricutron.xcodeproj/xcuserdata/torguet.xcuserdatad/xcschemes/Oricutron.xcscheme index 24c244f2..4975b9fc 100644 --- a/XCode/Oricutron/Oricutron.xcodeproj/xcuserdata/torguet.xcuserdatad/xcschemes/Oricutron.xcscheme +++ b/XCode/Oricutron/Oricutron.xcodeproj/xcuserdata/torguet.xcuserdatad/xcschemes/Oricutron.xcscheme @@ -1,6 +1,6 @@ + shouldUseLaunchSchemeArgsEnv = "YES"> + + + + @@ -39,26 +48,19 @@ - - - - - + - - - + CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier - uk.org.petergordon.${PRODUCT_NAME:rfc1034identifier} + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName diff --git a/XCode/Oricutron/Oricutron/Oricutron-Prefix.pch b/XCode/Oricutron/Oricutron/Oricutron-Prefix.pch new file mode 100644 index 00000000..5d15dfce --- /dev/null +++ b/XCode/Oricutron/Oricutron/Oricutron-Prefix.pch @@ -0,0 +1,15 @@ +// +// Oricutron-Prefix.pch +// Oricutron +// +// Created by Patrice Torguet on 11/11/2020. +// Copyright © 2020 Peter Gordon. All rights reserved. +// + +#ifndef Oricutron_Prefix_pch +#define Oricutron_Prefix_pch + +// Include any system framework and library headers here that should be included in all compilation units. +// You will also need to set the Prefix Header build setting of one or more of your targets to reference this file. + +#endif /* Oricutron_Prefix_pch */ diff --git a/XCode/Oricutron/OricutronTests/OricutronTests-Info.plist b/XCode/Oricutron/OricutronTests/OricutronTests-Info.plist index 0a7da72d..169b6f71 100644 --- a/XCode/Oricutron/OricutronTests/OricutronTests-Info.plist +++ b/XCode/Oricutron/OricutronTests/OricutronTests-Info.plist @@ -7,7 +7,7 @@ CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier - uk.org.petergordon.${PRODUCT_NAME:rfc1034identifier} + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundlePackageType diff --git a/avi.c b/avi.c index 3d5bfdfe..2d21694f 100644 --- a/avi.c +++ b/avi.c @@ -32,78 +32,78 @@ extern SDL_AudioSpec obtained; // Write a 32bit value to a stream in little-endian format -static SDL_bool write32l( SDL_bool stillok, struct avi_handle *ah, Uint32 val, Uint32 *rem ) +static SDL_bool write32l(SDL_bool stillok, struct avi_handle *ah, Uint32 val, Uint32 *rem) { - if( !stillok ) return SDL_FALSE; // Something failed earlier, so we're aborting - if( rem ) (*rem) = ah->csize; + if(!stillok) return SDL_FALSE; // Something failed earlier, so we're aborting + if(rem)(*rem) = ah->csize; ah->csize += 4; _MAKE_LE32(val); - return (fwrite( &val, 4, 1, ah->f ) == 1); + return (fwrite(&val, 4, 1, ah->f) == 1); } // Write a 16bit value to a stream in little-endian format -static SDL_bool write16l( SDL_bool stillok, struct avi_handle *ah, Uint16 val, Uint32 *rem ) +static SDL_bool write16l(SDL_bool stillok, struct avi_handle *ah, Uint16 val, Uint32 *rem) { - if( !stillok ) return SDL_FALSE; // Something failed earlier, so we're aborting - if( rem ) (*rem) = ah->csize; + if(!stillok) return SDL_FALSE; // Something failed earlier, so we're aborting + if(rem)(*rem) = ah->csize; ah->csize += 2; _MAKE_LE16(val); - return (fwrite( &val, 2, 1, ah->f ) == 1); + return (fwrite(&val, 2, 1, ah->f) == 1); } // Write a string to a stream -static SDL_bool writestr( SDL_bool stillok, struct avi_handle *ah, char *str, Uint32 *rem ) +static SDL_bool writestr(SDL_bool stillok, struct avi_handle *ah, char* str, Uint32 *rem) { - Sint32 i = (int)strlen( str ); - if( !stillok ) return SDL_FALSE; // Something failed earlier, so we're aborting - if( rem ) (*rem) = ah->csize; + Sint32 i = (int)strlen(str); + if(!stillok) return SDL_FALSE; // Something failed earlier, so we're aborting + if(rem)(*rem) = ah->csize; ah->csize += i; - return (fwrite( str, i, 1, ah->f ) == 1); + return (fwrite(str, i, 1, ah->f) == 1); } // Write a 32bit value to a stream in little-endian format at a specific offset -static SDL_bool seek_write32l( SDL_bool stillok, struct avi_handle *ah, Uint32 offs, Uint32 val ) +static SDL_bool seek_write32l(SDL_bool stillok, struct avi_handle *ah, Uint32 offs, Uint32 val) { - if( !stillok ) return SDL_FALSE; // Something failed earlier, so we're aborting - if( offs == 0 ) return SDL_TRUE; // Don't overwrite RIFF! - fseek( ah->f, offs, SEEK_SET ); + if(!stillok) return SDL_FALSE; // Something failed earlier, so we're aborting + if(offs == 0) return SDL_TRUE; // Don't overwrite RIFF! + fseek(ah->f, offs, SEEK_SET); _MAKE_LE32(val); - return (fwrite( &val, 4, 1, ah->f ) == 1); + return (fwrite(&val, 4, 1, ah->f) == 1); } // Write a block of memory -static SDL_bool writeblk( SDL_bool stillok, struct avi_handle *ah, Uint8 *blk, Uint32 blklen ) +static SDL_bool writeblk(SDL_bool stillok, struct avi_handle *ah, Uint8 *blk, Uint32 blklen) { - if( !stillok ) return SDL_FALSE; + if(!stillok) return SDL_FALSE; ah->csize += blklen; - return (fwrite( blk, blklen, 1, ah->f ) == 1); + return (fwrite(blk, blklen, 1, ah->f) == 1); } // Write an 8bit value to a stream -static SDL_bool writebyt( SDL_bool stillok, struct avi_handle *ah, Uint8 val ) +static SDL_bool writebyt(SDL_bool stillok, struct avi_handle *ah, Uint8 val) { - if( !stillok ) return SDL_FALSE; // Something failed earlier, so we're aborting + if(!stillok) return SDL_FALSE; // Something failed earlier, so we're aborting ah->csize += 1; - return (fwrite( &val, 1, 1, ah->f ) == 1); + return (fwrite(&val, 1, 1, ah->f) == 1); } #define AVIFLAGS (AVIF_ISINTERLEAVED|AVIF_WASCAPTUREFILE) -struct avi_handle *avi_open( char *filename, Uint8 *pal, SDL_bool dosound, int is50hz ) +struct avi_handle *avi_open(char* filename, Uint8 *pal, SDL_bool dosound, int is50hz) { struct avi_handle *ah; SDL_bool ok; Sint32 i; - ah = malloc( sizeof( struct avi_handle ) ); - if( !ah ) return NULL; - - memset( ah, 0, sizeof( struct avi_handle ) ); + ah = malloc(sizeof(struct avi_handle)); + if(!ah) return NULL; - ah->f = fopen( filename, "wb" ); - if( !ah->f ) + memset(ah, 0, sizeof(struct avi_handle)); + + ah->f = fopen(filename, "wb"); + if(!ah->f) { - free( ah ); + free(ah); return NULL; } @@ -112,115 +112,115 @@ struct avi_handle *avi_open( char *filename, Uint8 *pal, SDL_bool dosound, int i ah->is50hz = is50hz; ok = SDL_TRUE; - ok &= writestr( ok, ah, "RIFF" , NULL ); // RIFF header - ok &= write32l( ok, ah, 0, &ah->offs_riffsize ); // RIFF size - ok &= writestr( ok, ah, "AVI " , NULL ); // RIFF type - ok &= writestr( ok, ah, "LIST" , NULL ); // Header list - ok &= write32l( ok, ah, 0, &ah->offs_hdrlsize ); // Header list size - ok &= writestr( ok, ah, "hdrl" , NULL ); // Header list identifier - - ok &= writestr( ok, ah, "avih" , NULL ); // MainAVIHeader chunk - ok &= write32l( ok, ah, 56, NULL ); // Chunk size - ok &= write32l( ok, ah,is50hz?20000:16667,&ah->offs_usperfrm); // Microseconds per frame - ok &= write32l( ok, ah, 0, NULL ); // Max bytes per second - ok &= write32l( ok, ah, 0, NULL ); // Padding granularity - ok &= write32l( ok, ah, AVIFLAGS, NULL ); // Flags - ok &= write32l( ok, ah, 0, &ah->offs_frames ); // Number of frames - ok &= write32l( ok, ah, 0, NULL ); // Initial frames - ok &= write32l( ok, ah, ah->dosnd?2:1, NULL ); // Stream count - ok &= write32l( ok, ah, 0, NULL ); // Suggested buffer size - ok &= write32l( ok, ah, 240, NULL ); // Width - ok &= write32l( ok, ah, 224, NULL ); // Height - ok &= write32l( ok, ah, 0, NULL ); // Reserved - ok &= write32l( ok, ah, 0, NULL ); // Reserved - ok &= write32l( ok, ah, 0, NULL ); // Reserved - ok &= write32l( ok, ah, 0, NULL ); // Reserved - - ok &= writestr( ok, ah, "LIST" , NULL ); // Stream header list - ok &= write32l( ok, ah,4+8+56+8+40+8*4, NULL ); // Stream header list size - ok &= writestr( ok, ah, "strl" , NULL ); // Stream header list identifier - - ok &= writestr( ok, ah, "strh" , NULL ); // Video stream header - ok &= write32l( ok, ah, 56, NULL ); // Chunk size - ok &= writestr( ok, ah, "vids" , NULL ); // Type - ok &= writestr( ok, ah, "MRLE" , NULL ); // Microsoft Run Length Encoding - ok &= write32l( ok, ah, 0, NULL ); // Flags - ok &= write32l( ok, ah, 0, NULL ); // Reserved - ok &= write32l( ok, ah, 0, NULL ); // Initial frames - ok &= write32l( ok, ah, 1000000, NULL ); // Scale - ok &= write32l( ok, ah,is50hz?50000000:60000000,&ah->offs_frmrate); // Rate - ok &= write32l( ok, ah, 0, NULL ); // Start - ok &= write32l( ok, ah, 0, &ah->offs_frames2 ); // Length - ok &= write32l( ok, ah, 0, NULL ); // Suggested buffer size - ok &= write32l( ok, ah, 10000, NULL ); // Quality - ok &= write32l( ok, ah, 0, NULL ); // Sample size - ok &= write32l( ok, ah, 0, NULL ); // Frame - ok &= write32l( ok, ah, 0, NULL ); // Frame - - ok &= writestr( ok, ah, "strf" , NULL ); // Video stream format - ok &= write32l( ok, ah, 40+8*4, NULL ); // Chunk size - ok &= write32l( ok, ah, 40, NULL ); // Structure size - ok &= write32l( ok, ah, 240, NULL ); // Width - ok &= write32l( ok, ah, 224, NULL ); // Height - ok &= write16l( ok, ah, 1, NULL ); // Planes - ok &= write16l( ok, ah, 8, NULL ); // Bit count - ok &= write32l( ok, ah, 1, NULL ); // Compression - ok &= write32l( ok, ah, 240*244, NULL ); // Image size - ok &= write32l( ok, ah, 0, NULL ); // XPelsPerMeter - ok &= write32l( ok, ah, 0, NULL ); // YPelsPerMeter - ok &= write32l( ok, ah, 8, NULL ); // Colours used - ok &= write32l( ok, ah, 8, NULL ); // Colours important - - for( i=0; i<8; i++ ) + ok &= writestr(ok, ah, "RIFF", NULL); // RIFF header + ok &= write32l(ok, ah, 0, &ah->offs_riffsize); // RIFF size + ok &= writestr(ok, ah, "AVI ", NULL); // RIFF type + ok &= writestr(ok, ah, "LIST", NULL); // Header list + ok &= write32l(ok, ah, 0, &ah->offs_hdrlsize); // Header list size + ok &= writestr(ok, ah, "hdrl", NULL); // Header list identifier + + ok &= writestr(ok, ah, "avih", NULL); // MainAVIHeader chunk + ok &= write32l(ok, ah, 56, NULL); // Chunk size + ok &= write32l(ok, ah,is50hz?20000:16667, &ah->offs_usperfrm); // Microseconds per frame + ok &= write32l(ok, ah, 0, NULL); // Max bytes per second + ok &= write32l(ok, ah, 0, NULL); // Padding granularity + ok &= write32l(ok, ah, AVIFLAGS, NULL); // Flags + ok &= write32l(ok, ah, 0, &ah->offs_frames); // Number of frames + ok &= write32l(ok, ah, 0, NULL); // Initial frames + ok &= write32l(ok, ah, ah->dosnd?2:1, NULL); // Stream count + ok &= write32l(ok, ah, 0, NULL); // Suggested buffer size + ok &= write32l(ok, ah, 240, NULL); // Width + ok &= write32l(ok, ah, 224, NULL); // Height + ok &= write32l(ok, ah, 0, NULL); // Reserved + ok &= write32l(ok, ah, 0, NULL); // Reserved + ok &= write32l(ok, ah, 0, NULL); // Reserved + ok &= write32l(ok, ah, 0, NULL); // Reserved + + ok &= writestr(ok, ah, "LIST", NULL); // Stream header list + ok &= write32l(ok, ah,4+8+56+8+40+8*4, NULL); // Stream header list size + ok &= writestr(ok, ah, "strl", NULL); // Stream header list identifier + + ok &= writestr(ok, ah, "strh", NULL); // Video stream header + ok &= write32l(ok, ah, 56, NULL); // Chunk size + ok &= writestr(ok, ah, "vids", NULL); // Type + ok &= writestr(ok, ah, "MRLE", NULL); // Microsoft Run Length Encoding + ok &= write32l(ok, ah, 0, NULL); // Flags + ok &= write32l(ok, ah, 0, NULL); // Reserved + ok &= write32l(ok, ah, 0, NULL); // Initial frames + ok &= write32l(ok, ah, 1000000, NULL); // Scale + ok &= write32l(ok, ah,is50hz?50000000:60000000, &ah->offs_frmrate); // Rate + ok &= write32l(ok, ah, 0, NULL); // Start + ok &= write32l(ok, ah, 0, &ah->offs_frames2); // Length + ok &= write32l(ok, ah, 0, NULL); // Suggested buffer size + ok &= write32l(ok, ah, 10000, NULL); // Quality + ok &= write32l(ok, ah, 0, NULL); // Sample size + ok &= write32l(ok, ah, 0, NULL); // Frame + ok &= write32l(ok, ah, 0, NULL); // Frame + + ok &= writestr(ok, ah, "strf", NULL); // Video stream format + ok &= write32l(ok, ah, 40+8*4, NULL); // Chunk size + ok &= write32l(ok, ah, 40, NULL); // Structure size + ok &= write32l(ok, ah, 240, NULL); // Width + ok &= write32l(ok, ah, 224, NULL); // Height + ok &= write16l(ok, ah, 1, NULL); // Planes + ok &= write16l(ok, ah, 8, NULL); // Bit count + ok &= write32l(ok, ah, 1, NULL); // Compression + ok &= write32l(ok, ah, 240*244, NULL); // Image size + ok &= write32l(ok, ah, 0, NULL); // XPelsPerMeter + ok &= write32l(ok, ah, 0, NULL); // YPelsPerMeter + ok &= write32l(ok, ah, 8, NULL); // Colours used + ok &= write32l(ok, ah, 8, NULL); // Colours important + + for(i=0; i<8; i++) { - ok &= writebyt( ok, ah, pal[i*3+2] ); - ok &= writebyt( ok, ah, pal[i*3+1] ); - ok &= writebyt( ok, ah, pal[i*3+0] ); - ok &= writebyt( ok, ah, 0 ); + ok &= writebyt(ok, ah, pal[i*3+2]); + ok &= writebyt(ok, ah, pal[i*3+1]); + ok &= writebyt(ok, ah, pal[i*3+0]); + ok &= writebyt(ok, ah, 0); } - if( ah->dosnd ) + if(ah->dosnd) { - ok &= writestr( ok, ah, "LIST" , NULL ); // Stream header list - ok &= write32l( ok, ah, 4+8+56+8+16, NULL ); // Stream header list size - ok &= writestr( ok, ah, "strl" , NULL ); // Stream header identifier - - ok &= writestr( ok, ah, "strh" , NULL ); // Audio stream header - ok &= write32l( ok, ah, 56, NULL ); // Chunk size - ok &= writestr( ok, ah, "auds" , NULL ); // Type - ok &= write32l( ok, ah, 0, NULL ); // Codec - ok &= write32l( ok, ah, 0, NULL ); // Flags - ok &= write32l( ok, ah, 0, NULL ); // Reserved - ok &= write32l( ok, ah, 0, NULL ); // Initial frames - ok &= write32l( ok, ah, 1, NULL ); // Scale - ok &= write32l( ok, ah,obtained.freq, NULL ); // Rate - ok &= write32l( ok, ah, 0, NULL ); // Start - ok &= write32l( ok, ah, 0, &ah->offs_audiolen ); // Length - ok &= write32l( ok, ah, 0, NULL ); // Suggested buffer size - ok &= write32l( ok, ah, 10000, NULL ); // Quality - ok &= write32l( ok, ah, 2, NULL ); // Sample size - ok &= write32l( ok, ah, 0, NULL ); // Frame - ok &= write32l( ok, ah, 0, NULL ); // Frame - - ok &= writestr( ok, ah, "strf" , NULL ); // Audio stream format - ok &= write32l( ok, ah, 16, NULL ); // Chunk size - ok &= write16l( ok, ah, 1, NULL ); // Format (PCM) - ok &= write16l( ok, ah, 1, NULL ); // Channels - ok &= write32l( ok, ah,obtained.freq, NULL ); // Samples per second - ok &= write32l( ok, ah,obtained.freq*2, NULL ); // Bytes per second - ok &= write16l( ok, ah, 2, NULL ); // BlockAlign - ok &= write16l( ok, ah, 16, NULL ); // BitsPerSample + ok &= writestr(ok, ah, "LIST", NULL); // Stream header list + ok &= write32l(ok, ah, 4+8+56+8+16, NULL); // Stream header list size + ok &= writestr(ok, ah, "strl", NULL); // Stream header identifier + + ok &= writestr(ok, ah, "strh", NULL); // Audio stream header + ok &= write32l(ok, ah, 56, NULL); // Chunk size + ok &= writestr(ok, ah, "auds", NULL); // Type + ok &= write32l(ok, ah, 0, NULL); // Codec + ok &= write32l(ok, ah, 0, NULL); // Flags + ok &= write32l(ok, ah, 0, NULL); // Reserved + ok &= write32l(ok, ah, 0, NULL); // Initial frames + ok &= write32l(ok, ah, 1, NULL); // Scale + ok &= write32l(ok, ah,obtained.freq, NULL); // Rate + ok &= write32l(ok, ah, 0, NULL); // Start + ok &= write32l(ok, ah, 0, &ah->offs_audiolen); // Length + ok &= write32l(ok, ah, 0, NULL); // Suggested buffer size + ok &= write32l(ok, ah, 10000, NULL); // Quality + ok &= write32l(ok, ah, 2, NULL); // Sample size + ok &= write32l(ok, ah, 0, NULL); // Frame + ok &= write32l(ok, ah, 0, NULL); // Frame + + ok &= writestr(ok, ah, "strf", NULL); // Audio stream format + ok &= write32l(ok, ah, 16, NULL); // Chunk size + ok &= write16l(ok, ah, 1, NULL); // Format (PCM) + ok &= write16l(ok, ah, 1, NULL); // Channels + ok &= write32l(ok, ah,obtained.freq, NULL); // Samples per second + ok &= write32l(ok, ah,obtained.freq*2, NULL); // Bytes per second + ok &= write16l(ok, ah, 2, NULL); // BlockAlign + ok &= write16l(ok, ah, 16, NULL); // BitsPerSample } ah->hdrlsize = ah->csize - ah->offs_hdrlsize - 4; - ok &= writestr( ok, ah, "LIST" , NULL ); // movi list - ok &= write32l( ok, ah, 0, &ah->offs_movisize ); // Size - ok &= writestr( ok, ah, "movi" , NULL ); // identifier + ok &= writestr(ok, ah, "LIST", NULL); // movi list + ok &= write32l(ok, ah, 0, &ah->offs_movisize); // Size + ok &= writestr(ok, ah, "movi", NULL); // identifier - if( !ok ) + if(!ok) { - free( ah ); + free(ah); return NULL; } @@ -234,25 +234,25 @@ struct avi_handle *avi_open( char *filename, Uint8 *pal, SDL_bool dosound, int i return ah; } -static Uint32 rle_putpixels( struct avi_handle *ah, Uint8 *srcdata, Uint32 rlec, Uint32 srcc, Uint32 length ) +static Uint32 rle_putpixels(struct avi_handle *ah, Uint8 *srcdata, Uint32 rlec, Uint32 srcc, Uint32 length) { Uint32 c, chunker; - if( length == 0 ) return rlec; + if(length == 0) return rlec; - while( length > 254 ) + while(length > 254) { // Try not to leave an annoying dangly 1,2 or 3 byte section chunker = (length<258) ? 250 : 254; - rlec = rle_putpixels( ah, srcdata, rlec, srcc, chunker ); + rlec = rle_putpixels(ah, srcdata, rlec, srcc, chunker); srcc += chunker; length -= chunker; } // Somehow "chunker" failed :-( - if( length < 3 ) + if(length < 3) { - while( length > 0 ) + while(length > 0) { ah->rledata[rlec++] = 0x01; ah->rledata[rlec++] = srcdata[srcc++]; @@ -265,13 +265,13 @@ static Uint32 rle_putpixels( struct avi_handle *ah, Uint8 *srcdata, Uint32 rlec, ah->rledata[rlec++] = 0x00; ah->rledata[rlec++] = length; - while( c > 0 ) + while(c > 0) { ah->rledata[rlec++] = srcdata[srcc++]; c--; } - if( length & 1 ) + if(length & 1) ah->rledata[rlec++] = 0; return rlec; @@ -279,12 +279,12 @@ static Uint32 rle_putpixels( struct avi_handle *ah, Uint8 *srcdata, Uint32 rlec, // RLE encode the frame #define NOABS 0xffffffff -static Uint32 rle_encode( struct avi_handle *ah, Uint8 *srcdata, Uint32 rlec, Uint32 eol ) +static Uint32 rle_encode(struct avi_handle *ah, Uint8 *srcdata, Uint32 rlec, Uint32 eol) { Uint32 srcc, runc, abspos, chunker; Uint8 thiscol; - if( eol == 0 ) + if(eol == 0) { ah->rledata[rlec++] = 0x00; ah->rledata[rlec++] = 0x00; @@ -293,16 +293,16 @@ static Uint32 rle_encode( struct avi_handle *ah, Uint8 *srcdata, Uint32 rlec, Ui srcc = 0; // Source count abspos = NOABS; - while( srcc < eol ) + while(srcc < eol) { // Look for a run thiscol = srcdata[srcc]; // At the last pixel? - if( srcc == eol-1 ) + if(srcc == eol-1) { // Need to dump an absolute section? - if( abspos != NOABS ) rlec = rle_putpixels( ah, srcdata, rlec, abspos, srcc-abspos ); + if(abspos != NOABS) rlec = rle_putpixels(ah, srcdata, rlec, abspos, srcc-abspos); // Just encode it ah->rledata[rlec++] = 0x01; @@ -314,17 +314,17 @@ static Uint32 rle_encode( struct avi_handle *ah, Uint8 *srcdata, Uint32 rlec, Ui } runc = 1; // Set the run count to 1 - while( srcdata[srcc+runc] == thiscol ) + while(srcdata[srcc+runc] == thiscol) { runc++; - if( (srcc+runc) >= eol ) break; + if((srcc+runc) >= eol) break; } // Need an absolute mode section? - if( runc < 2 ) + if(runc < 2) { // Starting a new absolute mode section? - if( abspos == NOABS ) abspos = srcc; + if(abspos == NOABS) abspos = srcc; // Next pixel! srcc++; @@ -332,16 +332,16 @@ static Uint32 rle_encode( struct avi_handle *ah, Uint8 *srcdata, Uint32 rlec, Ui } // Need to dump an absolute section? - if( abspos != NOABS ) + if(abspos != NOABS) { - rlec = rle_putpixels( ah, srcdata, rlec, abspos, srcc-abspos ); + rlec = rle_putpixels(ah, srcdata, rlec, abspos, srcc-abspos); abspos = NOABS; } // Encode that run! srcc += runc; // Skip past the run - while( runc > 255 ) // Do any 255 byte chunks until runc < 255 + while(runc > 255) // Do any 255 byte chunks until runc < 255 { chunker = (runc<258) ? 250 : 255; ah->rledata[rlec++] = chunker; @@ -353,76 +353,78 @@ static Uint32 rle_encode( struct avi_handle *ah, Uint8 *srcdata, Uint32 rlec, Ui ah->rledata[rlec++] = thiscol; } - if( abspos != NOABS ) rlec = rle_putpixels( ah, srcdata, rlec, abspos, srcc-abspos ); + if(abspos != NOABS) rlec = rle_putpixels(ah, srcdata, rlec, abspos, srcc-abspos); ah->rledata[rlec++] = 0x00; // The end! ah->rledata[rlec++] = 0x00; return rlec; } -SDL_bool avi_addframe( struct avi_handle **ah, Uint8 *srcdata ) +SDL_bool avi_addframe(struct avi_handle **ah, Uint8 *srcdata) { SDL_bool ok; Sint32 i, x, lastline, lastx; Uint32 size; lastline = 0; - if( (*ah)->lastframevalid ) + if((*ah)->lastframevalid) { // Find the last line that differs - for( i=0; i<224; i++ ) + for(i=0; i<224; i++) { - for( x=0; x<240; x++ ) + for(x=0; x<240; x++) { - if( (*ah)->lastframe[i*240+x] != srcdata[i*240+x] ) + if((*ah)->lastframe[i*240+x] != srcdata[i*240+x]) break; } - if( x<240 ) break; + if(x<240) break; } lastline = i; } - if( lastline == 224 ) + if(lastline == 224) { size = 0; (*ah)->rledata[size++] = 0x00; (*ah)->rledata[size++] = 0x01; - } else { - for( i=223,size=0; i>=lastline; i-- ) + } + else + { + for(i=223,size=0; i>=lastline; i--) { lastx = 240; - if( (*ah)->lastframevalid ) + if((*ah)->lastframevalid) { // Find the last pixel we need to encode - for( x=239; x>=0; x-- ) + for(x=239; x>=0; x--) { - if( (*ah)->lastframe[i*240+x] != srcdata[i*240+x] ) + if((*ah)->lastframe[i*240+x] != srcdata[i*240+x]) break; } lastx = x+1; } - size = rle_encode( *ah, &srcdata[i*240], size, lastx ); + size = rle_encode(*ah, &srcdata[i*240], size, lastx); } (*ah)->rledata[size-1] = 0x01; } - memcpy( (*ah)->lastframe, srcdata, 240*224 ); + memcpy((*ah)->lastframe, srcdata, 240*224); (*ah)->lastframevalid = SDL_TRUE; ok = SDL_TRUE; - ok &= writestr( ok, *ah, "00dc", NULL ); // Chunk header - ok &= write32l( ok, *ah, size, NULL ); // Chunk size - ok &= writeblk( ok, *ah, (*ah)->rledata, size ); // Chunk data + ok &= writestr(ok, *ah, "00dc", NULL); // Chunk header + ok &= write32l(ok, *ah, size, NULL); // Chunk size + ok &= writeblk(ok, *ah, (*ah)->rledata, size); // Chunk data (*ah)->movisize += size + 8; (*ah)->frames++; - if( !ok ) + if(!ok) { - avi_close( ah ); + avi_close(ah); return SDL_FALSE; } - if( !(*ah)->time_start ) + if(!(*ah)->time_start) { (*ah)->time_start = SDL_GetTicks(); } @@ -430,58 +432,58 @@ SDL_bool avi_addframe( struct avi_handle **ah, Uint8 *srcdata ) return SDL_TRUE; } -SDL_bool avi_addaudio( struct avi_handle **ah, Sint16 *audiodata, Uint32 audiosize ) +SDL_bool avi_addaudio(struct avi_handle **ah, Sint16 *audiodata, Uint32 audiosize) { SDL_bool ok; - if( !(*ah)->dosnd ) return SDL_TRUE; + if(!(*ah)->dosnd) return SDL_TRUE; ok = SDL_TRUE; - ok &= writestr( ok, *ah, "01wb", NULL ); // Chunk header - ok &= write32l( ok, *ah, audiosize, NULL ); // Chunk size - ok &= writeblk( ok, *ah, (Uint8 *)audiodata, audiosize ); // Chunk data + ok &= writestr(ok, *ah, "01wb", NULL); // Chunk header + ok &= write32l(ok, *ah, audiosize, NULL); // Chunk size + ok &= writeblk(ok, *ah, (Uint8 *)audiodata, audiosize); // Chunk data (*ah)->movisize += audiosize+8; (*ah)->audiolen += audiosize; - if( !ok ) + if(!ok) { - avi_close( ah ); + avi_close(ah); return SDL_FALSE; } return SDL_TRUE; } -void avi_close( struct avi_handle **ah ) +void avi_close(struct avi_handle **ah) { SDL_bool ok; Uint32 time_end = SDL_GetTicks(); double time_ms, rate, usperfrm; - if( ( !ah ) || (!(*ah)) ) return; + if((!ah) || (!(*ah))) return; - if( (*ah)->f ) + if((*ah)->f) { ok = SDL_TRUE; - ok &= seek_write32l( ok, *ah, (*ah)->offs_riffsize, (*ah)->csize-8 ); - ok &= seek_write32l( ok, *ah, (*ah)->offs_hdrlsize, (*ah)->hdrlsize ); - ok &= seek_write32l( ok, *ah, (*ah)->offs_frames, (*ah)->frames ); - ok &= seek_write32l( ok, *ah, (*ah)->offs_frames2, (*ah)->frames ); - ok &= seek_write32l( ok, *ah, (*ah)->offs_movisize, (*ah)->movisize ); - ok &= seek_write32l( ok, *ah, (*ah)->offs_audiolen, (*ah)->audiolen ); + ok &= seek_write32l(ok, *ah, (*ah)->offs_riffsize, (*ah)->csize-8); + ok &= seek_write32l(ok, *ah, (*ah)->offs_hdrlsize, (*ah)->hdrlsize); + ok &= seek_write32l(ok, *ah, (*ah)->offs_frames, (*ah)->frames); + ok &= seek_write32l(ok, *ah, (*ah)->offs_frames2, (*ah)->frames); + ok &= seek_write32l(ok, *ah, (*ah)->offs_movisize, (*ah)->movisize); + ok &= seek_write32l(ok, *ah, (*ah)->offs_audiolen, (*ah)->audiolen); time_ms = (double)(time_end - (*ah)->time_start); // Time in milliseconds rate = ((double)((*ah)->frames) * 1000000000.0f) / time_ms; - usperfrm = (time_ms*1000.0f) / ((double)(*ah)->frames); + usperfrm = (time_ms*1000.0f) / ((double)(*ah)->frames); - ok &= seek_write32l( ok, *ah, (*ah)->offs_frmrate, (Uint32)(rate + .5) ); - ok &= seek_write32l( ok, *ah, (*ah)->offs_usperfrm, (Uint32)(usperfrm + .5) ); + ok &= seek_write32l(ok, *ah, (*ah)->offs_frmrate, (Uint32)(rate + .5)); + ok &= seek_write32l(ok, *ah, (*ah)->offs_usperfrm, (Uint32)(usperfrm + .5)); - fclose( (*ah)->f ); + fclose((*ah)->f); } - free( (*ah) ); + free((*ah)); *ah = NULL; } diff --git a/avi.h b/avi.h index 9a5bf7ef..d907fc16 100644 --- a/avi.h +++ b/avi.h @@ -18,12 +18,12 @@ ** */ -#define AVIF_HASINDEX 0x00000010 -#define AVIF_MUSTUSEINDEX 0x00000020 -#define AVIF_ISINTERLEAVED 0x00000100 -#define AVIF_TRUSTCKTYPE 0x00000800 -#define AVIF_WASCAPTUREFILE 0x00010000 -#define AVIF_COPYRIGHTED 0x00020000 +#define AVIF_HASINDEX 0x00000010 +#define AVIF_MUSTUSEINDEX 0x00000020 +#define AVIF_ISINTERLEAVED 0x00000100 +#define AVIF_TRUSTCKTYPE 0x00000800 +#define AVIF_WASCAPTUREFILE 0x00010000 +#define AVIF_COPYRIGHTED 0x00020000 struct avi_handle { @@ -53,8 +53,8 @@ struct avi_handle int is50hz; }; -struct avi_handle *avi_open( char *filename, Uint8 *pal, SDL_bool dosound, int is50hz ); -SDL_bool avi_addframe( struct avi_handle **ah, Uint8 *srcdata ); -SDL_bool avi_addaudio( struct avi_handle **ah, Sint16 *audiodata, Uint32 audiosize ); -void avi_close( struct avi_handle **ah ); +struct avi_handle *avi_open(char* filename, Uint8 *pal, SDL_bool dosound, int is50hz); +SDL_bool avi_addframe(struct avi_handle **ah, Uint8 *srcdata); +SDL_bool avi_addaudio(struct avi_handle **ah, Sint16 *audiodata, Uint32 audiosize); +void avi_close(struct avi_handle **ah); diff --git a/configure b/configure old mode 100755 new mode 100644 diff --git a/disk.c b/disk.c index 26f7a427..82b4354a 100644 --- a/disk.c +++ b/disk.c @@ -47,6 +47,10 @@ #include "msgbox.h" #include "filereq.h" +#ifdef WWW +#include +#endif + extern char diskfile[], diskpath[], filetmp[]; extern char telediskfile[], telediskpath[]; extern char pravdiskfile[], pravdiskpath[]; @@ -61,10 +65,10 @@ static int sectordumpcount; #endif #ifdef MICRODISC_FUDGE -void microdisc_setintrq( void *md ); +void microdisc_setintrq(void* md); #endif -static Uint16 calc_crc( Uint16 crc, Uint8 value) +static Uint16 calc_crc(Uint16 crc, Uint8 value) { crc = ((unsigned char)(crc >> 8)) | (crc << 8); crc ^= value; @@ -75,29 +79,30 @@ static Uint16 calc_crc( Uint16 crc, Uint8 value) } // Pop up disk image information for a couple of seconds -void disk_popup( struct machine *oric, int drive ) +void disk_popup(struct machine *oric, int drive) { char tmp[40]; - if( !oric->diskname[drive][0] ) + if(!oric->diskname[drive][0]) { - do_popup( oric, "\x14\x15\x13" ); + do_popup(oric, "\x14\x15\x13"); return; } - sprintf( tmp, "\x14\x15""%d %-16s", drive, oric->diskname[drive] ); - do_popup( oric, tmp ); + sprintf(tmp, "\x14\x15""%d %-16s", drive, oric->diskname[drive]); + do_popup(oric, tmp); } // Free a disk image and clear the pointer to it -void diskimage_free( struct machine *oric, struct diskimage **dimg ) +static void diskimage_free(struct machine *oric, struct diskimage **dimg) { - char *dpath, *dfile; + char* dpath, *dfile; - if( !(*dimg) ) return; + if(!dimg) return; + if(!(*dimg)) return; - if( oric->type != MACH_TELESTRAT ) + if(oric->type != MACH_TELESTRAT) { - switch (oric->drivetype) + switch(oric->drivetype) { case DRV_PRAVETZ: dpath = pravdiskpath; @@ -109,104 +114,163 @@ void diskimage_free( struct machine *oric, struct diskimage **dimg ) dfile = diskfile; break; } - } else { + } + else + { dpath = telediskpath; dfile = telediskfile; } - if( (*dimg)->modified ) + if((*dimg)->modified) { char modmsg[128]; - sprintf( modmsg, "The disk in drive %d is modified.\nWould you like to save the changes?", (*dimg)->drivenum ); - if( msgbox( oric, MSGBOX_YES_NO, modmsg ) ) + sprintf(modmsg, "The disk in drive %d is modified.\nWould you like to save the changes?", (*dimg)->drivenum); + if(msgbox(oric, MSGBOX_YES_NO, modmsg)) { - sprintf( modmsg, "Save disk %d", (*dimg)->drivenum ); - if( filerequester( oric, modmsg, dpath, dfile, FR_DISKSAVE ) ) + sprintf(modmsg, "Save disk %d", (*dimg)->drivenum); + if(filerequester(oric, modmsg, dpath, dfile, FR_DISKSAVE)) { - joinpath( dpath, dfile ); - diskimage_save( oric, filetmp, (*dimg)->drivenum ); + joinpath(dpath, dfile); + diskimage_save(oric, filetmp, (*dimg)->drivenum); } } } - if( (*dimg)->rawimage ) free( (*dimg)->rawimage ); - free( *dimg ); - (*dimg) = NULL; + if((*dimg)->rawimage) + { + free((*dimg)->rawimage); + (*dimg)->rawimage = NULL; + } + + free(*dimg); + *dimg = NULL; +} + +static inline char diskimage_check(struct diskimage* dimg, Uint32 offset) +{ + if(!dimg) return 0; + if(!dimg->rawimage) return 0; + if(dimg->rawimagelen < 4) return 0; + if((dimg->rawimagelen - 4) < offset) return 0; + + return 1; } // Read a raw integer from a disk image file -Uint32 diskimage_rawint( struct diskimage *dimg, Uint32 offset ) +static Uint32 diskimage_get_rawint(struct diskimage* dimg, Uint32 offset) { - if( !dimg ) return 0; - if( ( !dimg->rawimage ) || ( dimg->rawimagelen < 4 ) ) return 0; - if( offset > (dimg->rawimagelen-4) ) return 0; + Uint32 val = 0; + if(diskimage_check(dimg,offset)) + { + val |= dimg->rawimage[offset+3]<<24; + val |= dimg->rawimage[offset+2]<<16; + val |= dimg->rawimage[offset+1]<<8; + val |= dimg->rawimage[offset]; + } + return val; +} - return (dimg->rawimage[offset+3]<<24)|(dimg->rawimage[offset+2]<<16)|(dimg->rawimage[offset+1]<<8)|dimg->rawimage[offset]; +static void diskimage_set_rawint(struct diskimage* dimg, Uint32 offset, Uint32 val) +{ + if(diskimage_check(dimg, offset)) + { + dimg->rawimage[offset] = val & 0xff; + val >>= 8; + dimg->rawimage[offset+1] = val & 0xff; + val >>= 8; + dimg->rawimage[offset+2] = val & 0xff; + val >>= 8; + dimg->rawimage[offset+3] = val & 0xff; + } } // Allocate and initialise a disk image structure // If "rawimglen" isn't zero, it will also allocate // ram for a raw disk image -struct diskimage *diskimage_alloc( Uint32 rawimglen ) +static struct diskimage *diskimage_alloc(int drivetype, Uint32 rawimglen) { - struct diskimage *dimg; - Uint8 *buf=NULL; + struct diskimage *dimg = NULL; - if( rawimglen ) + if(0 < rawimglen) { - buf = malloc( rawimglen ); - if( !buf ) return NULL; + Uint8 *buf = NULL; + + if(DRV_PRAVETZ != drivetype) + rawimglen = 256+2*128*6400; + + buf = malloc(rawimglen); + if(!buf) return NULL; + + dimg = malloc(sizeof(struct diskimage)); + if(!dimg) + { + free(buf); + return NULL; + } + + dimg->drivenum = -1; + dimg->numsides = 0; + dimg->numtracks = 0; + dimg->numsides_in = 0; + dimg->numtracks_in = 0; + dimg->numsides_out = 0; + dimg->numtracks_out = 0; + dimg->geometry = 0; + dimg->cachedtrack = -1; + dimg->cachedside = -1; + dimg->numsectors = 0; + dimg->rawimage = buf; + dimg->rawimagelen = rawimglen; + dimg->modified = SDL_FALSE; + dimg->modified_time = 0; } + return dimg; +} - dimg = malloc( sizeof( struct diskimage ) ); - if( !dimg ) +static void diskimage_set_modified(struct diskimage* dimg, uint8_t side, uint8_t track) +{ + if(dimg) { - free( buf ); - return NULL; + dimg->modified = SDL_TRUE; + dimg->modified_time = 0; + side++; + if(dimg->numsides_out < side) + dimg->numsides_out = side; + track++; + if(dimg->numtracks_out < track) + dimg->numtracks_out = track; } - - dimg->drivenum = -1; - dimg->numtracks = 0; - dimg->numsides = 0; - dimg->geometry = 0; - dimg->cachedtrack = -1; - dimg->cachedside = -1; - dimg->numsectors = 0; - dimg->rawimage = buf; - dimg->rawimagelen = rawimglen; - dimg->modified = SDL_FALSE; - dimg->modified_time = 0; - return dimg; } // Eject a disk from a drive -void disk_eject( struct machine *oric, int drive ) +void disk_eject(struct machine *oric, int drive) { - diskimage_free( oric, &oric->wddisk.disk[drive] ); + diskimage_free(oric, &oric->wddisk.disk[drive]); + oric->wddisk.disk[drive] = NULL; oric->pravetz.drv[drive].pimg = NULL; oric->pravetz.drv[drive].byte = 0; oric->pravetz.drv[drive].dirty = SDL_FALSE; oric->pravetz.drv[drive].half_track = 0; oric->diskname[drive][0] = 0; - disk_popup( oric, drive ); + disk_popup(oric, drive); } // Whenever a seek operation occurs, the track where the head ends up // is "cached". The track is located within the raw image file, and // all the sector address and data markers are found, and pointers // are remembered for each. -void diskimage_cachetrack( struct diskimage *dimg, int track, int side ) +void diskimage_cachetrack(struct diskimage *dimg, int track, int side) { Uint8 *ptr, *eot; Uint32 sectorcount, n; // If this track is already cached, don't waste time doing it again - if( ( dimg->cachedtrack == track ) && - ( dimg->cachedside == side ) ) + if((dimg->cachedtrack == track) && + (dimg->cachedside == side)) return; // reset cached info - for( n=0; n<32; n++ ) + for(n=0; n<32; n++) { dimg->sector[n].id_ptr = NULL; dimg->sector[n].data_ptr = NULL; @@ -215,7 +279,7 @@ void diskimage_cachetrack( struct diskimage *dimg, int track, int side ) dimg->cachedtrack = -1; dimg->cachedside = -1; - if( side >= dimg->numsides ) + if(side >= dimg->numsides) return; // Find the start and end locations of the track within the disk image @@ -224,13 +288,14 @@ void diskimage_cachetrack( struct diskimage *dimg, int track, int side ) // Scan through the track looking for sectors sectorcount = 0; - while( ptr < eot ) + while(ptr < eot) { // Search for ID mark - while( (ptr= eot ) break; + if(ptr >= eot) break; // Store ID pointer dimg->sector[sectorcount].id_ptr = ptr; @@ -244,8 +309,8 @@ void diskimage_cachetrack( struct diskimage *dimg, int track, int side ) ptr+=7; // Search for data ID - while( (ptr= eot ) break; + while((ptr= eot) break; // Store pointer dimg->sector[sectorcount-1].data_ptr = ptr; @@ -254,7 +319,7 @@ void diskimage_cachetrack( struct diskimage *dimg, int track, int side ) ptr += (1<<(n+7))+3; } - if( 0 < sectorcount ) + if(0 < sectorcount) { // Remember how many sectors we have successfully cached dimg->numsectors = sectorcount; @@ -267,45 +332,80 @@ void diskimage_cachetrack( struct diskimage *dimg, int track, int side ) // Since the disk image is always kept in standard format, there is // no processing of the image in this routine, it is just dumped from // memory back to disk. -SDL_bool diskimage_save( struct machine *oric, char *fname, int drive ) +SDL_bool diskimage_save(struct machine *oric, char* fname, int drive) { - FILE *f; + struct diskimage* dimg = oric->wddisk.disk[drive]; // Make sure there is a disk in the drive! - if( !oric->wddisk.disk[drive] ) return SDL_FALSE; - - if( oric->drivetype == DRV_PRAVETZ ) - disk_pravetz_write_image(&oric->pravetz.drv[drive]); + if(!dimg) return SDL_FALSE; - // Open the file for writing - f = fopen( fname, "wb" ); - if( !f ) + if(oric->drivetype == DRV_PRAVETZ) { - do_popup( oric, "\x14\x15Save failed" ); - return SDL_FALSE; + disk_pravetz_write_image(&oric->pravetz.drv[drive]); } - - // Dump it to disk - if( fwrite( oric->wddisk.disk[drive]->rawimage, oric->wddisk.disk[drive]->rawimagelen, 1, f ) != 1 ) + else { - fclose( f ); - do_popup( oric, "\x14\x15Save failed" ); - return SDL_FALSE; - } + int sidesize = 0; + // Open the file for writing + FILE *f = fopen(fname, "wb"); + if(!f) + { + do_popup(oric, "\x14\x15Save failed"); + return SDL_FALSE; + } - // All done! - fclose( f ); + // Dump it to disk + if(dimg->numsides_in < dimg->numsides_out) + dimg->numsides_in = dimg->numsides_out; + if(dimg->numtracks_in < dimg->numtracks_out) + dimg->numtracks_in = dimg->numtracks_out; - // If we are not just overwriting the original file, remember the new filename - if( fname != oric->wddisk.disk[drive]->filename ) - { - strncpy( oric->wddisk.disk[drive]->filename, fname, 4096+512 ); - oric->wddisk.disk[drive]->filename[4096+511] = 0; + diskimage_set_rawint(dimg, 8, oric->wddisk.disk[drive]->numsides_in); + diskimage_set_rawint(dimg, 12, oric->wddisk.disk[drive]->numtracks_in); + + sidesize = oric->wddisk.disk[drive]->numtracks_in*6400; + + if(fwrite(dimg->rawimage, 256+sidesize, 1, f) != 1) + { + fclose(f); + do_popup(oric, "\x14\x15Save failed"); + return SDL_FALSE; + } + + if(1 < dimg->numsides_in) + { + if(fwrite(dimg->rawimage+256+128*6400, sidesize, 1, f) != 1) + { + fclose(f); + do_popup(oric, "\x14\x15Save failed"); + return SDL_FALSE; + } + } + + // All done! + fclose(f); + + // If we are not just overwriting the original file, remember the new filename + if(fname != dimg->filename) + { + strncpy(dimg->filename, fname, 4096+512-1); + dimg->filename[4096+512-1] = 0; + } } // The image in memory is no longer different to the last saved version - oric->wddisk.disk[drive]->modified = SDL_FALSE; - oric->wddisk.disk[drive]->modified_time = 0; + dimg->modified = SDL_FALSE; + dimg->modified_time = 0; + +#ifdef WWW + // sync from memory state to persisted + EM_ASM( + FS.syncfs(function(err) + { + assert(!err); + }); + ); +#endif // Remember to update the GUI refreshdisks = SDL_TRUE; @@ -313,121 +413,154 @@ SDL_bool diskimage_save( struct machine *oric, char *fname, int drive ) } // This routine "inserts" a disk image into a virtual drive -SDL_bool diskimage_load( struct machine *oric, char *fname, int drive ) +SDL_bool diskimage_load(struct machine *oric, char* fname, int drive) { FILE *f; Uint32 len; // Open the file - f = fopen( fname, "rb" ); - if( !f ) return SDL_FALSE; + f = fopen(fname, "rb"); + if(!f) return SDL_FALSE; // The file exists, so eject any currently inserted disk - disk_eject( oric, drive ); + disk_eject(oric, drive); // Determine the size of the disk image - fseek( f, 0, SEEK_END ); - len = (int)ftell( f ); - fseek( f, 0, SEEK_SET ); + fseek(f, 0, SEEK_END); + len = (int)ftell(f); + fseek(f, 0, SEEK_SET); // Empty file!? - if( len <= 0 ) + if(len <= 0) { - fclose( f ); + fclose(f); return SDL_FALSE; } // Allocate a new disk image structure and space for the raw image - oric->wddisk.disk[drive] = diskimage_alloc( len ); - if( !oric->wddisk.disk[drive] ) + oric->wddisk.disk[drive] = diskimage_alloc(oric->drivetype, len); + if(!oric->wddisk.disk[drive]) { - do_popup( oric, "\x14\x15""Out of memory" ); - fclose( f ); + do_popup(oric, "\x14\x15""Out of memory"); + fclose(f); return SDL_FALSE; } // Read the image file into memory - if( fread( oric->wddisk.disk[drive]->rawimage, len, 1, f ) != 1 ) + if(fread(oric->wddisk.disk[drive]->rawimage, len, 1, f) != 1) { - fclose( f ); - disk_eject( oric, drive ); - do_popup( oric, "\x14\x15""Read error" ); + fclose(f); + disk_eject(oric, drive); + do_popup(oric, "\x14\x15""Read error"); return SDL_FALSE; } - fclose( f ); + fclose(f); - if( oric->drivetype == DRV_PRAVETZ ) + if(oric->drivetype == DRV_PRAVETZ) { Uint16 t_idx; Uint16 s_idx; Uint16 sb_idx; Uint16 tb_idx; + oric->wddisk.disk[drive]->drivenum = drive; oric->pravetz.drv[drive].pimg = oric->wddisk.disk[drive]; - if( drive >= 2 ) + if(drive >= 2) { - disk_eject( oric, drive ); - do_popup( oric, "\x14\x15""Invalid drive number" ); + disk_eject(oric, drive); + do_popup(oric, "\x14\x15""Invalid drive number"); return SDL_FALSE; } - if( len != 143360 ) + if(len != 143360) { - disk_eject( oric, drive ); - do_popup( oric, "\x14\x15""Invalid pravetz disk image" ); + disk_eject(oric, drive); + do_popup(oric, "\x14\x15""Invalid pravetz disk image"); return SDL_FALSE; } // Get some basic image info - for (t_idx = 0; t_idx < PRAV_TRACKS_PER_DISK; t_idx++) + for(t_idx = 0; t_idx < PRAV_TRACKS_PER_DISK; t_idx++) { tb_idx = 0; - for (s_idx = 0; s_idx < PRAV_SECTORS_PER_TRACK; s_idx++) + for(s_idx = 0; s_idx < PRAV_SECTORS_PER_TRACK; s_idx++) { - for (sb_idx = 0; sb_idx < PRAV_RAW_BYTES_PER_SECTOR; sb_idx++, tb_idx++) + for(sb_idx = 0; sb_idx < PRAV_RAW_BYTES_PER_SECTOR; sb_idx++, tb_idx++) { oric->pravetz.drv[drive].image[t_idx][tb_idx] = disk_pravetz_image_raw_byte(oric, drive, t_idx, s_idx, sb_idx); } } - while (tb_idx < PRAV_RAW_TRACK_SIZE) + while(tb_idx < PRAV_RAW_TRACK_SIZE) { oric->pravetz.drv[drive].image[t_idx][tb_idx] = 0xFF; tb_idx++; } } - oric->pravetz.drv[drive].byte = 0; + oric->pravetz.drv[drive].byte = 0; oric->pravetz.drv[drive].half_track = 0; } else { // Check for the header ID - if( strncmp( (char *)oric->wddisk.disk[drive]->rawimage, "MFM_DISK", 8 ) != 0 ) + if(strncmp((char*)oric->wddisk.disk[drive]->rawimage, "MFM_DISK", 8) != 0) { - disk_eject( oric, drive ); - do_popup( oric, "\x14\x15""Invalid disk image" ); + disk_eject(oric, drive); + do_popup(oric, "\x14\x15""Invalid disk image"); return SDL_FALSE; } // Get some basic image info oric->wddisk.disk[drive]->drivenum = drive; - oric->wddisk.disk[drive]->numsides = diskimage_rawint( oric->wddisk.disk[drive], 8 ); - oric->wddisk.disk[drive]->numtracks = diskimage_rawint( oric->wddisk.disk[drive], 12 ); - oric->wddisk.disk[drive]->geometry = diskimage_rawint( oric->wddisk.disk[drive], 16 ); + oric->wddisk.disk[drive]->numsides_in = diskimage_get_rawint(oric->wddisk.disk[drive], 8); + oric->wddisk.disk[drive]->numtracks_in = diskimage_get_rawint(oric->wddisk.disk[drive], 12); + oric->wddisk.disk[drive]->geometry = diskimage_get_rawint(oric->wddisk.disk[drive], 16); // Is the disk sane!? - if( ( oric->wddisk.disk[drive]->numsides < 1 ) || - ( oric->wddisk.disk[drive]->numsides > 2 ) ) + if(1 != oric->wddisk.disk[drive]->geometry) { - disk_eject( oric, drive ); - do_popup( oric, "\x14\x15""Invalid disk image" ); + disk_eject(oric, drive); + do_popup(oric, "\x14\x15""Unsupported disk image geometry"); return SDL_FALSE; } + + if((oric->wddisk.disk[drive]->numsides_in < 1) || + (oric->wddisk.disk[drive]->numsides_in > 2)) + { + disk_eject(oric, drive); + do_popup(oric, "\x14\x15""Invalid disk image"); + return SDL_FALSE; + } + + if(oric->wddisk.disk[drive]->numtracks_in > 128) + { + disk_eject(oric, drive); + do_popup(oric, "\x14\x15""Invalid disk image"); + return SDL_FALSE; + } + + oric->wddisk.disk[drive]->numsides = 2; + oric->wddisk.disk[drive]->numtracks = 128; + + if(1 < oric->wddisk.disk[drive]->numsides_in) + { + if(oric->wddisk.disk[drive]->numtracks_in < 128) + { + // Reallocate side 2 + int size = oric->wddisk.disk[drive]->numtracks_in*6400; + uint8_t* src = oric->wddisk.disk[drive]->rawimage + 256+size; + uint8_t* dst = oric->wddisk.disk[drive]->rawimage + 256+128*6400; + memmove(dst,src,size); + // Clear the reallocated space + // NOTE: Cleared space is unformatted + memset(src,0x00,dst-src); + } + } } // Nobody has written to this disk yet @@ -435,21 +568,23 @@ SDL_bool diskimage_load( struct machine *oric, char *fname, int drive ) oric->wddisk.disk[drive]->modified_time = 0; // Remember the filename of the image for this drive - strncpy( oric->wddisk.disk[drive]->filename, fname, 4096+512 ); - oric->wddisk.disk[drive]->filename[4096+511] = 0; + strncpy(oric->wddisk.disk[drive]->filename, fname, 4096+512-1); + oric->wddisk.disk[drive]->filename[4096+512-1] = 0; // Come up with a suitable short name for popups etc. - if( strlen( fname ) > 31 ) + if(strlen(fname) > 31) { - strncpy( oric->diskname[drive], &fname[strlen(fname)-31], 32 ); + strncpy(oric->diskname[drive], &fname[strlen(fname)-31], 32); oric->diskname[drive][0] = 22; - } else { - strncpy( oric->diskname[drive], fname, 32 ); + } + else + { + strncpy(oric->diskname[drive], fname, 32); } oric->diskname[drive][31] = 0; // Do the popup - disk_popup( oric, drive ); + disk_popup(oric, drive); // Mark the disk status icons as needing a refresh refreshdisks = SDL_TRUE; @@ -458,12 +593,12 @@ SDL_bool diskimage_load( struct machine *oric, char *fname, int drive ) // This routine does nothing. It is just used as a default for the callback routines // and is usually replaced by the microdisc/jasmin/whatever implementations. -void wd17xx_dummy( void *nothing ) +void wd17xx_dummy(void* nothing) { } // Initialise a WD17xx controller instance -void wd17xx_init( struct wd17xx *wd ) +void wd17xx_init(struct wd17xx *wd) { wd->r_status = 0; wd->r_track = 0; @@ -489,25 +624,25 @@ void wd17xx_init( struct wd17xx *wd ) } // This routine emulates some cycles of disk activity. -void wd17xx_ticktock( struct wd17xx *wd, int cycles ) +void wd17xx_ticktock(struct wd17xx *wd, int cycles) { #ifdef MICRODISC_FUDGE - if ((wd->currentop == COP_READ_SECTORS_FUDGE) || + if((wd->currentop == COP_READ_SECTORS_FUDGE) || (wd->currentop == COP_READ_SECTOR_FUDGE)) { - if (wd->disk[wd->c_drive]) + if(wd->disk[wd->c_drive]) { wd->curroffs = 0; - wd->currsector = wd17xx_find_sector( wd, wd->r_sector ); - if( !wd->currsector ) + wd->currsector = wd17xx_find_sector(wd, wd->r_sector); + if(!wd->currsector) { wd->r_status = WSF_RNF; - wd->clrdrq( wd->drqarg ); - wd->setintrq( wd->intrqarg ); + wd->clrdrq(wd->drqarg); + wd->setintrq(wd->intrqarg); wd->currentop = COP_NUFFINK; refreshdisks = SDL_TRUE; #if GENERAL_DISK_DEBUG - dbg_printf( "DISK: Sector %d not found.", wd->r_sector ); + dbg_printf("DISK: Sector %d not found.", wd->r_sector); #endif } else @@ -528,19 +663,19 @@ void wd17xx_ticktock( struct wd17xx *wd, int cycles ) #endif // Is there a pending INTRQ? - if( wd->delayedint > 0 ) + if(wd->delayedint > 0) { // Count down the INTRQ timer! wd->delayedint -= cycles; // Time to assert INTRQ? - if( wd->delayedint <= 0 ) + if(wd->delayedint <= 0) { // Yep! Stop timing. wd->delayedint = 0; // Need to update the status register? - if( wd->distatus != -1 ) + if(wd->distatus != -1) { // Yep. Do so. wd->r_status = wd->distatus; @@ -548,27 +683,27 @@ void wd17xx_ticktock( struct wd17xx *wd, int cycles ) } // Assert INTRQ (this function pointer is set up by the microdisc/jasmin/whatever controller) - wd->setintrq( wd->intrqarg ); + wd->setintrq(wd->intrqarg); #if GENERAL_DISK_DEBUG - dbg_printf( "DISK: Delayed INTRQ" ); + dbg_printf("DISK: Delayed INTRQ"); #endif } } // Is there a pending DRQ? - if( wd->delayeddrq > 0 ) + if(wd->delayeddrq > 0) { // Count down the DRQ timer! wd->delayeddrq -= cycles; // Time to assert DRQ? - if( wd->delayeddrq <= 0 ) + if(wd->delayeddrq <= 0) { // Yep! Stop timing. wd->delayeddrq = 0; // Need to update the status register? - if( wd->ddstatus != -1 ) + if(wd->ddstatus != -1) { // Yep. Do so. wd->r_status = wd->ddstatus; @@ -577,19 +712,19 @@ void wd17xx_ticktock( struct wd17xx *wd, int cycles ) // Assert DRQ wd->r_status |= WSF_DRQ; - wd->setdrq( wd->drqarg ); + wd->setdrq(wd->drqarg); } } } // This routine seeks to the specified track. It is used by the SEEK and STEP commands. -void wd17xx_seek_track( struct wd17xx *wd, Uint8 track, SDL_bool dofudge ) +void wd17xx_seek_track(struct wd17xx *wd, Uint8 track, SDL_bool dofudge) { // Is there a disk in the drive? - if( wd->disk[wd->c_drive] ) + if(wd->disk[wd->c_drive]) { - // Yes. If we are trying to seek to a non-existant track, just seek as far as we can - if( track >= wd->disk[wd->c_drive]->numtracks ) + // Yes. If we are trying to seek to a non-existent track, just seek as far as we can + if(track >= wd->disk[wd->c_drive]->numtracks) { track = (wd->disk[wd->c_drive]->numtracks>0)?wd->disk[wd->c_drive]->numtracks-1:0; wd->distatus = WSFI_HEADL|WSFI_SEEKERR; @@ -600,7 +735,7 @@ void wd17xx_seek_track( struct wd17xx *wd, Uint8 track, SDL_bool dofudge ) } // Cache the new track - diskimage_cachetrack( wd->disk[wd->c_drive], track, wd->c_side ); + diskimage_cachetrack(wd->disk[wd->c_drive], track, wd->c_side); // Update our status wd->c_track = track; @@ -612,28 +747,28 @@ void wd17xx_seek_track( struct wd17xx *wd, Uint8 track, SDL_bool dofudge ) // delay would depend how far the head had to seek, and what stepping speed was // currently set). wd->delayedint = 20; - if( wd->c_track == 0 ) wd->distatus |= WSFI_TRK0; + if(wd->c_track == 0) wd->distatus |= WSFI_TRK0; #if GENERAL_DISK_DEBUG - dbg_printf( "DISK: At track %u (%u sectors)", track, wd->disk[wd->c_drive]->numsectors ); + dbg_printf("DISK: At track %u (%u sectors)", track, wd->disk[wd->c_drive]->numsectors); #endif return; } // No disk in drive // Set INTRQ because the operation has finished. - wd->setintrq( wd->intrqarg ); + wd->setintrq(wd->intrqarg); wd->r_track = 0; #if GENERAL_DISK_DEBUG - dbg_printf( "DISK: Seek fail" ); + dbg_printf("DISK: Seek fail"); #endif #ifdef MICRODISC_FUDGE // Euphoric style workaround for the sedoric bug... - if ((dofudge) && (wd->setintrq == microdisc_setintrq)) + if((dofudge) && (wd->setintrq == microdisc_setintrq)) { - wd->r_status = 0x44; - return; + wd->r_status = 0x44; + return; } #endif @@ -644,7 +779,7 @@ void wd17xx_seek_track( struct wd17xx *wd, Uint8 track, SDL_bool dofudge ) // This routine looks for the sector with the specified ID in the current track. // It returns NULL if there is no such sector, or a structure with pointers to // the ID and data fields if the sector is found. -struct mfmsector *wd17xx_find_sector( struct wd17xx *wd, Uint8 secid ) +struct mfmsector *wd17xx_find_sector(struct wd17xx *wd, Uint8 secid) { int revs=0; struct diskimage *dimg; @@ -653,58 +788,58 @@ struct mfmsector *wd17xx_find_sector( struct wd17xx *wd, Uint8 secid ) dimg = wd->disk[wd->c_drive]; // No disk image? No sectors! - if( !dimg ) return NULL; + if(!dimg) return NULL; // Make sure the current track is cached - diskimage_cachetrack( dimg, wd->c_track, wd->c_side ); + diskimage_cachetrack(dimg, wd->c_track, wd->c_side); // No sectors on this track? Someone needs to format their disk... - if( dimg->numsectors < 1 ) + if(dimg->numsectors < 1) return NULL; // We do this more realistically than we need to since this is not // a super-accurate emulation (for now). Never mind. Lets go // around the track up to two times. - while( revs < 2 ) + while(revs < 2) { // Move on to the next sector wd->c_sector = (wd->c_sector+1)%dimg->numsectors; // If we passed through the start of the track, set the pulse bit in the status register - if( !wd->c_sector ) + if(!wd->c_sector) { revs++; wd->r_status |= WSFI_PULSE; } // Found the required sector? - if( dimg->sector[wd->c_sector].id_ptr[3] == secid ) + if(dimg->sector[wd->c_sector].id_ptr[3] == secid) return &dimg->sector[wd->c_sector]; } // The search failed :-( #if GENERAL_DISK_DEBUG - dbg_printf( "Couldn't find sector %u", secid ); + dbg_printf("Couldn't find sector %u", secid); #endif return NULL; } // This returns the first valid sector in the current track, or NULL if // there aren't any sectors. -struct mfmsector *wd17xx_first_sector( struct wd17xx *wd ) +struct mfmsector *wd17xx_first_sector(struct wd17xx *wd) { struct diskimage *dimg; dimg = wd->disk[wd->c_drive]; // No disk? no sector... - if( !dimg ) return NULL; + if(!dimg) return NULL; // Make sure the current track is cached - diskimage_cachetrack( dimg, wd->c_track, wd->c_side ); + diskimage_cachetrack(dimg, wd->c_track, wd->c_side); // No sectors?! - if( dimg->numsectors < 1 ) + if(dimg->numsectors < 1) return NULL; // We're at the first sector! @@ -716,40 +851,40 @@ struct mfmsector *wd17xx_first_sector( struct wd17xx *wd ) } // Move on to the next sector -struct mfmsector *wd17xx_next_sector( struct wd17xx *wd ) +struct mfmsector *wd17xx_next_sector(struct wd17xx *wd) { struct diskimage *dimg; dimg = wd->disk[wd->c_drive]; // No disk? No sectors! - if( !dimg ) return NULL; + if(!dimg) return NULL; // Make sure the current track is cached - diskimage_cachetrack( dimg, wd->c_track, wd->c_side ); + diskimage_cachetrack(dimg, wd->c_track, wd->c_side); // No sectors? - if( dimg->numsectors < 1 ) + if(dimg->numsectors < 1) return NULL; // Get the next sector number wd->c_sector = (wd->c_sector+1)%dimg->numsectors; // If we are at the start of the track, set the pulse bit - if( !wd->c_sector ) wd->r_status |= WSFI_PULSE; + if(!wd->c_sector) wd->r_status |= WSFI_PULSE; // Return the sector pointers return &dimg->sector[wd->c_sector]; } // Perform a read operation on a WD17xx register -unsigned char wd17xx_read( struct wd17xx *wd, unsigned short addr ) +unsigned char wd17xx_read(struct wd17xx *wd, unsigned short addr) { // Which register?! - switch( addr ) + switch(addr) { case 0: // Status register - wd->clrintrq( wd->intrqarg ); // Reading the status register clears INTRQ + wd->clrintrq(wd->intrqarg); // Reading the status register clears INTRQ return wd->r_status; case 1: // Track register @@ -760,7 +895,7 @@ unsigned char wd17xx_read( struct wd17xx *wd, unsigned short addr ) case 3: // Data register // What are we currently doing? - switch( wd->currentop ) + switch(wd->currentop) { #ifdef MICRODISC_FUDGE case COP_READ_SECTOR_FUDGE: @@ -771,82 +906,82 @@ unsigned char wd17xx_read( struct wd17xx *wd, unsigned short addr ) case COP_READ_SECTOR: case COP_READ_SECTORS: // We somehow started a sector read operation without a valid sector. - if( !wd->currsector ) + if(!wd->currsector) { // Abort. wd->r_status &= ~WSF_DRQ; wd->r_status |= WSF_RNF; - wd->clrdrq( wd->drqarg ); + wd->clrdrq(wd->drqarg); wd->currentop = COP_NUFFINK; refreshdisks = SDL_TRUE; break; } // If this is the first read of a read operation, remember the record type for later - if( wd->curroffs == 0 ) wd->sectype = (wd->currsector->data_ptr[wd->curroffs++]==0xf8)?WSFR_RECTYP:0x00; + if(wd->curroffs == 0) wd->sectype = (wd->currsector->data_ptr[wd->curroffs++]==0xf8)?WSFR_RECTYP:0x00; // Get the next byte from the sector wd->r_data = wd->currsector->data_ptr[wd->curroffs++]; - wd->crc = calc_crc( wd->crc, wd->r_data ); + wd->crc = calc_crc(wd->crc, wd->r_data); // Clear any previous DRQ wd->r_status &= ~WSF_DRQ; - wd->clrdrq( wd->drqarg ); + wd->clrdrq(wd->drqarg); #if DEBUG_SECTOR_DUMP - sprintf( §ordumpstr[sectordumpcount*2], "%02X", wd->r_data ); + sprintf(§ordumpstr[sectordumpcount*2], "%02X", wd->r_data); sectordumpstr[34+sectordumpcount] = ((wd->r_data>31)&&(wd->r_data<127)) ? wd->r_data : '.'; sectordumpcount++; - if( sectordumpcount >= 16 ) + if(sectordumpcount >= 16) { sectordumpstr[32] = ' '; sectordumpstr[33] = '\''; sectordumpstr[50] = '\''; sectordumpstr[51] = 0; - dbg_printf( "%s", sectordumpstr ); + dbg_printf("%s", sectordumpstr); sectordumpcount = 0; } #endif // Has the whole sector been read? - if( wd->curroffs > wd->currseclen ) + if(wd->curroffs > wd->currseclen) { // If you want to do CRC checking, wd->crc should equal (wd->currsector->data_ptr[wd_curroffs]<<8)|wd->currsector->data_ptr[wd_curroffs+1] right here #if DEBUG_SECTOR_DUMP - if( sectordumpcount ) + if(sectordumpcount) { sectordumpstr[33] = '\''; sectordumpstr[34+sectordumpcount] = '\''; sectordumpstr[35+sectordumpcount] = 0; - for( sectordumpcount*=2; sectordumpcount<33; sectordumpcount++ ) + for(sectordumpcount*=2; sectordumpcount<33; sectordumpcount++) sectordumpstr[sectordumpcount*2] = ' '; - dbg_printf( "%s", sectordumpstr ); + dbg_printf("%s", sectordumpstr); sectordumpcount = 0; } #endif // We've got to the end of the current sector. IF it is a multiple sector // operation, we need to move on! - if( wd->currentop == COP_READ_SECTORS ) + if(wd->currentop == COP_READ_SECTORS) { #if GENERAL_DISK_DEBUG - dbg_printf( "Next sector..." ); + dbg_printf("Next sector..."); #endif // Get the next sector, and carry on! wd->r_sector++; wd->curroffs = 0; - wd->currsector = wd17xx_find_sector( wd, wd->r_sector ); + wd->currsector = wd17xx_find_sector(wd, wd->r_sector); wd->crc = 0xe295; - // If we hit the end of the track, thats fine, it just means the operation + // If we hit the end of the track, that's fine, it just means the operation // is finished. - if( !wd->currsector ) + if(!wd->currsector) { wd->delayedint = 20; // Assert INTRQ in 20 cycles time wd->distatus = wd->sectype; // ...and when doing so, set the status to reflect the record type wd->currentop = COP_NUFFINK; // No longer in the middle of an operation wd->r_status &= (~WSF_DRQ); // Clear DRQ (no data to read) - wd->clrdrq( wd->drqarg ); + wd->clrdrq(wd->drqarg); refreshdisks = SDL_TRUE; // Turn off the disk LED in the status bar break; } @@ -863,9 +998,11 @@ unsigned char wd17xx_read( struct wd17xx *wd, unsigned short addr ) wd->distatus = wd->sectype; // Set the status accordingly wd->currentop = COP_NUFFINK; // Finished the op wd->r_status &= (~WSF_DRQ); // Clear DRQ (no more data) - wd->clrdrq( wd->drqarg ); + wd->clrdrq(wd->drqarg); refreshdisks = SDL_TRUE; // Turn off disk LED - } else { + } + else + { wd->delayeddrq = 32; // More data ready. DRQ to let them know! } break; @@ -875,41 +1012,45 @@ unsigned char wd17xx_read( struct wd17xx *wd, unsigned short addr ) wd->r_data = wd->disk[wd->c_drive]->rawimage[(wd->c_side*wd->disk[wd->c_drive]->numtracks + wd->c_track)*6400+256 + wd->curroffs]; wd->curroffs++; wd->r_status &= ~WSF_DRQ; - wd->clrdrq( wd->drqarg ); + wd->clrdrq(wd->drqarg); // Has the whole track been read? - if( wd->curroffs >= 6400 ) + if(wd->curroffs >= 6400) { wd->delayedint = 20; wd->distatus = 0; wd->currentop = COP_NUFFINK; refreshdisks = SDL_TRUE; - } else { + } + else + { wd->delayeddrq = 32; } break; case COP_READ_ADDRESS: - if( !wd->currsector ) + if(!wd->currsector) { wd->r_status &= ~WSF_DRQ; - wd->clrdrq( wd->drqarg ); + wd->clrdrq(wd->drqarg); wd->currentop = COP_NUFFINK; refreshdisks = SDL_TRUE; break; } - if( wd->curroffs == 0 ) wd->r_sector = wd->currsector->id_ptr[1]; + if(wd->curroffs == 0) wd->r_sector = wd->currsector->id_ptr[1]; wd->r_data = wd->currsector->id_ptr[++wd->curroffs]; wd->r_status &= ~WSF_DRQ; - wd->clrdrq( wd->drqarg ); - if( wd->curroffs >= 6 ) + wd->clrdrq(wd->drqarg); + if(wd->curroffs >= 6) { wd->delayedint = 20; wd->distatus = 0; wd->currentop = COP_NUFFINK; refreshdisks = SDL_TRUE; - } else { + } + else + { wd->delayeddrq = 32; } break; @@ -922,35 +1063,35 @@ unsigned char wd17xx_read( struct wd17xx *wd, unsigned short addr ) } static SDL_bool last_step_in = SDL_FALSE; -void wd17xx_write( struct machine *oric, struct wd17xx *wd, unsigned short addr, unsigned char data ) +void wd17xx_write(struct machine *oric, struct wd17xx *wd, unsigned short addr, unsigned char data) { - switch( addr ) + switch(addr) { case 0: // Command register - wd->clrintrq( wd->intrqarg ); - switch( data & 0xe0 ) + wd->clrintrq(wd->intrqarg); + switch(data & 0xe0) { case 0x00: // Restore or seek - switch( data & 0x10 ) + switch(data & 0x10) { case 0x00: // Restore (Type I) #if GENERAL_DISK_DEBUG - dbg_printf( "DISK: (%04X) Restore", oric->cpu.pc-1 ); + dbg_printf("DISK: (%04X) Restore", oric->cpu.pc-1); #endif wd->r_status = WSF_BUSY; - if( data & 8 ) wd->r_status |= WSFI_HEADL; - wd17xx_seek_track( wd, 0, oric->cpu.calcpc == 0xe3a1 ); + if(data & 8) wd->r_status |= WSFI_HEADL; + wd17xx_seek_track(wd, 0, oric->cpu.calcpc == 0xe3a1); wd->currentop = COP_NUFFINK; refreshdisks = SDL_TRUE; break; case 0x10: // Seek (Type I) #if GENERAL_DISK_DEBUG - dbg_printf( "DISK: (%04X) Seek", oric->cpu.pc-1 ); + dbg_printf("DISK: (%04X) Seek", oric->cpu.pc-1); #endif wd->r_status = WSF_BUSY; - if( data & 8 ) wd->r_status |= WSFI_HEADL; - wd17xx_seek_track( wd, wd->r_data, SDL_FALSE ); + if(data & 8) wd->r_status |= WSFI_HEADL; + wd17xx_seek_track(wd, wd->r_data, SDL_FALSE); wd->currentop = COP_NUFFINK; refreshdisks = SDL_TRUE; break; @@ -959,25 +1100,25 @@ void wd17xx_write( struct machine *oric, struct wd17xx *wd, unsigned short addr, case 0x20: // Step (Type I) #if GENERAL_DISK_DEBUG - dbg_printf( "DISK: (%04X) Step", oric->cpu.pc-1 ); + dbg_printf("DISK: (%04X) Step", oric->cpu.pc-1); #endif wd->r_status = WSF_BUSY; - if( data & 8 ) wd->r_status |= WSFI_HEADL; - if( last_step_in ) - wd17xx_seek_track( wd, wd->c_track+1, SDL_FALSE ); + if(data & 8) wd->r_status |= WSFI_HEADL; + if(last_step_in) + wd17xx_seek_track(wd, wd->c_track+1, SDL_FALSE); else - wd17xx_seek_track( wd, wd->c_track > 0 ? wd->c_track-1 : 0, SDL_FALSE ); + wd17xx_seek_track(wd, wd->c_track > 0 ? wd->c_track-1 : 0, SDL_FALSE); wd->currentop = COP_NUFFINK; refreshdisks = SDL_TRUE; break; case 0x40: // Step-in (Type I) #if GENERAL_DISK_DEBUG - dbg_printf( "DISK: (%04X) Step-In (%d,%d)", oric->cpu.pc-1, wd->c_track, wd->c_track+1 ); + dbg_printf("DISK: (%04X) Step-In (%d,%d)", oric->cpu.pc-1, wd->c_track, wd->c_track+1); #endif wd->r_status = WSF_BUSY; - if( data & 8 ) wd->r_status |= WSFI_HEADL; - wd17xx_seek_track( wd, wd->c_track+1, SDL_FALSE ); + if(data & 8) wd->r_status |= WSFI_HEADL; + wd17xx_seek_track(wd, wd->c_track+1, SDL_FALSE); last_step_in = SDL_TRUE; wd->currentop = COP_NUFFINK; refreshdisks = SDL_TRUE; @@ -985,12 +1126,12 @@ void wd17xx_write( struct machine *oric, struct wd17xx *wd, unsigned short addr, case 0x60: // Step-out (Type I) #if GENERAL_DISK_DEBUG - dbg_printf( "DISK: Step-Out" ); + dbg_printf("DISK: Step-Out"); #endif wd->r_status = WSF_BUSY; - if( data & 8 ) wd->r_status |= WSFI_HEADL; - if( wd->c_track > 0 ) - wd17xx_seek_track( wd, wd->c_track-1, SDL_FALSE ); + if(data & 8) wd->r_status |= WSFI_HEADL; + if(wd->c_track > 0) + wd17xx_seek_track(wd, wd->c_track-1, SDL_FALSE); last_step_in = SDL_FALSE; wd->currentop = COP_NUFFINK; refreshdisks = SDL_TRUE; @@ -998,19 +1139,19 @@ void wd17xx_write( struct machine *oric, struct wd17xx *wd, unsigned short addr, case 0x80: // Read sector (Type II) #if GENERAL_DISK_DEBUG - switch( oric->drivetype ) + switch(oric->drivetype) { case DRV_MICRODISC: - dbg_printf( "DISK: (%04X) Read sector %u (CODE=%02X,ROM=%s,EPROM=%s)", oric->cpu.pc-1, wd->r_sector, data, oric->romdis?"OFF":"ON", oric->md.diskrom?"ON":"OFF" ); + dbg_printf("DISK: (%04X) Read sector %u (CODE=%02X,ROM=%s,EPROM=%s)", oric->cpu.pc-1, wd->r_sector, data, oric->romdis?"OFF":"ON", oric->md.diskrom?"ON":"OFF"); break; default: - dbg_printf( "DISK: (%04X) Read sector %u (CODE=%02X)", oric->cpu.pc-1, wd->r_sector, data ); + dbg_printf("DISK: (%04X) Read sector %u (CODE=%02X)", oric->cpu.pc-1, wd->r_sector, data); break; } #endif #ifdef MICRODISC_FUDGE - if (!wd->disk[wd->c_drive]) + if(!wd->disk[wd->c_drive]) { wd->currentop = (data&0x10) ? COP_READ_SECTORS_FUDGE : COP_READ_SECTOR_FUDGE; break; @@ -1018,18 +1159,18 @@ void wd17xx_write( struct machine *oric, struct wd17xx *wd, unsigned short addr, #endif wd->curroffs = 0; - wd->currsector = wd17xx_find_sector( wd, wd->r_sector ); - if( !wd->currsector ) + wd->currsector = wd17xx_find_sector(wd, wd->r_sector); + if(!wd->currsector) { wd->r_status = WSF_RNF; - wd->clrdrq( wd->drqarg ); - wd->setintrq( wd->intrqarg ); + wd->clrdrq(wd->drqarg); + wd->setintrq(wd->intrqarg); wd->currentop = COP_NUFFINK; refreshdisks = SDL_TRUE; #if GENERAL_DISK_DEBUG - dbg_printf( "DISK: Sector %d not found.", wd->r_sector ); + dbg_printf("DISK: Sector %d not found.", wd->r_sector); #endif -// setemumode( oric, NULL, EM_DEBUG ); + // setemumode( oric, NULL, EM_DEBUG ); break; } @@ -1047,30 +1188,30 @@ void wd17xx_write( struct machine *oric, struct wd17xx *wd, unsigned short addr, case 0xa0: // Write sector (Type II) #if GENERAL_DISK_DEBUG - switch( oric->drivetype ) + switch(oric->drivetype) { case DRV_MICRODISC: - dbg_printf( "DISK: (%04X) Write sector %u (CODE=%02X,ROM=%s,EPROM=%s)", oric->cpu.pc-1, wd->r_sector, data, oric->romdis?"OFF":"ON", oric->md.diskrom?"ON":"OFF" ); + dbg_printf("DISK: (%04X) Write sector %u (CODE=%02X,ROM=%s,EPROM=%s)", oric->cpu.pc-1, wd->r_sector, data, oric->romdis?"OFF":"ON", oric->md.diskrom?"ON":"OFF"); break; default: - dbg_printf( "DISK: (%04X) Write sector %u (CODE=%02X)", oric->cpu.pc-1, wd->r_sector, data ); + dbg_printf("DISK: (%04X) Write sector %u (CODE=%02X)", oric->cpu.pc-1, wd->r_sector, data); break; } #endif wd->curroffs = 0; - wd->currsector = wd17xx_find_sector( wd, wd->r_sector ); - if( !wd->currsector ) + wd->currsector = wd17xx_find_sector(wd, wd->r_sector); + if(!wd->currsector) { wd->r_status = WSF_RNF; - wd->clrdrq( wd->drqarg ); - wd->setintrq( wd->intrqarg ); + wd->clrdrq(wd->drqarg); + wd->setintrq(wd->intrqarg); wd->currentop = COP_NUFFINK; refreshdisks = SDL_TRUE; #if GENERAL_DISK_DEBUG - dbg_printf( "DISK: Sector %d not found.", wd->r_sector ); + dbg_printf("DISK: Sector %d not found.", wd->r_sector); #endif -// setemumode( oric, NULL, EM_DEBUG ); + // setemumode( oric, NULL, EM_DEBUG ); break; } @@ -1083,53 +1224,53 @@ void wd17xx_write( struct machine *oric, struct wd17xx *wd, unsigned short addr, break; case 0xc0: // Read address / Force IRQ - switch( data & 0x10 ) + switch(data & 0x10) { case 0x00: // Read address (Type III) #if GENERAL_DISK_DEBUG - dbg_printf( "DISK: (%04X) Read address", oric->cpu.pc-1 ); + dbg_printf("DISK: (%04X) Read address", oric->cpu.pc-1); #endif wd->curroffs = 0; - if( !wd->currsector ) - wd->currsector = wd17xx_first_sector( wd ); + if(!wd->currsector) + wd->currsector = wd17xx_first_sector(wd); else - wd->currsector = wd17xx_next_sector( wd ); + wd->currsector = wd17xx_next_sector(wd); - if( !wd->currsector ) + if(!wd->currsector) { wd->r_status = WSF_RNF; - wd->clrdrq( wd->drqarg ); + wd->clrdrq(wd->drqarg); wd->currentop = COP_NUFFINK; - wd->setintrq( wd->intrqarg ); + wd->setintrq(wd->intrqarg); refreshdisks = SDL_TRUE; #if GENERAL_DISK_DEBUG - dbg_printf( "DISK: No sectors on this track?" ); + dbg_printf("DISK: No sectors on this track?"); #endif break; } #if GENERAL_DISK_DEBUG - dbg_printf( "DISK: %02X,%02X,%02X,%02X,%02X,%02X", - wd->currsector->id_ptr[1], - wd->currsector->id_ptr[2], - wd->currsector->id_ptr[3], - wd->currsector->id_ptr[4], - wd->currsector->id_ptr[5], - wd->currsector->id_ptr[6] ); + dbg_printf("DISK: %02X,%02X,%02X,%02X,%02X,%02X", + wd->currsector->id_ptr[1], + wd->currsector->id_ptr[2], + wd->currsector->id_ptr[3], + wd->currsector->id_ptr[4], + wd->currsector->id_ptr[5], + wd->currsector->id_ptr[6]); #endif wd->r_status = WSF_NOTREADY|WSF_BUSY|WSF_DRQ; - wd->setdrq( wd->drqarg ); + wd->setdrq(wd->drqarg); wd->currentop = COP_READ_ADDRESS; refreshdisks = SDL_TRUE; break; case 0x10: // Force Interrupt (Type IV) #if GENERAL_DISK_DEBUG - dbg_printf( "DISK: (%04X) Force int", oric->cpu.pc-1 ); + dbg_printf("DISK: (%04X) Force int", oric->cpu.pc-1); #endif wd->r_status = 0; - wd->clrdrq( wd->drqarg ); - wd->setintrq( wd->intrqarg ); + wd->clrdrq(wd->drqarg); + wd->setintrq(wd->intrqarg); wd->delayedint = 0; wd->delayeddrq = 0; wd->currentop = COP_NUFFINK; @@ -1139,11 +1280,11 @@ void wd17xx_write( struct machine *oric, struct wd17xx *wd, unsigned short addr, break; case 0xe0: // Read track / Write track - switch( data & 0x10 ) + switch(data & 0x10) { case 0x00: // Read track (Type III) #if GENERAL_DISK_DEBUG - dbg_printf( "DISK: (%04X) Read track", oric->cpu.pc-1 ); + dbg_printf("DISK: (%04X) Read track", oric->cpu.pc-1); #endif wd->curroffs = 0; wd->r_status = WSF_BUSY|WSF_NOTREADY; @@ -1155,13 +1296,13 @@ void wd17xx_write( struct machine *oric, struct wd17xx *wd, unsigned short addr, case 0x10: // Write track (Type III) #if GENERAL_DISK_DEBUG - dbg_printf( "DISK: (%04X) Write track", oric->cpu.pc-1 ); + dbg_printf("DISK: (%04X) Write track", oric->cpu.pc-1); #endif wd->curroffs = 0; wd->r_status = WSF_NOTREADY|WSF_BUSY; wd->delayeddrq = 500; - wd->clrdrq( wd->drqarg ); - wd->clrintrq( wd->intrqarg ); + wd->clrdrq(wd->drqarg); + wd->clrintrq(wd->intrqarg); wd->delayedint = 0; wd->currentop = COP_WRITE_TRACK; @@ -1183,50 +1324,49 @@ void wd17xx_write( struct machine *oric, struct wd17xx *wd, unsigned short addr, case 3: // Data register wd->r_data = data; - switch( wd->currentop ) + switch(wd->currentop) { case COP_WRITE_SECTOR: case COP_WRITE_SECTORS: - if( !wd->currsector ) + if(!wd->currsector) { wd->r_status &= ~WSF_DRQ; wd->r_status |= WSF_RNF; - wd->clrdrq( wd->drqarg ); + wd->clrdrq(wd->drqarg); wd->currentop = COP_NUFFINK; refreshdisks = SDL_TRUE; break; } - if( wd->curroffs == 0 ) wd->currsector->data_ptr[wd->curroffs++]=0xfb; + if(wd->curroffs == 0) wd->currsector->data_ptr[wd->curroffs++]=0xfb; wd->currsector->data_ptr[wd->curroffs++] = wd->r_data; - wd->crc = calc_crc( wd->crc, wd->r_data ); - if( !wd->disk[wd->c_drive]->modified ) refreshdisks = SDL_TRUE; - wd->disk[wd->c_drive]->modified = SDL_TRUE; - wd->disk[wd->c_drive]->modified_time = 0; + wd->crc = calc_crc(wd->crc, wd->r_data); + if(!wd->disk[wd->c_drive]->modified) refreshdisks = SDL_TRUE; + diskimage_set_modified(wd->disk[wd->c_drive], wd->c_side, wd->c_track); wd->r_status &= ~WSF_DRQ; - wd->clrdrq( wd->drqarg ); + wd->clrdrq(wd->drqarg); - if( wd->curroffs > wd->currseclen ) + if(wd->curroffs > wd->currseclen) { wd->currsector->data_ptr[wd->curroffs++] = wd->crc>>8; wd->currsector->data_ptr[wd->curroffs++] = wd->crc; - if( wd->currentop == COP_WRITE_SECTORS ) + if(wd->currentop == COP_WRITE_SECTORS) { #if GENERAL_DISK_DEBUG - dbg_printf( "Next sector..." ); + dbg_printf("Next sector..."); #endif // Get the next sector, and carry on! wd->r_sector++; wd->curroffs = 0; - wd->currsector = wd17xx_find_sector( wd, wd->r_sector ); + wd->currsector = wd17xx_find_sector(wd, wd->r_sector); wd->crc = 0xe295; - if( !wd->currsector ) + if(!wd->currsector) { wd->delayedint = 20; wd->distatus = wd->sectype; wd->currentop = COP_NUFFINK; wd->r_status &= (~WSF_DRQ); - wd->clrdrq( wd->drqarg ); + wd->clrdrq(wd->drqarg); refreshdisks = SDL_TRUE; break; } @@ -1238,9 +1378,11 @@ void wd17xx_write( struct machine *oric, struct wd17xx *wd, unsigned short addr, wd->distatus = wd->sectype; wd->currentop = COP_NUFFINK; wd->r_status &= (~WSF_DRQ); - wd->clrdrq( wd->drqarg ); + wd->clrdrq(wd->drqarg); refreshdisks = SDL_TRUE; - } else { + } + else + { wd->delayeddrq = 32; } break; @@ -1253,26 +1395,26 @@ void wd17xx_write( struct machine *oric, struct wd17xx *wd, unsigned short addr, // MFM: Initialize CRC generator // FM : Not allowed #if GENERAL_DISK_DEBUG - dbg_printf( "\tCOP_WRITE_TRACK: %02X -> SYNC (clear crc) -> 0xA1", wd->r_data); + dbg_printf("\tCOP_WRITE_TRACK: %02X -> SYNC (clear crc) -> 0xA1", wd->r_data); #endif wd->crc = 0x968b; wd->r_data = 0xa1; - wd->crc = calc_crc( wd->crc, wd->r_data ); + wd->crc = calc_crc(wd->crc, wd->r_data); // wd->crc = 0xcdb4; break; case 0xf6: // FM : Not allowed #if GENERAL_DISK_DEBUG - dbg_printf( "\tCOP_WRITE_TRACK: %02X -> SYNC -> 0xC2", wd->r_data); + dbg_printf("\tCOP_WRITE_TRACK: %02X -> SYNC -> 0xC2", wd->r_data); #endif wd->r_data = 0xc2; - wd->crc = calc_crc( wd->crc, wd->r_data ); + wd->crc = calc_crc(wd->crc, wd->r_data); break; case 0xf7: #if GENERAL_DISK_DEBUG - dbg_printf( "\tCOP_WRITE_TRACK: %02X -> CRC -> %04X", wd->r_data, wd->crc); + dbg_printf("\tCOP_WRITE_TRACK: %02X -> CRC -> %04X", wd->r_data, wd->crc); #endif wd->disk[wd->c_drive]->rawimage[(wd->c_side*wd->disk[wd->c_drive]->numtracks + wd->c_track)*6400+256 + wd->curroffs] = wd->crc >> 8; wd->curroffs++; @@ -1283,55 +1425,55 @@ void wd17xx_write( struct machine *oric, struct wd17xx *wd, unsigned short addr, // MFM: 0xf8 -> 0xff: write control byte // FM : 0xf8 -> 0xfe: Initialize CRC generator case 0xf8: - dbg_printf( "\tCOP_WRITE_TRACK: %02X -> Data Address Mark (deleted)", wd->r_data); - wd->crc = calc_crc( wd->crc, wd->r_data ); + dbg_printf("\tCOP_WRITE_TRACK: %02X -> Data Address Mark (deleted)", wd->r_data); + wd->crc = calc_crc(wd->crc, wd->r_data); // next bytes: data, ; break; case 0xf9: - dbg_printf( "\tCOP_WRITE_TRACK: %02X -> Data Mark", wd->r_data); - wd->crc = calc_crc( wd->crc, wd->r_data ); + dbg_printf("\tCOP_WRITE_TRACK: %02X -> Data Mark", wd->r_data); + wd->crc = calc_crc(wd->crc, wd->r_data); break; case 0xfa: - dbg_printf( "\tCOP_WRITE_TRACK: %02X -> Data Mark", wd->r_data); - wd->crc = calc_crc( wd->crc, wd->r_data ); + dbg_printf("\tCOP_WRITE_TRACK: %02X -> Data Mark", wd->r_data); + wd->crc = calc_crc(wd->crc, wd->r_data); break; case 0xfb: - dbg_printf( "\tCOP_WRITE_TRACK: %02X -> Data Address Mark (normal)", wd->r_data); - wd->crc = calc_crc( wd->crc, wd->r_data ); + dbg_printf("\tCOP_WRITE_TRACK: %02X -> Data Address Mark (normal)", wd->r_data); + wd->crc = calc_crc(wd->crc, wd->r_data); // next bytes: data, ; break; case 0xfc: - dbg_printf( "\tCOP_WRITE_TRACK: %02X -> Data Mark", wd->r_data); - wd->crc = calc_crc( wd->crc, wd->r_data ); + dbg_printf("\tCOP_WRITE_TRACK: %02X -> Data Mark", wd->r_data); + wd->crc = calc_crc(wd->crc, wd->r_data); break; case 0xfd: - dbg_printf( "\tCOP_WRITE_TRACK: %02X -> Data Mark", wd->r_data); - wd->crc = calc_crc( wd->crc, wd->r_data ); + dbg_printf("\tCOP_WRITE_TRACK: %02X -> Data Mark", wd->r_data); + wd->crc = calc_crc(wd->crc, wd->r_data); break; case 0xfe: - dbg_printf( "\tCOP_WRITE_TRACK: %02X -> Index Address Mark", wd->r_data); - wd->crc = calc_crc( wd->crc, wd->r_data ); + dbg_printf("\tCOP_WRITE_TRACK: %02X -> Index Address Mark", wd->r_data); + wd->crc = calc_crc(wd->crc, wd->r_data); // next 6 bytes: track, side, sector, size, ; break; case 0xff: - dbg_printf( "\tCOP_WRITE_TRACK: %02X -> ???", wd->r_data); - wd->crc = calc_crc( wd->crc, wd->r_data ); + dbg_printf("\tCOP_WRITE_TRACK: %02X -> ???", wd->r_data); + wd->crc = calc_crc(wd->crc, wd->r_data); break; #endif default: - wd->crc = calc_crc( wd->crc, wd->r_data ); + wd->crc = calc_crc(wd->crc, wd->r_data); } - // Write byte to disk image + // Write byte to disk image #if GENERAL_DISK_DEBUG dbg_printf("\tCOP_WRITE_TRACK: write byte: %02X '%c'", wd->r_data, wd->r_data); #endif @@ -1339,15 +1481,14 @@ void wd17xx_write( struct machine *oric, struct wd17xx *wd, unsigned short addr, wd->curroffs++; wd->r_status &= ~WSF_DRQ; - wd->clrdrq( wd->drqarg ); + wd->clrdrq(wd->drqarg); - wd->disk[wd->c_drive]->modified = SDL_TRUE; - wd->disk[wd->c_drive]->modified_time = 0; + diskimage_set_modified(wd->disk[wd->c_drive], wd->c_side, wd->c_track); refreshdisks = SDL_TRUE; // Has the whole track been written? - if (wd->curroffs >= 6400) - { + if(wd->curroffs >= 6400) + { #if GENERAL_DISK_DEBUG dbg_printf("\tCOP_WRITE_TRACK: track full (%d)", wd->curroffs); #endif @@ -1355,9 +1496,9 @@ void wd17xx_write( struct machine *oric, struct wd17xx *wd, unsigned short addr, wd->currentop = COP_NUFFINK; // wd->r_status &= (~WSF_DRQ); wd->r_status = 0; - wd->clrdrq( wd->drqarg ); - } - else + wd->clrdrq(wd->drqarg); + } + else wd->delayeddrq = 64; break; @@ -1366,28 +1507,29 @@ void wd17xx_write( struct machine *oric, struct wd17xx *wd, unsigned short addr, } } -void microdisc_setdrq( void *md ) +// Microdisc interface handlers +void microdisc_setdrq(void* md) { struct microdisc *mdp = (struct microdisc *)md; mdp->drq = 0; } -void microdisc_clrdrq( void *md ) +void microdisc_clrdrq(void* md) { struct microdisc *mdp = (struct microdisc *)md; mdp->drq = MF_DRQ; } -void microdisc_setintrq( void *md ) +void microdisc_setintrq(void* md) { struct microdisc *mdp = (struct microdisc *)md; mdp->intrq = 0; //MDSF_INTRQ; - if( mdp->status & MDSF_INTENA ) + if(mdp->status & MDSF_INTENA) mdp->oric->cpu.irq |= IRQF_DISK; } -void microdisc_clrintrq( void *md ) +void microdisc_clrintrq(void* md) { struct microdisc *mdp = (struct microdisc *)md; @@ -1395,9 +1537,9 @@ void microdisc_clrintrq( void *md ) mdp->oric->cpu.irq &= ~IRQF_DISK; } -void microdisc_init( struct microdisc *md, struct wd17xx *wd, struct machine *oric ) +void microdisc_init(struct microdisc *md, struct wd17xx *wd, struct machine *oric) { - wd17xx_init( wd ); + wd17xx_init(wd); wd->setintrq = microdisc_setintrq; wd->clrintrq = microdisc_clrintrq; wd->intrqarg = (void*)md; @@ -1413,20 +1555,20 @@ void microdisc_init( struct microdisc *md, struct wd17xx *wd, struct machine *or md->diskrom = SDL_TRUE; } -void microdisc_free( struct microdisc *md ) +void microdisc_free(struct microdisc *md) { int i; - for( i=0; ioric, i ); + for(i=0; ioric, i); } -unsigned char microdisc_read( struct microdisc *md, unsigned short addr ) +unsigned char microdisc_read(struct microdisc *md, unsigned short addr) { -// dbg_printf( "DISK: (%04X) Read from %04X", md->oric->cpu.pc-1, addr ); - if( ( addr >= 0x310 ) && ( addr < 0x314 ) ) - return wd17xx_read( md->wd, addr&3 ); + // dbg_printf( "DISK: (%04X) Read from %04X", md->oric->cpu.pc-1, addr ); + if((addr >= 0x310) && (addr < 0x314)) + return wd17xx_read(md->wd, addr&3); - switch( addr ) + switch(addr) { case 0x314: return md->intrq|0x7f; @@ -1438,28 +1580,30 @@ unsigned char microdisc_read( struct microdisc *md, unsigned short addr ) break; } - return via_read( &md->oric->via, addr ); + return via_read(&md->oric->via, addr); } -void microdisc_write( struct microdisc *md, unsigned short addr, unsigned char data ) +void microdisc_write(struct microdisc *md, unsigned short addr, unsigned char data) { -// dbg_printf( "DISK: (%04X) Write %02X to %04X", md->oric->cpu.pc-1, data, addr ); - if( ( addr >= 0x310 ) && ( addr < 0x314 ) ) + // dbg_printf( "DISK: (%04X) Write %02X to %04X", md->oric->cpu.pc-1, data, addr ); + if((addr >= 0x310) && (addr < 0x314)) { - wd17xx_write( md->oric, md->wd, addr&3, data ); + wd17xx_write(md->oric, md->wd, addr&3, data); return; } - switch( addr ) + switch(addr) { case 0x314: md->status = data; // Interrupts enabled, and /INTRQ == 0 ? - if( ( data&MDSF_INTENA ) && ( md->intrq == 0 ) ) + if((data&MDSF_INTENA) && (md->intrq == 0)) { md->oric->cpu.irq |= IRQF_DISK; - } else { + } + else + { md->oric->cpu.irq &= ~IRQF_DISK; } @@ -1474,34 +1618,235 @@ void microdisc_write( struct microdisc *md, unsigned short addr, unsigned char d break; default: - via_write( &md->oric->via, addr, data ); + via_write(&md->oric->via, addr, data); + break; + } +} + +// Byte Drive 500 interface handlers +// NOTE: Info by Ray McLaughlin +// +// 0x310 MOTOFF R switches the disk drive motor off. +// 0x311 MOTON R switches the disk drive motor on. +// NOTE: (probably)the motor is switched on +// by (electronic) default on first powering up +// the BD interface but it is safer to switch it +// on in the boot sector (page 4) code. +// +// 0x312 DSTATS R bit 7 - DRQ +// bit 6 - IRQ +// bit 0 - motor status (): b0=0 ON, b0=1 OFF (NOTE: DOS7 only). +// +// 0x313 MAPOFF R/W enables the ORIC ROM and disables the overlay RAM. +// +// 0x314 MAPON R/W disables the ORIC ROM and enables the overlay RAM. +// +// 0x315 PRECMP R (probably) forwrite compensation on the FDC. +// NOTE: maybe it's used in the DOS versions V2.2 & V3.1 +// of the BD software but not in Ray's latest version, +// perhaps it will be included. +// +// 0x316 SDEN R/W enables the the lower 8k of the ORIC's EPROM +// (used where the ORIC has 2x8k EPROMS) and therefore +// disables the overlay RAM in that memory area. +// This overrides MAPON (see above). +// +// 0x317 DDEN R/W disables the lower 8k of the ORIC's EPROM +// (used where the ORIC has 1x16k EPROM or ROM) +// and therefore enables the overlay RAM when MAPON +// has been accessed. +// +// 0x31a DRVSEL R/W bit 7,6 - get/set current drive +// bit 5 - get/set current side +// +// 0x0380 R/W disables the BD interface ROM which covers addresses +// 0xE000 to 0xFFFF but before that is done, it takes +// precedence over the above for that memory space. + +void bd500_setdrq(void* bd) +{ + struct bd500 *bdp = (struct bd500 *)bd; + bdp->drq = 0x80; +} + +void bd500_clrdrq(void* bd) +{ + struct bd500 *bdp = (struct bd500 *)bd; + bdp->drq = 0; +} + +void bd500_setintrq(void* bd) +{ + struct bd500 *bdp = (struct bd500 *)bd; + bdp->intrq = 0x40; +} + +void bd500_clrintrq(void* bd) +{ + struct bd500 *bdp = (struct bd500 *)bd; + bdp->intrq = 0; +} + +void bd500_init(struct bd500 *bd, struct wd17xx *wd, struct machine *oric) +{ + wd17xx_init(wd); + wd->setintrq = bd500_setintrq; + wd->clrintrq = bd500_clrintrq; + wd->intrqarg = (void*)bd; + wd->setdrq = bd500_setdrq; + wd->clrdrq = bd500_clrdrq; + wd->drqarg = (void*)bd; + + bd->status = 0; + bd->intrq = 0; + bd->drq = 0; + bd->wd = wd; + bd->oric = oric; + bd->diskrom = SDL_TRUE; + bd->motor = SDL_FALSE; +} + +void bd500_free(struct bd500 *bd) +{ + int i; + for(i=0; ioric, i); +} + +unsigned char bd500_read(struct bd500 *bd, unsigned short addr) +{ + unsigned char ret = 0xff; + + // dbg_printf( "DISK: (%04X) Read from %04X", bd->oric->cpu.pc-1, addr ); + + if((addr >= 0x320) && (addr < 0x324)) + return wd17xx_read(bd->wd, addr&3); + + switch(addr) + { + case 0x312: + ret = bd->drq | bd->intrq; + if(bd->oric->dos70) ret |= bd->motor? 0:1; + break; + + case 0x313: + bd->oric->romdis = SDL_FALSE; + break; + + case 0x314: + bd->oric->romdis = SDL_TRUE; + break; + + case 0x310: + // MOTOFF = 0 + bd->motor = SDL_FALSE; + bd->wd->currentop = COP_NUFFINK; + break; + + case 0x311: + // MOTON = 1 + bd->motor = SDL_TRUE; + bd->wd->currentop = COP_READ_SECTOR; + break; + + case 0x315: + // PRECMP + break; + + case 0x316: + // SDEN + bd->diskrom = SDL_FALSE; + break; + + case 0x317: + // DDEN + // 64k/56k mode depend on ROM chips + bd->diskrom = bd->oric->rom16? SDL_FALSE : SDL_TRUE; + break; + + case 0x31a: + // bits 7,6 current drive + // bit 5 current side + ret = ((bd->wd->c_drive&3)<<6) | ((bd->wd->c_side&1)<<5); + break; + + case 0x0380: + bd->diskrom = SDL_FALSE; + break; + + default: + break; + } + + return ret; +} + +void bd500_write(struct bd500 *bd, unsigned short addr, unsigned char data) +{ + // dbg_printf( "DISK: (%04X) Write %02X to %04X", bd->oric->cpu.pc-1, data, addr ); + + if((addr >= 0x320) && (addr < 0x324)) + { + wd17xx_write(bd->oric, bd->wd, addr&3, data); + return; + } + + switch(addr) + { + case 0x313: + bd->oric->romdis = SDL_FALSE; + break; + + case 0x314: + bd->oric->romdis = SDL_TRUE; + break; + + case 0x316: + // SDEN + bd->diskrom = SDL_FALSE; + break; + + case 0x317: + // DDEN + // 64k/56k mode depend on ROM chips + bd->diskrom = bd->oric->rom16? SDL_FALSE : SDL_TRUE; + break; + + case 0x0380: + bd->diskrom = SDL_FALSE; + break; + + case 0x31a: + bd->wd->c_side = (data>>5)&1; + bd->wd->c_drive = (data>>6)&3; break; } } -void jasmin_setdrq( void *j ) +// Jasmin interface handlers +void jasmin_setdrq(void* j) { struct jasmin *jp = (struct jasmin *)j; jp->oric->cpu.irq |= IRQF_DISK; } -void jasmin_clrdrq( void *j ) +void jasmin_clrdrq(void* j) { struct jasmin *jp = (struct jasmin *)j; jp->oric->cpu.irq &= ~IRQF_DISK; } -void jasmin_setintrq( void *j ) +void jasmin_setintrq(void* j) { } -void jasmin_clrintrq( void *j ) +void jasmin_clrintrq(void* j) { } -void jasmin_init( struct jasmin *j, struct wd17xx *wd, struct machine *oric ) +void jasmin_init(struct jasmin *j, struct wd17xx *wd, struct machine *oric) { - wd17xx_init( wd ); + wd17xx_init(wd); wd->setintrq = jasmin_setintrq; wd->clrintrq = jasmin_clrintrq; wd->intrqarg = (void*)j; @@ -1515,20 +1860,20 @@ void jasmin_init( struct jasmin *j, struct wd17xx *wd, struct machine *oric ) j->oric = oric; } -void jasmin_free( struct jasmin *j ) +void jasmin_free(struct jasmin *j) { int i; - for( i=0; ioric, i ); + for(i=0; ioric, i); } -unsigned char jasmin_read( struct jasmin *j, unsigned short addr ) +unsigned char jasmin_read(struct jasmin *j, unsigned short addr) { -// dbg_printf( "DISK: (%04X) Read from %04X", md->oric->cpu.pc-1, addr ); - if( ( addr >= 0x3f4 ) && ( addr < 0x3f8 ) ) - return wd17xx_read( j->wd, addr&3 ); + // dbg_printf( "DISK: (%04X) Read from %04X", md->oric->cpu.pc-1, addr ); + if((addr >= 0x3f4) && (addr < 0x3f8)) + return wd17xx_read(j->wd, addr&3); - switch( addr ) + switch(addr) { case 0x3f8: // Side select return j->wd->c_side ? 1 : 0; @@ -1550,18 +1895,18 @@ unsigned char jasmin_read( struct jasmin *j, unsigned short addr ) break; } - return via_read( &j->oric->via, addr ); + return via_read(&j->oric->via, addr); } -void jasmin_write( struct jasmin *j, unsigned short addr, unsigned char data ) +void jasmin_write(struct jasmin *j, unsigned short addr, unsigned char data) { - if( ( addr >= 0x3f4 ) && ( addr < 0x3f8 ) ) + if((addr >= 0x3f4) && (addr < 0x3f8)) { - wd17xx_write( j->oric, j->wd, addr&3, data ); + wd17xx_write(j->oric, j->wd, addr&3, data); return; } - switch( addr ) + switch(addr) { case 0x3f8: // side select j->wd->c_side = data&1; @@ -1588,13 +1933,13 @@ void jasmin_write( struct jasmin *j, unsigned short addr, unsigned char data ) break; default: - via_write( &j->oric->via, addr, data ); + via_write(&j->oric->via, addr, data); break; } } // Pravetz -void pravetz_init( struct pravetz *p, struct machine *oric ) +void pravetz_init(struct pravetz *p, struct machine *oric) { int i; @@ -1603,34 +1948,34 @@ void pravetz_init( struct pravetz *p, struct machine *oric ) p->extension = 0; p->oric = oric; - for( i=0; idrv[i].write_ready = 0x80; - p->drv[i].volume = 254; - p->drv[i].select = 0; - p->drv[i].motor_on = 0; - p->drv[i].pimg = NULL; + p->drv[i].write_ready = 0x80; + p->drv[i].volume = 254; + p->drv[i].select = 0; + p->drv[i].motor_on = 0; + p->drv[i].pimg = NULL; } } -void pravetz_free( struct pravetz *p ) +void pravetz_free(struct pravetz *p) { int i; - for( i=0; ioric, i ); + for(i=0; ioric, i); } -unsigned char pravetz_read( struct pravetz *p, unsigned short addr ) +unsigned char pravetz_read(struct pravetz *p, unsigned short addr) { unsigned char data = 0; - data = disk_pravetz_read( p->oric, addr ); + data = disk_pravetz_read(p->oric, addr); p->oric->wddisk.currentop = p->drv[p->oric->wddisk.c_drive].motor_on ? COP_READ_SECTOR : COP_NUFFINK; return data; } -void pravetz_write( struct pravetz *p, unsigned short addr, unsigned char data ) +void pravetz_write(struct pravetz *p, unsigned short addr, unsigned char data) { - disk_pravetz_write( p->oric, addr, data ); - p->oric->wddisk.currentop = p->drv[p->oric->wddisk.c_drive].motor_on ? COP_READ_SECTOR : COP_NUFFINK; + disk_pravetz_write(p->oric, addr, data); + p->oric->wddisk.currentop = p->drv[p->oric->wddisk.c_drive].motor_on ? COP_WRITE_SECTOR : COP_NUFFINK; } diff --git a/disk.h b/disk.h index a3e7f4e5..3ee585c0 100644 --- a/disk.h +++ b/disk.h @@ -113,8 +113,12 @@ struct mfmsector struct diskimage { Sint16 drivenum; // The drive this disk is inserted into, or -1 - Uint32 numtracks; // Number of tracks per side Uint32 numsides; // Number of sides in the image + Uint32 numtracks; // Number of tracks per side + Uint32 numsides_in; // Number of sides in the image on input + Uint32 numtracks_in; // Number of tracks per side on input + Uint32 numsides_out; // Number of sides in the image on output + Uint32 numtracks_out; // Number of tracks per side on output Uint32 geometry; // Geometry. I don't know what this is. Sint16 cachedtrack; // Currently cached track (or -1 for none) Sint16 cachedside; // Currently cached side (or -1 for none) @@ -140,12 +144,12 @@ struct wd17xx Uint8 c_sector; // Currently selected sector ID Uint8 sectype; // When reading a sector, this is used to remember if it was marked as deleted SDL_bool last_step_in; // Set to TRUE if the last seek operation stepped the head inwards - void (*setintrq)(void *); // Function pointer called by the WD17xx core when INTRQ is set (used for microdisc/jasmin integration) - void (*clrintrq)(void *); // Called when INTRQ is cleared - void *intrqarg; // Userdata passed to setintrq/clrintrq - void (*setdrq)(void *); // Called when DRQ is set - void (*clrdrq)(void *); // Called when DRQ is cleared - void *drqarg; // Userdata passed to setdrq/clrdrq + void (*setintrq)(void*); // Function pointer called by the WD17xx core when INTRQ is set (used for microdisc/jasmin integration) + void (*clrintrq)(void*); // Called when INTRQ is cleared + void* intrqarg; // Userdata passed to setintrq/clrintrq + void (*setdrq)(void*); // Called when DRQ is set + void (*clrdrq)(void*); // Called when DRQ is cleared + void* drqarg; // Userdata passed to setdrq/clrdrq struct diskimage *disk[MAX_DRIVES]; // Loaded disk images int currentop; // Current operation in progress struct mfmsector *currsector; // Pointers to the current sector in the disk image being used by an active read or write operation @@ -169,6 +173,17 @@ struct microdisc SDL_bool diskrom; // TRUE if the diskrom is enabled }; +// Current state of the Byte Drive 500 hardware +struct bd500 +{ + Uint8 status; // Status register (write to 0x314) + Uint8 intrq; // intrq register (read from 0x314) + Uint8 drq; // drq register (read/write 0x318) + struct wd17xx *wd; // Pointer to the WD17xx structure + struct machine *oric; // Pointer to the Oric structure + SDL_bool diskrom; // TRUE if the diskrom is enabled + SDL_bool motor; +}; // Current state of the Jasmin hardware struct jasmin @@ -204,29 +219,37 @@ struct pravetz struct pravetz_drive drv[MAX_DRIVES]; }; +void disk_eject(struct machine *oric, int drive); + // Functions to read/write diskimages -SDL_bool diskimage_load( struct machine *oric, char *fname, int drive ); -SDL_bool diskimage_save( struct machine *oric, char *fname, int drive ); -void diskimage_cachetrack( struct diskimage *dimg, int track, int side ); -struct mfmsector *wd17xx_find_sector( struct wd17xx *wd, Uint8 secid ); +SDL_bool diskimage_load(struct machine *oric, char* fname, int drive); +SDL_bool diskimage_save(struct machine *oric, char* fname, int drive); +void diskimage_cachetrack(struct diskimage *dimg, int track, int side); +struct mfmsector *wd17xx_find_sector(struct wd17xx *wd, Uint8 secid); // Call this to emulate some cycles of disk activity -void wd17xx_ticktock( struct wd17xx *wd, int cycles ); +void wd17xx_ticktock(struct wd17xx *wd, int cycles); // Microdisc interface -void microdisc_init( struct microdisc *md, struct wd17xx *wd, struct machine *oric ); -void microdisc_free( struct microdisc *md ); -unsigned char microdisc_read( struct microdisc *md, unsigned short addr ); -void microdisc_write( struct microdisc *md, unsigned short addr, unsigned char data ); +void microdisc_init(struct microdisc *md, struct wd17xx *wd, struct machine *oric); +void microdisc_free(struct microdisc *md); +unsigned char microdisc_read(struct microdisc *md, unsigned short addr); +void microdisc_write(struct microdisc *md, unsigned short addr, unsigned char data); + +// Byte Drive 500 interface +void bd500_init(struct bd500 *bd, struct wd17xx *wd, struct machine *oric); +void bd500_free(struct bd500 *bd); +unsigned char bd500_read(struct bd500 *bd, unsigned short addr); +void bd500_write(struct bd500 *bd, unsigned short addr, unsigned char data); // Jasmin interface -void jasmin_init( struct jasmin *j, struct wd17xx *wd, struct machine *oric ); -void jasmin_free( struct jasmin *j ); -unsigned char jasmin_read( struct jasmin *j, unsigned short addr ); -void jasmin_write( struct jasmin *j, unsigned short addr, unsigned char data ); +void jasmin_init(struct jasmin *j, struct wd17xx *wd, struct machine *oric); +void jasmin_free(struct jasmin *j); +unsigned char jasmin_read(struct jasmin *j, unsigned short addr); +void jasmin_write(struct jasmin *j, unsigned short addr, unsigned char data); // Pravetz 8D disk interface -void pravetz_init( struct pravetz *p, struct machine *oric ); -void pravetz_free( struct pravetz *p ); -unsigned char pravetz_read( struct pravetz *p, unsigned short addr ); -void pravetz_write( struct pravetz *p, unsigned short addr, unsigned char data ); +void pravetz_init(struct pravetz *p, struct machine *oric); +void pravetz_free(struct pravetz *p); +unsigned char pravetz_read(struct pravetz *p, unsigned short addr); +void pravetz_write(struct pravetz *p, unsigned short addr, unsigned char data); diff --git a/disk_pravetz.c b/disk_pravetz.c index e30e3fbf..af3cbb77 100644 --- a/disk_pravetz.c +++ b/disk_pravetz.c @@ -51,87 +51,87 @@ static void disk_pravetz_switch(struct machine *oric, Uint16 addr); Uint8 disk_pravetz_read(struct machine *oric, Uint16 addr) { - disk_pravetz_switch(oric, addr-PRAV_DISK_OFFSET); - /* odd addresses don't produce anything */ - return (!(addr & 1))? disk_pravetz_read_selected(oric) : 0; + disk_pravetz_switch(oric, addr-PRAV_DISK_OFFSET); + /* odd addresses don't produce anything */ + return (!(addr & 1))? disk_pravetz_read_selected(oric) : 0; } void disk_pravetz_write(struct machine *oric, Uint16 addr, Uint8 data) { - disk_pravetz_switch(oric, addr-PRAV_DISK_OFFSET); - /* even addresses don't write anything */ - if(addr & 1) - { - disk_pravetz_write_selected(oric, data); - } + disk_pravetz_switch(oric, addr-PRAV_DISK_OFFSET); + /* even addresses don't write anything */ + if(addr & 1) + { + disk_pravetz_write_selected(oric, data); + } } /* Skewing-Table */ static int interleave[16] = { - 0, 7, 14, 6, 13, 5, 12, 4, 11, 3, 10, 2, 9, 1, 8, 15 + 0, 7, 14, 6, 13, 5, 12, 4, 11, 3, 10, 2, 9, 1, 8, 15 }; /* Translation Table */ static int translate[256] = { - 0x96, 0x97, 0x9a, 0x9b, 0x9d, 0x9e, 0x9f, 0xa6, - 0xa7, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb2, 0xb3, - 0xb4, 0xb5, 0xb6, 0xb7, 0xb9, 0xba, 0xbb, 0xbc, - 0xbd, 0xbe, 0xbf, 0xcb, 0xcd, 0xce, 0xcf, 0xd3, - 0xd6, 0xd7, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, - 0xdf, 0xe5, 0xe6, 0xe7, 0xe9, 0xea, 0xeb, 0xec, - 0xed, 0xee, 0xef, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, - 0xf7, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x01, - 0x80, 0x80, 0x02, 0x03, 0x80, 0x04, 0x05, 0x06, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x07, 0x08, - 0x80, 0x80, 0x80, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, - 0x80, 0x80, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, - 0x80, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x1b, 0x80, 0x1c, 0x1d, 0x1e, - 0x80, 0x80, 0x80, 0x1f, 0x80, 0x80, 0x20, 0x21, - 0x80, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x29, 0x2a, 0x2b, - 0x80, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, - 0x80, 0x80, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, - 0x80, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f + 0x96, 0x97, 0x9a, 0x9b, 0x9d, 0x9e, 0x9f, 0xa6, + 0xa7, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb2, 0xb3, + 0xb4, 0xb5, 0xb6, 0xb7, 0xb9, 0xba, 0xbb, 0xbc, + 0xbd, 0xbe, 0xbf, 0xcb, 0xcd, 0xce, 0xcf, 0xd3, + 0xd6, 0xd7, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, + 0xdf, 0xe5, 0xe6, 0xe7, 0xe9, 0xea, 0xeb, 0xec, + 0xed, 0xee, 0xef, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, + 0xf7, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x01, + 0x80, 0x80, 0x02, 0x03, 0x80, 0x04, 0x05, 0x06, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x07, 0x08, + 0x80, 0x80, 0x80, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, + 0x80, 0x80, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, + 0x80, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x1b, 0x80, 0x1c, 0x1d, 0x1e, + 0x80, 0x80, 0x80, 0x1f, 0x80, 0x80, 0x20, 0x21, + 0x80, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x29, 0x2a, 0x2b, + 0x80, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, + 0x80, 0x80, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, + 0x80, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f }; -static void disk_pravetz_update_position (struct pravetz_drive *drv) +static void disk_pravetz_update_position(struct pravetz_drive *drv) { - if (drv->motor_on) - { - drv->byte = (1 + drv->byte) % PRAV_RAW_TRACK_SIZE; - } + if(drv->motor_on) + { + drv->byte = (1 + drv->byte) % PRAV_RAW_TRACK_SIZE; + } } Uint8 disk_pravetz_image_raw_byte(struct machine *oric, int drive, Uint16 t_idx, Uint16 s_idx, Uint16 b_idx) { - long f_pos; + long f_pos; - static Uint8 old; - static Uint8 eor; - static Uint8 raw; - static Uint8 check; + static Uint8 old; + static Uint8 eor; + static Uint8 raw; + static Uint8 check; - struct pravetz_drive *drv = &oric->pravetz.drv[drive]; + struct pravetz_drive *drv = &oric->pravetz.drv[drive]; - raw = 0xFF; + raw = 0xFF; - switch (b_idx) - { + switch(b_idx) + { case 0: case 1: case 2: @@ -143,118 +143,118 @@ Uint8 disk_pravetz_image_raw_byte(struct machine *oric, int drive, Uint16 t_id case 22: case 23: case 24: - /* sync bytes */ - return 0xFF; + /* sync bytes */ + return 0xFF; case 6: case 25: - /* sector header byte #1 */ - return 0xD5; + /* sector header byte #1 */ + return 0xD5; case 7: case 26: - /* sector header byte #2 */ - return 0xAA; + /* sector header byte #2 */ + return 0xAA; case 8: - /* address header byte */ - return 0x96; + /* address header byte */ + return 0x96; case 9: - /* volume byte #1 */ - check = drv->volume; - return 0xAA | (drv->volume >> 1); + /* volume byte #1 */ + check = drv->volume; + return 0xAA | (drv->volume >> 1); case 10: - /* volume */ - return 0xAA | drv->volume; + /* volume */ + return 0xAA | drv->volume; case 11: - /* track byte #1 */ - check ^= t_idx; - return 0xAA | (t_idx >> 1); + /* track byte #1 */ + check ^= t_idx; + return 0xAA | (t_idx >> 1); case 12: - /* track byte #2 */ - return 0xAA | t_idx; + /* track byte #2 */ + return 0xAA | t_idx; case 13: - /* sector byte #1 */ - check ^= s_idx; - return 0xAA | (s_idx >> 1); + /* sector byte #1 */ + check ^= s_idx; + return 0xAA | (s_idx >> 1); case 14: - /* sector byte #2 */ - return 0xAA | s_idx; + /* sector byte #2 */ + return 0xAA | s_idx; case 15: - /* checksum byte #1 */ - return 0xAA | (check >> 1); + /* checksum byte #1 */ + return 0xAA | (check >> 1); case 16: - /* checksum byte #2 */ - return 0xAA | check; + /* checksum byte #2 */ + return 0xAA | check; case 17: case 371: - /* address/data trailer byte #1 */ - return 0xDE; + /* address/data trailer byte #1 */ + return 0xDE; case 18: case 372: - /* address/data trailer byte #2 */ - return 0xAA; + /* address/data trailer byte #2 */ + return 0xAA; case 19: case 373: - /* address/data trailer byte #3 */ - return 0xEB; + /* address/data trailer byte #3 */ + return 0xEB; case 27: - /* data header */ - eor = 0; + /* data header */ + eor = 0; - /* Read the coming sector */ - f_pos = (256 * 16 * t_idx) + (256 * interleave[s_idx]); - if (drv->pimg) - drv->sector_ptr = &drv->pimg->rawimage[f_pos]; - else - drv->sector_ptr = NULL; - return 0xAD; + /* Read the coming sector */ + f_pos = (256 * 16 * t_idx) + (256 * interleave[s_idx]); + if(drv->pimg) + drv->sector_ptr = &drv->pimg->rawimage[f_pos]; + else + drv->sector_ptr = NULL; + return 0xAD; case 370: - /* checksum */ - return translate[eor & 0x3F]; + /* checksum */ + return translate[eor & 0x3F]; default: - b_idx -= 28; - - if (b_idx >= 0x56) - { - /* 6 Bit */ - old = drv->sector_ptr[b_idx - 0x56]; - old = old >> 2; - eor ^= old; - raw = translate[eor & 0x3F]; - eor = old; - } - else - { - /* 3 * 2 Bit */ - old = (drv->sector_ptr[b_idx] & 0x01) << 1; - old |= (drv->sector_ptr[b_idx] & 0x02) >> 1; - old |= (drv->sector_ptr[b_idx + 0x56] & 0x01) << 3; - old |= (drv->sector_ptr[b_idx + 0x56] & 0x02) << 1; - old |= (drv->sector_ptr[b_idx + 0xAC] & 0x01) << 5; - old |= (drv->sector_ptr[b_idx + 0xAC] & 0x02) << 3; - eor ^= old; - raw = translate[eor & 0x3F]; - eor = old; - } - break; - } - - return raw; + b_idx -= 28; + + if(b_idx >= 0x56) + { + /* 6 Bit */ + old = drv->sector_ptr[b_idx - 0x56]; + old = old >> 2; + eor ^= old; + raw = translate[eor & 0x3F]; + eor = old; + } + else + { + /* 3 * 2 Bit */ + old = (drv->sector_ptr[b_idx] & 0x01) << 1; + old |= (drv->sector_ptr[b_idx] & 0x02) >> 1; + old |= (drv->sector_ptr[b_idx + 0x56] & 0x01) << 3; + old |= (drv->sector_ptr[b_idx + 0x56] & 0x02) << 1; + old |= (drv->sector_ptr[b_idx + 0xAC] & 0x01) << 5; + old |= (drv->sector_ptr[b_idx + 0xAC] & 0x02) << 3; + eor ^= old; + raw = translate[eor & 0x3F]; + eor = old; + } + break; + } + + return raw; } @@ -264,30 +264,30 @@ Uint8 disk_pravetz_image_raw_byte(struct machine *oric, int drive, Uint16 t_id static Uint8 disk_pravetz_readbyte(struct machine *oric) { - struct pravetz_drive *drv = &oric->pravetz.drv[oric->wddisk.c_drive]; + struct pravetz_drive *drv = &oric->pravetz.drv[oric->wddisk.c_drive]; - /* make sure there's a 'disk in the drive' */ - if (!drv->pimg) - return 0xFF; + /* make sure there's a 'disk in the drive' */ + if(!drv->pimg) + return 0xFF; - disk_pravetz_update_position(drv); + disk_pravetz_update_position(drv); - /**/ + /**/ #if GENERAL_DISK_DEBUG - if(last_sector != drv->byte / PRAV_RAW_BYTES_PER_SECTOR || last_track != drv->half_track) - { - printf("{R} fdu: T:%.2d S:%.2X.%.3d [%.2X]\n", - drv->half_track / 2, - drv->byte / PRAV_RAW_BYTES_PER_SECTOR, - drv->byte % PRAV_RAW_BYTES_PER_SECTOR, - drv->image[drv->half_track / 2][drv->byte]); - last_sector = drv->byte / PRAV_RAW_BYTES_PER_SECTOR; - last_track = drv->half_track; - } + if(last_sector != drv->byte / PRAV_RAW_BYTES_PER_SECTOR || last_track != drv->half_track) + { + printf("{R} fdu: T:%.2d S:%.2X.%.3d [%.2X]\n", + drv->half_track / 2, + drv->byte / PRAV_RAW_BYTES_PER_SECTOR, + drv->byte % PRAV_RAW_BYTES_PER_SECTOR, + drv->image[drv->half_track / 2][drv->byte]); + last_sector = drv->byte / PRAV_RAW_BYTES_PER_SECTOR; + last_track = drv->half_track; + } #endif - /**/ + /**/ - return drv->image[drv->half_track / 2][drv->byte]; + return drv->image[drv->half_track / 2][drv->byte]; } /** @@ -297,149 +297,149 @@ static Uint8 disk_pravetz_readbyte(struct machine *oric) static Uint8 disk_pravetz_read_selected(struct machine *oric) { - struct pravetz_drive *drv = &oric->pravetz.drv[oric->wddisk.c_drive]; + struct pravetz_drive *drv = &oric->pravetz.drv[oric->wddisk.c_drive]; - if (!drv->write_ready) - { - drv->write_ready = 0x80; - } + if(!drv->write_ready) + { + drv->write_ready = 0x80; + } - switch (drv->select) - { + switch(drv->select) + { case 0: - return disk_pravetz_readbyte(oric); + return disk_pravetz_readbyte(oric); case 1: - return drv->prot | drv->motor_on; + return drv->prot | drv->motor_on; case 2: - return drv->write_ready; - } + return drv->write_ready; + } - return 0; + return 0; } static Uint8 temp_sector_buffer[PRAV_BYTES_PER_SECTOR + 2]; void disk_pravetz_write_image(struct pravetz_drive *d_ptr) { - Uint8 eor; - Uint8 s_idx; - - int sector_search_count; - - int t_idx; - int b_idx; - int tb_idx; - int sector_count, f_pos; - - if (!d_ptr) - return; - - if (!d_ptr->dirty) - return; - - tb_idx = 0; - for (t_idx = 0; t_idx < PRAV_TRACKS_PER_DISK; t_idx++) - { - sector_count = 16; + Uint8 eor; + Uint8 s_idx; -find_sector: + int sector_search_count; - /* look for the sector header */ + int t_idx; + int b_idx; + int tb_idx; + int sector_count, f_pos; - sector_search_count = 0; - while (0xD5 != d_ptr->image[t_idx][tb_idx]) - { - tb_idx = (tb_idx + 1) % PRAV_RAW_TRACK_SIZE; - if (++sector_search_count > PRAV_RAW_TRACK_SIZE) return; - } + if(!d_ptr) + return; - tb_idx = (tb_idx + 1) % PRAV_RAW_TRACK_SIZE; - if (0xAA != d_ptr->image[t_idx][tb_idx]) - { - tb_idx = (tb_idx + 1) % PRAV_RAW_TRACK_SIZE; - goto find_sector; - } + if(!d_ptr->dirty) + return; - tb_idx = (tb_idx + 1) % PRAV_RAW_TRACK_SIZE; - if (0x96 != d_ptr->image[t_idx][tb_idx]) - { - tb_idx = (tb_idx + 1) % PRAV_RAW_TRACK_SIZE; - goto find_sector; - } + tb_idx = 0; + for(t_idx = 0; t_idx < PRAV_TRACKS_PER_DISK; t_idx++) + { + sector_count = 16; + +find_sector: - /* found the sector header */ + /* look for the sector header */ - /* skip 'volume' and 'track' */ - tb_idx = (tb_idx + 5) % PRAV_RAW_TRACK_SIZE; + sector_search_count = 0; + while(0xD5 != d_ptr->image[t_idx][tb_idx]) + { + tb_idx = (tb_idx + 1) % PRAV_RAW_TRACK_SIZE; + if(++sector_search_count > PRAV_RAW_TRACK_SIZE) return; + } - /* sector byte #1 */ - s_idx = 0x55 | (d_ptr->image[t_idx][tb_idx] << 1); - tb_idx = (tb_idx + 1) % PRAV_RAW_TRACK_SIZE; - s_idx &= d_ptr->image[t_idx][tb_idx]; - tb_idx = (tb_idx + 1) % PRAV_RAW_TRACK_SIZE; + tb_idx = (tb_idx + 1) % PRAV_RAW_TRACK_SIZE; + if(0xAA != d_ptr->image[t_idx][tb_idx]) + { + tb_idx = (tb_idx + 1) % PRAV_RAW_TRACK_SIZE; + goto find_sector; + } - /* look for the sector data */ + tb_idx = (tb_idx + 1) % PRAV_RAW_TRACK_SIZE; + if(0x96 != d_ptr->image[t_idx][tb_idx]) + { + tb_idx = (tb_idx + 1) % PRAV_RAW_TRACK_SIZE; + goto find_sector; + } - while (0xD5 != d_ptr->image[t_idx][tb_idx]) - tb_idx = (tb_idx + 1) % PRAV_RAW_TRACK_SIZE; + /* found the sector header */ - tb_idx = (tb_idx + 1) % PRAV_RAW_TRACK_SIZE; - if (0xAA != d_ptr->image[t_idx][tb_idx]) - { - tb_idx = (tb_idx + 1) % PRAV_RAW_TRACK_SIZE; - goto find_sector; - } + /* skip 'volume' and 'track' */ + tb_idx = (tb_idx + 5) % PRAV_RAW_TRACK_SIZE; - tb_idx = (tb_idx + 1) % PRAV_RAW_TRACK_SIZE; - if (0xAD != d_ptr->image[t_idx][tb_idx]) - { - tb_idx = (tb_idx + 1) % PRAV_RAW_TRACK_SIZE; - goto find_sector; - } + /* sector byte #1 */ + s_idx = 0x55 | (d_ptr->image[t_idx][tb_idx] << 1); + tb_idx = (tb_idx + 1) % PRAV_RAW_TRACK_SIZE; + s_idx &= d_ptr->image[t_idx][tb_idx]; + tb_idx = (tb_idx + 1) % PRAV_RAW_TRACK_SIZE; - /* found the sector data */ + /* look for the sector data */ - tb_idx = (tb_idx + 1) % PRAV_RAW_TRACK_SIZE; - eor = 0; + while(0xD5 != d_ptr->image[t_idx][tb_idx]) + tb_idx = (tb_idx + 1) % PRAV_RAW_TRACK_SIZE; - for (b_idx = 0; b_idx < 342; b_idx++) - { - eor ^= translate[d_ptr->image[t_idx][tb_idx]]; - tb_idx = (tb_idx + 1) % PRAV_RAW_TRACK_SIZE; + tb_idx = (tb_idx + 1) % PRAV_RAW_TRACK_SIZE; + if(0xAA != d_ptr->image[t_idx][tb_idx]) + { + tb_idx = (tb_idx + 1) % PRAV_RAW_TRACK_SIZE; + goto find_sector; + } - if (b_idx >= 0x56) - { - /* 6 Bit */ - temp_sector_buffer[b_idx - 0x56] |= (eor << 2); - } - else - { - /* 3 * 2 Bit */ - temp_sector_buffer[b_idx] = (eor & 0x01) << 1; - temp_sector_buffer[b_idx] |= (eor & 0x02) >> 1; - temp_sector_buffer[b_idx + 0x56] = (eor & 0x04) >> 1; - temp_sector_buffer[b_idx + 0x56] |= (eor & 0x08) >> 3; - temp_sector_buffer[b_idx + 0xAC] = (eor & 0x10) >> 3; - temp_sector_buffer[b_idx + 0xAC] |= (eor & 0x20) >> 5; - } - } + tb_idx = (tb_idx + 1) % PRAV_RAW_TRACK_SIZE; + if(0xAD != d_ptr->image[t_idx][tb_idx]) + { + tb_idx = (tb_idx + 1) % PRAV_RAW_TRACK_SIZE; + goto find_sector; + } - /* write the sector */ - f_pos = (PRAV_BYTES_PER_SECTOR * PRAV_SECTORS_PER_TRACK * t_idx) + - (PRAV_BYTES_PER_SECTOR * interleave[s_idx]); + /* found the sector data */ - memcpy(&d_ptr->pimg->rawimage[f_pos], temp_sector_buffer, PRAV_BYTES_PER_SECTOR); - d_ptr->pimg->modified = SDL_TRUE; - d_ptr->pimg->modified_time = 0; - sector_count--; + tb_idx = (tb_idx + 1) % PRAV_RAW_TRACK_SIZE; + eor = 0; - if (sector_count) - goto find_sector; + for(b_idx = 0; b_idx < 342; b_idx++) + { + eor ^= translate[d_ptr->image[t_idx][tb_idx]]; + tb_idx = (tb_idx + 1) % PRAV_RAW_TRACK_SIZE; + + if(b_idx >= 0x56) + { + /* 6 Bit */ + temp_sector_buffer[b_idx - 0x56] |= (eor << 2); + } + else + { + /* 3 * 2 Bit */ + temp_sector_buffer[b_idx] = (eor & 0x01) << 1; + temp_sector_buffer[b_idx] |= (eor & 0x02) >> 1; + temp_sector_buffer[b_idx + 0x56] = (eor & 0x04) >> 1; + temp_sector_buffer[b_idx + 0x56] |= (eor & 0x08) >> 3; + temp_sector_buffer[b_idx + 0xAC] = (eor & 0x10) >> 3; + temp_sector_buffer[b_idx + 0xAC] |= (eor & 0x20) >> 5; + } } - d_ptr->dirty = SDL_FALSE; + /* write the sector */ + f_pos = (PRAV_BYTES_PER_SECTOR * PRAV_SECTORS_PER_TRACK * t_idx) + + (PRAV_BYTES_PER_SECTOR * interleave[s_idx]); + + memcpy(&d_ptr->pimg->rawimage[f_pos], temp_sector_buffer, PRAV_BYTES_PER_SECTOR); + d_ptr->pimg->modified = SDL_TRUE; + d_ptr->pimg->modified_time = 0; + sector_count--; + + if(sector_count) + goto find_sector; + } + + d_ptr->dirty = SDL_FALSE; } /** @@ -448,37 +448,37 @@ void disk_pravetz_write_image(struct pravetz_drive *d_ptr) static void disk_pravetz_writebyte(struct machine *oric, Uint8 w_byte) { - struct pravetz_drive *drv = &oric->pravetz.drv[oric->wddisk.c_drive]; - disk_pravetz_update_position(drv); + struct pravetz_drive *drv = &oric->pravetz.drv[oric->wddisk.c_drive]; + disk_pravetz_update_position(drv); - /* make sure there's a 'disk in the drive' */ - if (!drv->pimg) - return; + /* make sure there's a 'disk in the drive' */ + if(!drv->pimg) + return; - if (drv->prot) - return; + if(drv->prot) + return; - /* don't allow impossible bytes */ - if (w_byte < 0x96) - return; + /* don't allow impossible bytes */ + if(w_byte < 0x96) + return; - drv->dirty = SDL_TRUE; - drv->image[drv->half_track / 2][drv->byte] = w_byte; + drv->dirty = SDL_TRUE; + drv->image[drv->half_track / 2][drv->byte] = w_byte; - /**/ + /**/ #if GENERAL_DISK_DEBUG - if(last_sector != drv->byte / PRAV_RAW_BYTES_PER_SECTOR || last_track != drv->half_track) - { - printf("{W} fdu: T:%.2d S:%.2X.%.3d [%.2X]\n", - drv->half_track / 2, - drv->byte / PRAV_RAW_BYTES_PER_SECTOR, - drv->byte % PRAV_RAW_BYTES_PER_SECTOR, - w_byte); - last_sector = drv->byte / PRAV_RAW_BYTES_PER_SECTOR; - last_track = drv->half_track; - } + if(last_sector != drv->byte / PRAV_RAW_BYTES_PER_SECTOR || last_track != drv->half_track) + { + printf("{W} fdu: T:%.2d S:%.2X.%.3d [%.2X]\n", + drv->half_track / 2, + drv->byte / PRAV_RAW_BYTES_PER_SECTOR, + drv->byte % PRAV_RAW_BYTES_PER_SECTOR, + w_byte); + last_sector = drv->byte / PRAV_RAW_BYTES_PER_SECTOR; + last_track = drv->half_track; + } #endif - /**/ + /**/ } /** @@ -488,90 +488,90 @@ static void disk_pravetz_writebyte(struct machine *oric, Uint8 w_byte) static void disk_pravetz_write_selected(struct machine *oric, Uint8 w_byte) { - struct pravetz_drive *drv = &oric->pravetz.drv[oric->wddisk.c_drive]; + struct pravetz_drive *drv = &oric->pravetz.drv[oric->wddisk.c_drive]; - if (3 == drv->select) + if(3 == drv->select) + { + if(drv->motor_on) { - if (drv->motor_on) - { - if (drv->write_ready) - { - disk_pravetz_writebyte(oric, w_byte); - drv->write_ready = 0; - } - } + if(drv->write_ready) + { + disk_pravetz_writebyte(oric, w_byte); + drv->write_ready = 0; + } } + } } -static void disk_pravetz_switch (struct machine *oric, Uint16 addr) +static void disk_pravetz_switch(struct machine *oric, Uint16 addr) { - struct pravetz_drive *drv = &oric->pravetz.drv[oric->wddisk.c_drive]; + struct pravetz_drive *drv = &oric->pravetz.drv[oric->wddisk.c_drive]; - switch (addr & 0xF) - { + switch(addr & 0xF) + { case 0x08: - drv->motor_on = 0; - disk_pravetz_write_image(drv); - break; + drv->motor_on = 0; + disk_pravetz_write_image(drv); + break; case 0x09: - drv->motor_on = 0x20; - break; + drv->motor_on = 0x20; + break; /* select drive 0/1 */ case 0x0A: case 0x0B: - if (oric->wddisk.c_drive != (addr&1)) - { - disk_pravetz_write_image(drv); - oric->wddisk.c_drive = addr&1; - } - break; + if(oric->wddisk.c_drive != (addr&1)) + { + disk_pravetz_write_image(drv); + oric->wddisk.c_drive = addr&1; + } + break; case 0x0C: - drv->select &= 0xFE; - break; + drv->select &= 0xFE; + break; case 0x0D: - drv->select |= 0x01; - break; + drv->select |= 0x01; + break; case 0x0E: - drv->select &= 0xFD; - break; + drv->select &= 0xFD; + break; case 0x0F: - drv->select |= 0x02; - break; + drv->select |= 0x02; + break; default: - { + { int phase = (addr & 0x06) >> 1; /* move the head in and out by stepping motor */ - if (addr & 0x01) + if(addr & 0x01) { - phase += 4; - phase -= (drv->half_track % 4); - phase %= 4; + phase += 4; + phase -= (drv->half_track % 4); + phase %= 4; - if (1 == phase) + if(1 == phase) + { + if(drv->half_track < (2 * PRAV_TRACKS_PER_DISK - 2)) { - if (drv->half_track < (2 * PRAV_TRACKS_PER_DISK - 2)) - { - drv->half_track++; - } + drv->half_track++; } - else if (3 == phase) + } + else if(3 == phase) + { + if(drv->half_track > 0) { - if (drv->half_track > 0) - { - drv->half_track--; - } + drv->half_track--; } + } } - } - break; - } + } + break; + } } diff --git a/filereq.h b/filereq.h index 0cabefa2..f7f5e1e9 100644 --- a/filereq.h +++ b/filereq.h @@ -34,7 +34,7 @@ enum FR_OTHER }; -SDL_bool init_filerequester( struct machine *oric ); -void shut_filerequester( struct machine *oric ); -SDL_bool filerequester( struct machine *oric, char *title, char *path, char *fname, int type ); +SDL_bool init_filerequester(struct machine *oric); +void shut_filerequester(struct machine *oric); +SDL_bool filerequester(struct machine *oric, char* title, char* path, char* fname, int type); diff --git a/filereq_amiga.c b/filereq_amiga.c index e6164c68..29a8a0a0 100644 --- a/filereq_amiga.c +++ b/filereq_amiga.c @@ -46,44 +46,44 @@ static struct FileRequester *req = NULL; struct AslIFace *IAsl = NULL; #endif -SDL_bool init_filerequester( struct machine *oric ) +SDL_bool init_filerequester(struct machine *oric) { - AslBase = OpenLibrary( (CONST_STRPTR)AslName, 39 ); - if( !AslBase ) return SDL_FALSE; + AslBase = OpenLibrary((CONST_STRPTR)AslName, 39); + if(!AslBase) return SDL_FALSE; #ifdef __amigaos4__ - IAsl = (struct AslIFace *)GetInterface( AslBase, "main", 1, NULL ); - if( !IAsl ) return SDL_FALSE; + IAsl = (struct AslIFace *)GetInterface(AslBase, "main", 1, NULL); + if(!IAsl) return SDL_FALSE; #endif - req = (struct FileRequester *)AllocAslRequestTags( ASL_FileRequest, TAG_DONE ); - if( !req ) return SDL_FALSE; + req = (struct FileRequester *)AllocAslRequestTags(ASL_FileRequest, TAG_DONE); + if(!req) return SDL_FALSE; return SDL_TRUE; } -void shut_filerequester( struct machine *oric ) +void shut_filerequester(struct machine *oric) { - if( req ) FreeAslRequest( req ); + if(req) FreeAslRequest(req); #ifdef __amigaos4__ - if( IAsl ) DropInterface( (struct Interface *)IAsl ); + if(IAsl) DropInterface((struct Interface *)IAsl); #endif - if( AslBase ) CloseLibrary( AslBase ); + if(AslBase) CloseLibrary(AslBase); } -SDL_bool filerequester( struct machine *oric, char *title, char *path, char *fname, int type ) +SDL_bool filerequester(struct machine *oric, char* title, char* path, char* fname, int type) { - char *pat, ppat[16*2+2]; + char* pat, ppat[16*2+2]; BOOL dosavemode = FALSE; - - switch( type ) + + switch(type) { case FR_DISKSAVE: dosavemode = TRUE; case FR_DISKLOAD: pat = "#?.dsk"; break; - + case FR_TAPESAVETAP: dosavemode = TRUE; pat = "#?.tap"; @@ -97,7 +97,7 @@ SDL_bool filerequester( struct machine *oric, char *title, char *path, char *fna case FR_TAPELOAD: pat = "#?.(tap|ort|wav)"; break; - + case FR_ROMS: pat = "#?.rom"; break; @@ -107,35 +107,37 @@ SDL_bool filerequester( struct machine *oric, char *title, char *path, char *fna case FR_SNAPSHOTLOAD: pat = "#?.sna"; break; - + case FR_KEYMAPPINGSAVE: - dosavemode = TRUE; + dosavemode = TRUE; case FR_KEYMAPPINGLOAD: - pat = "#?.kma"; - break; - + pat = "#?.kma"; + break; + default: pat = NULL; break; } - - if( pat ) ParsePatternNoCase( (CONST_STRPTR)pat, (UBYTE *)ppat, 16*2+2 ); - - if( !AslRequestTags( req, - ASLFR_TitleText, title, - ASLFR_InitialDrawer, path, - ASLFR_InitialFile, fname, - ASLFR_DoPatterns, pat != NULL, - ASLFR_RejectIcons, TRUE, - ASLFR_DoSaveMode, dosavemode, - pat ? ASLFR_AcceptPattern : TAG_IGNORE, ppat, - pat ? ASLFR_InitialPattern : TAG_IGNORE, pat, - TAG_DONE ) ) + + if(pat) ParsePatternNoCase((CONST_STRPTR)pat, (UBYTE *)ppat, 16*2+2); + + if(!AslRequestTags(req, + ASLFR_TitleText, title, + ASLFR_InitialDrawer, path, + ASLFR_InitialFile, fname, + ASLFR_DoPatterns, pat != NULL, + ASLFR_RejectIcons, TRUE, + ASLFR_DoSaveMode, dosavemode, + pat ? ASLFR_AcceptPattern : TAG_IGNORE, ppat, + pat ? ASLFR_InitialPattern : TAG_IGNORE, pat, + TAG_DONE)) return SDL_FALSE; - - strncpy( path, (const char *)req->fr_Drawer, 4096 ); path[4095] = 0; - strncpy( fname, (const char *)req->fr_File, 512 ); fname[511] = 0; - + + strncpy(path, (const char*)req->fr_Drawer, 4096); + path[4095] = 0; + strncpy(fname, (const char*)req->fr_File, 512); + fname[511] = 0; + return SDL_TRUE; } diff --git a/filereq_beos.cpp b/filereq_beos.cpp index dedf78db..9f41f35b 100644 --- a/filereq_beos.cpp +++ b/filereq_beos.cpp @@ -43,85 +43,93 @@ extern "C" { } -class PanelLooper : public BLooper { -public: - PanelLooper(); - virtual ~PanelLooper(); - virtual void MessageReceived(BMessage* message); - - void Wait(); - SDL_bool DoIt() const { return fDoIt; }; - void GetRef(entry_ref &ref) const { ref = fRef; }; - -private: - sem_id fSem; - entry_ref fRef; - SDL_bool fDoIt; +class PanelLooper : public BLooper +{ + public: + PanelLooper(); + virtual ~PanelLooper(); + virtual void MessageReceived(BMessage* message); + + void Wait(); + SDL_bool DoIt() const + { + return fDoIt; + }; + void GetRef(entry_ref &ref) const + { + ref = fRef; + }; + + private: + sem_id fSem; + entry_ref fRef; + SDL_bool fDoIt; }; PanelLooper::PanelLooper() - : BLooper("PanelLooper"), - fDoIt(SDL_FALSE) + : BLooper("PanelLooper"), + fDoIt(SDL_FALSE) { - fSem = create_sem(0, "PanelLooper lock"); + fSem = create_sem(0, "PanelLooper lock"); } PanelLooper::~PanelLooper() { - delete_sem(fSem); + delete_sem(fSem); } void PanelLooper::MessageReceived(BMessage* message) { - //message->PrintToStream(); - switch (message->what) { - case B_SAVE_REQUESTED: - message->FindRef("refs", &fRef); - fDoIt = SDL_TRUE; - break; - case B_REFS_RECEIVED: - message->FindRef("refs", &fRef); - fDoIt = SDL_TRUE; - break; - case B_CANCEL: - default: - break; - } - release_sem(fSem); + //message->PrintToStream(); + switch(message->what) + { + case B_SAVE_REQUESTED: + message->FindRef("refs", &fRef); + fDoIt = SDL_TRUE; + break; + case B_REFS_RECEIVED: + message->FindRef("refs", &fRef); + fDoIt = SDL_TRUE; + break; + case B_CANCEL: + default: + break; + } + release_sem(fSem); } void PanelLooper::Wait() { - acquire_sem(fSem); + acquire_sem(fSem); } -SDL_bool init_filerequester( struct machine *oric ) +SDL_bool init_filerequester(struct machine *oric) { return SDL_TRUE; } -void shut_filerequester( struct machine *oric ) +void shut_filerequester(struct machine *oric) { } -SDL_bool filerequester( struct machine *oric, char *title, char *path, char *fname, int type ) +SDL_bool filerequester(struct machine *oric, char* title, char* path, char* fname, int type) { - BFilePanel *panel; - PanelLooper *looper = new PanelLooper(); - looper->Run(); - SDL_bool ret; + BFilePanel *panel; + PanelLooper *looper = new PanelLooper(); + looper->Run(); + SDL_bool ret; - char *pat; + char* pat; bool dosavemode = false; - - switch( type ) + + switch(type) { case FR_DISKSAVE: dosavemode = true; @@ -136,7 +144,7 @@ SDL_bool filerequester( struct machine *oric, char *title, char *path, char *fna case FR_TAPELOAD: pat = "*.tap"; break; - + case FR_ROMS: pat = "*.rom"; break; @@ -146,42 +154,45 @@ SDL_bool filerequester( struct machine *oric, char *title, char *path, char *fna case FR_SNAPSHOTLOAD: pat = "*.sna"; break; - + case FR_KEYMAPPINGSAVE: - dosavemode = true; + dosavemode = true; case FR_KEYMAPPINGLOAD: - pat = "*.kma"; - break; - + pat = "*.kma"; + break; + default: pat = NULL; break; } - //XXX: use RefFilter + //XXX: use RefFilter + + panel = new BFilePanel(dosavemode ? B_SAVE_PANEL : B_OPEN_PANEL); + panel->SetTarget(BMessenger(looper)); - panel = new BFilePanel(dosavemode ? B_SAVE_PANEL : B_OPEN_PANEL); - panel->SetTarget(BMessenger(looper)); + if(path) + panel->SetPanelDirectory(path); - if (path) - panel->SetPanelDirectory(path); + panel->Show(); - panel->Show(); + looper->Wait(); + ret = looper->DoIt(); + entry_ref ref; + looper->GetRef(ref); - looper->Wait(); - ret = looper->DoIt(); - entry_ref ref; - looper->GetRef(ref); - - delete panel; - looper->Lock(); - looper->Quit(); - - if (ret) { + delete panel; + looper->Lock(); + looper->Quit(); + + if(ret) + { BPath p(&ref); - strncpy( fname, p.Leaf(), 512 ); path[511] = 0; + strncpy(fname, p.Leaf(), 512); + path[511] = 0; p.GetParent(&p); - strncpy( path, p.Path(), 4096 ); path[4095] = 0; + strncpy(path, p.Path(), 4096); + path[4095] = 0; } return ret; diff --git a/filereq_gtk.c b/filereq_gtk.c index 83152fe2..a47c1fab 100644 --- a/filereq_gtk.c +++ b/filereq_gtk.c @@ -40,15 +40,15 @@ #include "filereq.h" extern SDL_bool fullscreen; -void togglefullscreen( struct machine *oric, struct osdmenuitem *mitem, int dummy ); +void togglefullscreen(struct machine *oric, struct osdmenuitem *mitem, int dummy); -SDL_bool init_filerequester( struct machine *oric ) +SDL_bool init_filerequester(struct machine *oric) { gtk_init(0, NULL); return SDL_TRUE; } -void shut_filerequester( struct machine *oric ) +void shut_filerequester(struct machine *oric) { } @@ -57,8 +57,8 @@ void shut_filerequester( struct machine *oric ) // path = initial path to show // fname = initial contents of the filename textbox // It returns true if the user selected a file, although the file is not -// guarranteed to exist. -SDL_bool filerequester( struct machine *oric, char *title, char *path, char *fname, int type ) +// guaranteed to exist. +SDL_bool filerequester(struct machine *oric, char* title, char* path, char* fname, int type) { GtkWidget *dialog; SDL_bool result = SDL_FALSE; @@ -66,13 +66,13 @@ SDL_bool filerequester( struct machine *oric, char *title, char *path, char *fna GtkFileFilter *filter = NULL, *allfilter = gtk_file_filter_new(); SDL_bool was_fullscreen = fullscreen; - if (fullscreen) + if(fullscreen) togglefullscreen(oric, NULL, 0); gtk_file_filter_set_name(allfilter, "All files"); gtk_file_filter_add_pattern(allfilter, "*"); - switch( type ) + switch(type) { case FR_DISKSAVE: action = GTK_FILE_CHOOSER_ACTION_SAVE; @@ -119,7 +119,7 @@ SDL_bool filerequester( struct machine *oric, char *title, char *path, char *fna break; case FR_KEYMAPPINGSAVE: - action = GTK_FILE_CHOOSER_ACTION_SAVE; + action = GTK_FILE_CHOOSER_ACTION_SAVE; case FR_KEYMAPPINGLOAD: filter = gtk_file_filter_new(); gtk_file_filter_set_name(filter, "Keyboard Mapping files"); @@ -143,36 +143,38 @@ SDL_bool filerequester( struct machine *oric, char *title, char *path, char *fna NULL); gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), path); - if (action == GTK_FILE_CHOOSER_ACTION_SAVE) + if(action == GTK_FILE_CHOOSER_ACTION_SAVE) gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), fname); - if (filter) + if(filter) gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter); gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), allfilter); - if (gtk_dialog_run(GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) + if(gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { - char *filename; + char* filename; int i; - filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)); - strncpy( path, filename, 4096 ); path[4095] = 0; + filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); + strncpy(path, filename, 4096); + path[4095] = 0; i = strlen(path)-1; - while (i >= 0) + while(i >= 0) { - if (path[i] == PATHSEP) break; + if(path[i] == PATHSEP) break; i--; } - strncpy( fname, &path[i+1], 512 ); fname[511] = 0; + strncpy(fname, &path[i+1], 512); + fname[511] = 0; path[i+1] = 0; g_free(filename); result = SDL_TRUE; } gtk_widget_destroy(dialog); - while (gtk_events_pending()) + while(gtk_events_pending()) gtk_main_iteration(); - if (was_fullscreen) + if(was_fullscreen) togglefullscreen(oric, NULL, 0); return result; diff --git a/filereq_osx.m b/filereq_osx.m index fb5a6b3f..a672abf9 100644 --- a/filereq_osx.m +++ b/filereq_osx.m @@ -37,6 +37,13 @@ #include "machine.h" #include "filereq.h" +#ifndef MAC_OS_X_VERSION_10_9 +#define MAC_OS_X_VERSION_10_9 1090 +#endif + +#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_9 +#define NSModalResponseOK NSFileHandlingPanelOKButton +#endif SDL_bool init_filerequester( struct machine *oric ) { @@ -128,7 +135,7 @@ SDL_bool filerequester( struct machine *oric, char *title, char *path, char *fna } } - ret = [sp runModal] == NSAlertDefaultReturn; + ret = [sp runModal] == NSModalResponseOK; if (!ret) return ret; diff --git a/filereq_sdl.c b/filereq_sdl.c index 82a0c8b3..f501b35c 100644 --- a/filereq_sdl.c +++ b/filereq_sdl.c @@ -40,6 +40,10 @@ #include "machine.h" #include "filereq.h" +#ifdef WWW +#include +#endif + // Externs extern SDL_Surface *screen; extern struct textzone *tz[NUM_TZ]; @@ -55,55 +59,55 @@ struct frq_ent // A text input box (used in the file requester) struct frq_textbox { - char *buf; + char* buf; int x, y, w; int maxlen, slen, cpos, vpos; }; // The actual text box structures used by the file requester static struct frq_textbox freqf_tbox[] = { { NULL, 7, 28, 32, 4096, 0, 0, 0 }, - { NULL, 7, 30, 32, 512, 0, 0, 0 } }; + { NULL, 7, 30, 32, 512, 0, 0, 0 } +}; // File requester state static int freqf_size=0, freqf_used=0, freqf_cgad=2; static struct frq_ent *freqfiles=NULL; static int freqf_clicktime=0; -SDL_bool init_filerequester( struct machine *oric ) +SDL_bool init_filerequester(struct machine *oric) { - if( !alloc_textzone( oric, TZ_FILEREQ, 160, 48, 40, 32, "Files" ) ) return SDL_FALSE; + if(!alloc_textzone(oric, TZ_FILEREQ, 160, 48, 40, 32, "Files")) return SDL_FALSE; return SDL_TRUE; } -void shut_filerequester( struct machine *oric ) +void shut_filerequester(struct machine *oric) { - free_textzone( oric, TZ_FILEREQ ); + free_textzone(oric, TZ_FILEREQ); } // Render the filerequester -static void filereq_render( struct machine *oric ) +static void filereq_render(struct machine *oric) { - oric->render_begin( oric ); + oric->render_begin(oric); - oric->render_video( oric, SDL_TRUE ); - oric->render_textzone( oric, TZ_FILEREQ ); - - oric->render_end( oric ); + oric->render_video(oric, SDL_TRUE); + oric->render_textzone(oric, TZ_FILEREQ); + oric->render_end(oric); } // Add a file to the list of files to show in the file requester -static void filereq_addent( SDL_bool isdir, char *name, char *showname ) +static void filereq_addent(SDL_bool isdir, char* name, char* showname) { struct frq_ent *tmpf; int i, j; // No file buffer yet, or file buffer full? - if( ( !freqfiles ) || ( freqf_used >= freqf_size ) ) + if((!freqfiles) || (freqf_used >= freqf_size)) { // (re)allocate it! - tmpf = (struct frq_ent *)realloc( freqfiles, sizeof( struct frq_ent ) * (freqf_size+8) ); - if( !tmpf ) return; + tmpf = (struct frq_ent *)realloc(freqfiles, sizeof(struct frq_ent) * (freqf_size+8)); + if(!tmpf) return; freqfiles = tmpf; freqf_size += 8; @@ -111,35 +115,37 @@ static void filereq_addent( SDL_bool isdir, char *name, char *showname ) // Get the point to insert it j = 0; - if( freqf_used > 0 ) + if(freqf_used > 0) { - if( isdir ) + if(isdir) { - for( j=1; jj; i-- ) + for(i=freqf_used; i>j; i--) freqfiles[i] = freqfiles[i-1]; } } // Fill in this structure freqfiles[j].isdir = isdir; - strncpy( freqfiles[j].name, name, 512 ); - strncpy( freqfiles[j].showname, showname, 38 ); + strncpy(freqfiles[j].name, name, 512); + strncpy(freqfiles[j].showname, showname, 38); freqfiles[j].name[511] = 0; freqfiles[j].showname[37] = 0; @@ -148,85 +154,85 @@ static void filereq_addent( SDL_bool isdir, char *name, char *showname ) } // Scan a directory to show in the filerequester -static SDL_bool filereq_scan( char *path ) +static SDL_bool filereq_scan(char* path) { DIR *dh; struct dirent *de; struct stat sb; - char *odir, *tpath; + char* odir, *tpath; tpath = path; #ifndef __amigaos4__ - if( !path[0] ) + if(!path[0]) tpath = "."; #endif freqf_used = 0; - dh = opendir( tpath ); - if( !dh ) return SDL_FALSE; + dh = opendir(tpath); + if(!dh) return SDL_FALSE; - odir = getcwd( NULL, 0 ); - chdir( tpath ); + odir = getcwd(NULL, 0); + chdir(tpath); - filereq_addent( SDL_TRUE, "", "[Parent]" ); + filereq_addent(SDL_TRUE, "", "[Parent]"); - while( ( de = readdir( dh ) ) ) + while((de = readdir(dh))) { - if( ( strcmp( de->d_name, "." ) == 0 ) || - ( strcmp( de->d_name, ".." ) == 0 ) ) + if((strcmp(de->d_name, ".") == 0) || + (strcmp(de->d_name, "..") == 0)) continue; - stat( de->d_name, &sb ); - filereq_addent( S_ISDIR(sb.st_mode), de->d_name, de->d_name ); + stat(de->d_name, &sb); + filereq_addent(S_ISDIR(sb.st_mode), de->d_name, de->d_name); } - closedir( dh ); + closedir(dh); - chdir( odir ); - free( odir ); + chdir(odir); + free(odir); return SDL_TRUE; } // Render the file list into the filerequester textzone -static void filereq_showfiles( int offset, int cfile ) +static void filereq_showfiles(int offset, int cfile) { int i, j, o; // If the listview isn't selected, don't show a current file - if( freqf_cgad != 2 ) + if(freqf_cgad != 2) cfile = -1; - for( i=0; i<26; i++ ) + for(i=0; i<26; i++) { // Set the colours - if( (i+offset) < freqf_used ) - tzsetcol( tz[TZ_FILEREQ], freqfiles[i+offset].isdir ? 1 : 0, (i+offset)==cfile ? 7 : 6 ); + if((i+offset) < freqf_used) + tzsetcol(tz[TZ_FILEREQ], freqfiles[i+offset].isdir ? 1 : 0, (i+offset)==cfile ? 7 : 6); else - tzsetcol( tz[TZ_FILEREQ], 0, 6 ); + tzsetcol(tz[TZ_FILEREQ], 0, 6); // Clear this line o = (i+1)*tz[TZ_FILEREQ]->w+1; - for( j=0; j<38; j++, o++ ) + for(j=0; j<38; j++, o++) { tz[TZ_FILEREQ]->fc[o] = tz[TZ_FILEREQ]->cfc; tz[TZ_FILEREQ]->bc[o] = tz[TZ_FILEREQ]->cbc; tz[TZ_FILEREQ]->tx[o] = 32; } - if( (i+offset) >= freqf_used ) + if((i+offset) >= freqf_used) continue; // Print the name - tzstrpos( tz[TZ_FILEREQ], 1, i+1, freqfiles[i+offset].showname ); + tzstrpos(tz[TZ_FILEREQ], 1, i+1, freqfiles[i+offset].showname); } } // Set a filerequester textbox contents to the specified string -static void filereq_settbox( struct frq_textbox *tb, char *buf ) +static void filereq_settbox(struct frq_textbox *tb, char* buf) { // Set up the buffer tb->buf = buf; - tb->slen = strlen( buf ); + tb->slen = strlen(buf); // Make sure the cursor is in view tb->cpos = tb->slen; @@ -234,23 +240,25 @@ static void filereq_settbox( struct frq_textbox *tb, char *buf ) } // Draw a textbox into the filerequester textzone -static void filereq_drawtbox( struct frq_textbox *tb, SDL_bool active ) +static void filereq_drawtbox(struct frq_textbox *tb, SDL_bool active) { int i, j, o; - tzsetcol( tz[TZ_FILEREQ], 0, active ? 7 : 6 ); + tzsetcol(tz[TZ_FILEREQ], 0, active ? 7 : 6); o = (tb->y*tz[TZ_FILEREQ]->w)+tb->x; - for( i=0,j=tb->vpos; iw; i++, o++, j++ ) + for(i=0,j=tb->vpos; iw; i++, o++, j++) { - if( ( active ) && ( j==tb->cpos ) ) + if((active) && (j==tb->cpos)) { tz[TZ_FILEREQ]->fc[o] = tz[TZ_FILEREQ]->cbc; tz[TZ_FILEREQ]->bc[o] = tz[TZ_FILEREQ]->cfc; - } else { + } + else + { tz[TZ_FILEREQ]->fc[o] = tz[TZ_FILEREQ]->cfc; tz[TZ_FILEREQ]->bc[o] = tz[TZ_FILEREQ]->cbc; } - if( j < tb->slen ) + if(j < tb->slen) tz[TZ_FILEREQ]->tx[o] = tb->buf[j]; else tz[TZ_FILEREQ]->tx[o] = 32; @@ -259,10 +267,10 @@ static void filereq_drawtbox( struct frq_textbox *tb, SDL_bool active ) // This sets the file textbox to the currently highlighted file // It also stores the filename in "fname" -static void filereq_setfiletbox( int cfile, char *fname ) +static void filereq_setfiletbox(int cfile, char* fname) { - if( ( cfile < 0 ) || ( cfile >= freqf_used ) || - ( freqfiles[cfile].isdir ) ) + if((cfile < 0) || (cfile >= freqf_used) || + (freqfiles[cfile].isdir)) { fname[0] = 0; freqf_tbox[1].cpos=0; @@ -271,9 +279,9 @@ static void filereq_setfiletbox( int cfile, char *fname ) return; } - strncpy( fname, freqfiles[cfile].name, 512 ); + strncpy(fname, freqfiles[cfile].name, 512); fname[511] = 0; - filereq_settbox( &freqf_tbox[1], fname ); + filereq_settbox(&freqf_tbox[1], fname); } enum @@ -289,8 +297,8 @@ enum // path = initial path to show // fname = initial contents of the filename textbox // It returns true if the user selected a file, although the file is not -// guarranteed to exist. -SDL_bool filerequester( struct machine *oric, char *title, char *path, char *fname, int type ) +// guaranteed to exist. +SDL_bool filerequester(struct machine *oric, char* title, char* path, char* fname, int type) { SDL_Event event; struct frq_textbox *tb; @@ -298,50 +306,60 @@ SDL_bool filerequester( struct machine *oric, char *title, char *path, char *fna SDL_bool shifty = SDL_FALSE, wasunicode; int doaction; - wasunicode = SDL_COMPAT_EnableUNICODE( SDL_TRUE ); - SDL_COMPAT_EnableKeyRepeat( SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL ); + wasunicode = SDL_COMPAT_EnableUNICODE(SDL_TRUE); + SDL_COMPAT_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL); - filereq_settbox( &freqf_tbox[0], path ); - filereq_settbox( &freqf_tbox[1], fname ); + filereq_settbox(&freqf_tbox[0], path); + filereq_settbox(&freqf_tbox[1], fname); - tzsettitle( tz[TZ_FILEREQ], title ); - tzsetcol( tz[TZ_FILEREQ], 2, 3 ); - tzstrpos( tz[TZ_FILEREQ], 1, 28, "Path:" ); - tzstrpos( tz[TZ_FILEREQ], 1, 30, "File:" ); + tzsettitle(tz[TZ_FILEREQ], title); + tzsetcol(tz[TZ_FILEREQ], 2, 3); + tzstrpos(tz[TZ_FILEREQ], 1, 28, "Path:"); + tzstrpos(tz[TZ_FILEREQ], 1, 30, "File:"); - if( !filereq_scan( path ) ) + if(!filereq_scan(path)) { - if( path[0] ) + if(path[0]) { path[0] = 0; - filereq_settbox( &freqf_tbox[0], path ); - if( !filereq_scan( path ) ) + filereq_settbox(&freqf_tbox[0], path); + if(!filereq_scan(path)) { - SDL_COMPAT_EnableUNICODE( wasunicode ); - SDL_COMPAT_EnableKeyRepeat( wasunicode ? SDL_DEFAULT_REPEAT_DELAY : 0, wasunicode ? SDL_DEFAULT_REPEAT_INTERVAL : 0 ); + SDL_COMPAT_EnableUNICODE(wasunicode); + SDL_COMPAT_EnableKeyRepeat(wasunicode ? SDL_DEFAULT_REPEAT_DELAY : 0, wasunicode ? SDL_DEFAULT_REPEAT_INTERVAL : 0); return SDL_FALSE; } - } else { - SDL_COMPAT_EnableUNICODE( wasunicode ); - SDL_COMPAT_EnableKeyRepeat( wasunicode ? SDL_DEFAULT_REPEAT_DELAY : 0, wasunicode ? SDL_DEFAULT_REPEAT_INTERVAL : 0 ); + } + else + { + SDL_COMPAT_EnableUNICODE(wasunicode); + SDL_COMPAT_EnableKeyRepeat(wasunicode ? SDL_DEFAULT_REPEAT_DELAY : 0, wasunicode ? SDL_DEFAULT_REPEAT_INTERVAL : 0); return SDL_FALSE; } } - filereq_showfiles( top, cfile ); - filereq_drawtbox( &freqf_tbox[0], freqf_cgad==0 ); - filereq_drawtbox( &freqf_tbox[1], freqf_cgad==1 ); - filereq_render( oric ); + filereq_showfiles(top, cfile); + filereq_drawtbox(&freqf_tbox[0], freqf_cgad==0); + filereq_drawtbox(&freqf_tbox[1], freqf_cgad==1); + filereq_render(oric); - for( ;; ) + for(;;) { - if( !SDL_WaitEvent( &event ) ) +#ifdef WWW + if(!SDL_PollEvent(&event)) + { + emscripten_sleep(10); + continue; + } +#else + if(!SDL_WaitEvent(&event)) break; +#endif mx = -1; my = -1; mclick = 0; doaction = ACTION_NONE; - switch( event.type ) + switch(event.type) { case SDL_MOUSEMOTION: mx = (event.motion.x - tz[TZ_FILEREQ]->x)/8; @@ -349,7 +367,7 @@ SDL_bool filerequester( struct machine *oric, char *title, char *path, char *fna break; case SDL_MOUSEBUTTONDOWN: - if( event.button.button == SDL_BUTTON_LEFT ) + if(event.button.button == SDL_BUTTON_LEFT) { mx = (event.button.x - tz[TZ_FILEREQ]->x)/8; my = (event.button.y - tz[TZ_FILEREQ]->y)/12; @@ -358,49 +376,64 @@ SDL_bool filerequester( struct machine *oric, char *title, char *path, char *fna break; } - switch( event.type ) + switch(event.type) { case SDL_COMPAT_ACTIVEEVENT: - if(SDL_COMPAT_IsAppFocused( &event ) ) { - filereq_render( oric ); + if(SDL_COMPAT_IsAppFocused(&event)) + { + filereq_render(oric); } break; case SDL_MOUSEBUTTONDOWN: - if( ( mx < 1 ) || ( mx > 38 ) ) + if((mx < 1) || (mx > 38)) + { +#ifdef WWW + SDL_COMPAT_EnableUNICODE(wasunicode); + SDL_COMPAT_EnableKeyRepeat(wasunicode ? SDL_DEFAULT_REPEAT_DELAY : 0, wasunicode ? SDL_DEFAULT_REPEAT_INTERVAL : 0); + return SDL_FALSE; +#endif break; + } - if( ( my == 28 ) || ( my == 30 ) ) + if((my == 28) || (my == 30)) { freqf_cgad = (my-28)/2; - filereq_showfiles( top, cfile ); - filereq_drawtbox( &freqf_tbox[0], freqf_cgad==0 ); - filereq_drawtbox( &freqf_tbox[1], freqf_cgad==1 ); - filereq_render( oric ); + filereq_showfiles(top, cfile); + filereq_drawtbox(&freqf_tbox[0], freqf_cgad==0); + filereq_drawtbox(&freqf_tbox[1], freqf_cgad==1); + filereq_render(oric); break; } - if( ( my < 1 ) || ( my > 26 ) ) + if((my < 1) || (my > 26)) + { +#ifdef WWW + SDL_COMPAT_EnableUNICODE(wasunicode); + SDL_COMPAT_EnableKeyRepeat(wasunicode ? SDL_DEFAULT_REPEAT_DELAY : 0, wasunicode ? SDL_DEFAULT_REPEAT_INTERVAL : 0); + return SDL_FALSE; +#endif break; + } freqf_cgad = 2; i = (my-1)-top; - if( i >= freqf_used ) i = freqf_used-1; + if(i >= freqf_used) i = freqf_used-1; - if( cfile != i ) + if(cfile != i) { cfile = i; - filereq_setfiletbox( cfile, fname ); - filereq_showfiles( top, cfile ); - filereq_drawtbox( &freqf_tbox[1], 0 ); - filereq_render( oric ); + filereq_setfiletbox(cfile, fname); + filereq_showfiles(top, cfile); + filereq_drawtbox(&freqf_tbox[1], 0); + filereq_render(oric); freqf_clicktime = mclick; break; } - if( ( freqf_clicktime == 0 ) || - ( (mclick-freqf_clicktime) >= 2000 ) ) + if((freqf_clicktime == 0) || + ((mclick-freqf_clicktime) >= 2000)) { freqf_clicktime = mclick; break; @@ -411,7 +444,7 @@ SDL_bool filerequester( struct machine *oric, char *title, char *path, char *fna break; case SDL_KEYUP: - switch( event.key.keysym.sym ) + switch(event.key.keysym.sym) { case SDLK_LSHIFT: case SDLK_RSHIFT: @@ -419,43 +452,45 @@ SDL_bool filerequester( struct machine *oric, char *title, char *path, char *fna break; case SDLK_ESCAPE: - SDL_COMPAT_EnableUNICODE( wasunicode ); - SDL_COMPAT_EnableKeyRepeat( wasunicode ? SDL_DEFAULT_REPEAT_DELAY : 0, wasunicode ? SDL_DEFAULT_REPEAT_INTERVAL : 0 ); + SDL_COMPAT_EnableUNICODE(wasunicode); + SDL_COMPAT_EnableKeyRepeat(wasunicode ? SDL_DEFAULT_REPEAT_DELAY : 0, wasunicode ? SDL_DEFAULT_REPEAT_INTERVAL : 0); return SDL_FALSE; case SDLK_RETURN: case SDLK_KP_ENTER: - switch( freqf_cgad ) + switch(freqf_cgad) { case 0: cfile = top = 0; - if( !filereq_scan( path ) ) + if(!filereq_scan(path)) { - if( path[0] ) + if(path[0]) { path[0] = 0; - filereq_settbox( &freqf_tbox[0], path ); - if( !filereq_scan( path ) ) + filereq_settbox(&freqf_tbox[0], path); + if(!filereq_scan(path)) { - SDL_COMPAT_EnableUNICODE( wasunicode ); - SDL_COMPAT_EnableKeyRepeat( wasunicode ? SDL_DEFAULT_REPEAT_DELAY : 0, wasunicode ? SDL_DEFAULT_REPEAT_INTERVAL : 0 ); + SDL_COMPAT_EnableUNICODE(wasunicode); + SDL_COMPAT_EnableKeyRepeat(wasunicode ? SDL_DEFAULT_REPEAT_DELAY : 0, wasunicode ? SDL_DEFAULT_REPEAT_INTERVAL : 0); return SDL_FALSE; } - } else { - SDL_COMPAT_EnableUNICODE( wasunicode ); - SDL_COMPAT_EnableKeyRepeat( wasunicode ? SDL_DEFAULT_REPEAT_DELAY : 0, wasunicode ? SDL_DEFAULT_REPEAT_INTERVAL : 0 ); + } + else + { + SDL_COMPAT_EnableUNICODE(wasunicode); + SDL_COMPAT_EnableKeyRepeat(wasunicode ? SDL_DEFAULT_REPEAT_DELAY : 0, wasunicode ? SDL_DEFAULT_REPEAT_INTERVAL : 0); return SDL_FALSE; } } - filereq_showfiles( top, cfile ); - filereq_drawtbox( &freqf_tbox[0], freqf_cgad==0 ); - filereq_drawtbox( &freqf_tbox[1], freqf_cgad==1 ); - filereq_render( oric ); + filereq_showfiles(top, cfile); + filereq_drawtbox(&freqf_tbox[0], freqf_cgad==0); + filereq_drawtbox(&freqf_tbox[1], freqf_cgad==1); + filereq_render(oric); break; case 1: - SDL_COMPAT_EnableUNICODE( wasunicode ); - SDL_COMPAT_EnableKeyRepeat( wasunicode ? SDL_DEFAULT_REPEAT_DELAY : 0, wasunicode ? SDL_DEFAULT_REPEAT_INTERVAL : 0 ); + SDL_COMPAT_EnableUNICODE(wasunicode); + SDL_COMPAT_EnableKeyRepeat(wasunicode ? SDL_DEFAULT_REPEAT_DELAY : 0, wasunicode ? SDL_DEFAULT_REPEAT_INTERVAL : 0); return SDL_TRUE; case 2: @@ -470,7 +505,7 @@ SDL_bool filerequester( struct machine *oric, char *title, char *path, char *fna break; case SDL_KEYDOWN: - switch( event.key.keysym.sym ) + switch(event.key.keysym.sym) { case SDLK_LSHIFT: case SDLK_RSHIFT: @@ -478,74 +513,74 @@ SDL_bool filerequester( struct machine *oric, char *title, char *path, char *fna break; case SDLK_TAB: - if( shifty ) + if(shifty) freqf_cgad = (freqf_cgad+2)%3; else freqf_cgad = (freqf_cgad+1)%3; - filereq_showfiles( top, cfile ); - filereq_drawtbox( &freqf_tbox[0], freqf_cgad==0 ); - filereq_drawtbox( &freqf_tbox[1], freqf_cgad==1 ); - filereq_render( oric ); + filereq_showfiles(top, cfile); + filereq_drawtbox(&freqf_tbox[0], freqf_cgad==0); + filereq_drawtbox(&freqf_tbox[1], freqf_cgad==1); + filereq_render(oric); break; case SDLK_UP: - if( freqf_cgad != 2 ) + if(freqf_cgad != 2) { freqf_cgad = 2; - filereq_showfiles( top, cfile ); - filereq_drawtbox( &freqf_tbox[0], freqf_cgad==0 ); - filereq_drawtbox( &freqf_tbox[1], freqf_cgad==1 ); - filereq_render( oric ); + filereq_showfiles(top, cfile); + filereq_drawtbox(&freqf_tbox[0], freqf_cgad==0); + filereq_drawtbox(&freqf_tbox[1], freqf_cgad==1); + filereq_render(oric); break; } - if( cfile <= 0 ) break; - if( shifty ) + if(cfile <= 0) break; + if(shifty) { doaction = ACTION_PAGEUP; break; } cfile--; - if( cfile < top ) top = cfile; - filereq_setfiletbox( cfile, fname ); - filereq_showfiles( top, cfile ); - filereq_drawtbox( &freqf_tbox[1], SDL_FALSE ); - filereq_render( oric ); + if(cfile < top) top = cfile; + filereq_setfiletbox(cfile, fname); + filereq_showfiles(top, cfile); + filereq_drawtbox(&freqf_tbox[1], SDL_FALSE); + filereq_render(oric); break; case SDLK_DOWN: - if( freqf_cgad != 2 ) + if(freqf_cgad != 2) { freqf_cgad = 2; - filereq_showfiles( top, cfile ); - filereq_drawtbox( &freqf_tbox[0], freqf_cgad==0 ); - filereq_drawtbox( &freqf_tbox[1], freqf_cgad==1 ); - filereq_render( oric ); + filereq_showfiles(top, cfile); + filereq_drawtbox(&freqf_tbox[0], freqf_cgad==0); + filereq_drawtbox(&freqf_tbox[1], freqf_cgad==1); + filereq_render(oric); break; } - if( cfile >= (freqf_used-1) ) break; - if( shifty ) + if(cfile >= (freqf_used-1)) break; + if(shifty) { doaction = ACTION_PAGEDOWN; break; } cfile++; - if( cfile > (top+25) ) top = cfile-25; - filereq_setfiletbox( cfile, fname ); - filereq_showfiles( top, cfile ); - filereq_drawtbox( &freqf_tbox[1], SDL_FALSE ); - filereq_render( oric ); + if(cfile > (top+25)) top = cfile-25; + filereq_setfiletbox(cfile, fname); + filereq_showfiles(top, cfile); + filereq_drawtbox(&freqf_tbox[1], SDL_FALSE); + filereq_render(oric); break; case SDLK_PAGEUP: - if( freqf_cgad != 2 ) + if(freqf_cgad != 2) { freqf_cgad = 2; - filereq_showfiles( top, cfile ); - filereq_drawtbox( &freqf_tbox[0], freqf_cgad==0 ); - filereq_drawtbox( &freqf_tbox[1], freqf_cgad==1 ); - filereq_render( oric ); + filereq_showfiles(top, cfile); + filereq_drawtbox(&freqf_tbox[0], freqf_cgad==0); + filereq_drawtbox(&freqf_tbox[1], freqf_cgad==1); + filereq_render(oric); break; } @@ -553,13 +588,13 @@ SDL_bool filerequester( struct machine *oric, char *title, char *path, char *fna break; case SDLK_PAGEDOWN: - if( freqf_cgad != 2 ) + if(freqf_cgad != 2) { freqf_cgad = 2; - filereq_showfiles( top, cfile ); - filereq_drawtbox( &freqf_tbox[0], freqf_cgad==0 ); - filereq_drawtbox( &freqf_tbox[1], freqf_cgad==1 ); - filereq_render( oric ); + filereq_showfiles(top, cfile); + filereq_drawtbox(&freqf_tbox[0], freqf_cgad==0); + filereq_drawtbox(&freqf_tbox[1], freqf_cgad==1); + filereq_render(oric); break; } @@ -567,186 +602,198 @@ SDL_bool filerequester( struct machine *oric, char *title, char *path, char *fna break; case SDLK_BACKSPACE: - if( freqf_cgad == 2 ) break; + if(freqf_cgad == 2) break; tb = &freqf_tbox[freqf_cgad]; - if( tb->cpos < 1 ) break; - for( i=tb->cpos-1; islen; i++ ) + if(tb->cpos < 1) break; + for(i=tb->cpos-1; islen; i++) tb->buf[i] = tb->buf[i+1]; tb->slen--; - if( tb->slen < 0 ) + if(tb->slen < 0) { tb->slen = 0; tb->cpos = 0; } case SDLK_LEFT: - if( freqf_cgad == 2 ) break; + if(freqf_cgad == 2) break; tb = &freqf_tbox[freqf_cgad]; - if( tb->cpos > 0 ) tb->cpos--; - if( tb->cpos < tb->vpos ) tb->vpos = tb->cpos; - if( tb->cpos >= (tb->vpos+tb->w) ) tb->vpos = tb->cpos-(tb->w-1); - if( tb->vpos < 0 ) tb->vpos = 0; - filereq_drawtbox( tb, SDL_TRUE ); - filereq_render( oric ); + if(tb->cpos > 0) tb->cpos--; + if(tb->cpos < tb->vpos) tb->vpos = tb->cpos; + if(tb->cpos >= (tb->vpos+tb->w)) tb->vpos = tb->cpos-(tb->w-1); + if(tb->vpos < 0) tb->vpos = 0; + filereq_drawtbox(tb, SDL_TRUE); + filereq_render(oric); break; case SDLK_RIGHT: - if( freqf_cgad == 2 ) break; + if(freqf_cgad == 2) break; tb = &freqf_tbox[freqf_cgad]; - if( tb->cpos < tb->slen ) tb->cpos++; - if( tb->cpos < tb->vpos ) tb->vpos = tb->cpos; - if( tb->cpos >= (tb->vpos+tb->w) ) tb->vpos = tb->cpos-(tb->w-1); - if( tb->vpos < 0 ) tb->vpos = 0; - filereq_drawtbox( tb, SDL_TRUE ); - filereq_render( oric ); + if(tb->cpos < tb->slen) tb->cpos++; + if(tb->cpos < tb->vpos) tb->vpos = tb->cpos; + if(tb->cpos >= (tb->vpos+tb->w)) tb->vpos = tb->cpos-(tb->w-1); + if(tb->vpos < 0) tb->vpos = 0; + filereq_drawtbox(tb, SDL_TRUE); + filereq_render(oric); break; case SDLK_DELETE: - if( freqf_cgad == 2 ) break; + if(freqf_cgad == 2) break; tb = &freqf_tbox[freqf_cgad]; - if( tb->cpos >= tb->slen ) break; - for( i=tb->cpos; islen; i++ ) + if(tb->cpos >= tb->slen) break; + for(i=tb->cpos; islen; i++) tb->buf[i] = tb->buf[i+1]; tb->slen--; - if( tb->slen < 0 ) + if(tb->slen < 0) { tb->slen = 0; tb->cpos = 0; } - filereq_drawtbox( tb, SDL_TRUE ); - filereq_render( oric ); + filereq_drawtbox(tb, SDL_TRUE); + filereq_render(oric); break; default: break; } - switch( SDL_COMPAT_GetKeysymUnicode( event.key.keysym ) ) + switch(SDL_COMPAT_GetKeysymUnicode(event.key.keysym)) { default: - if( freqf_cgad == 2 ) break; + if(freqf_cgad == 2) break; - if( ( SDL_COMPAT_GetKeysymUnicode( event.key.keysym ) > 31 ) && ( SDL_COMPAT_GetKeysymUnicode( event.key.keysym ) < 127 ) ) + if((SDL_COMPAT_GetKeysymUnicode(event.key.keysym) > 31) && (SDL_COMPAT_GetKeysymUnicode(event.key.keysym) < 127)) { tb = &freqf_tbox[freqf_cgad]; - if( tb->slen >= (tb->maxlen-1) ) break; - for( i=tb->slen; i>=tb->cpos; i-- ) + if(tb->slen >= (tb->maxlen-1)) break; + for(i=tb->slen; i>=tb->cpos; i--) tb->buf[i] = tb->buf[i-1]; - tb->buf[tb->cpos] = SDL_COMPAT_GetKeysymUnicode( event.key.keysym ); + tb->buf[tb->cpos] = SDL_COMPAT_GetKeysymUnicode(event.key.keysym); tb->slen++; tb->cpos++; tb->buf[tb->cpos] = 0; - if( tb->cpos < tb->vpos ) tb->vpos = tb->cpos; - if( tb->cpos >= (tb->vpos+tb->w) ) tb->vpos = tb->cpos-(tb->w-1); - if( tb->vpos < 0 ) tb->vpos = 0; - filereq_drawtbox( tb, SDL_TRUE ); - filereq_render( oric ); + if(tb->cpos < tb->vpos) tb->vpos = tb->cpos; + if(tb->cpos >= (tb->vpos+tb->w)) tb->vpos = tb->cpos-(tb->w-1); + if(tb->vpos < 0) tb->vpos = 0; + filereq_drawtbox(tb, SDL_TRUE); + filereq_render(oric); } break; } break; case SDL_QUIT: - setemumode( oric, NULL, EM_PLEASEQUIT ); + setemumode(oric, NULL, EM_PLEASEQUIT); return SDL_FALSE; default: break; } - switch( doaction ) + switch(doaction) { case ACTION_PAGEUP: - if( cfile > top ) + if(cfile > top) { cfile = top; - } else { + } + else + { top -= 25; - if( top < 0 ) top = 0; + if(top < 0) top = 0; cfile = top; } - filereq_showfiles( top, cfile ); - filereq_drawtbox( &freqf_tbox[0], freqf_cgad==0 ); - filereq_drawtbox( &freqf_tbox[1], freqf_cgad==1 ); - filereq_render( oric ); + filereq_showfiles(top, cfile); + filereq_drawtbox(&freqf_tbox[0], freqf_cgad==0); + filereq_drawtbox(&freqf_tbox[1], freqf_cgad==1); + filereq_render(oric); break; case ACTION_PAGEDOWN: - if( cfile < (top+25) ) + if(cfile < (top+25)) { cfile = top+25; - } else { + } + else + { cfile += 25; } - if( cfile > (freqf_used-1) ) cfile = freqf_used-1; + if(cfile > (freqf_used-1)) cfile = freqf_used-1; top = cfile-25; - if( top < 0 ) top = 0; - filereq_showfiles( top, cfile ); - filereq_drawtbox( &freqf_tbox[0], freqf_cgad==0 ); - filereq_drawtbox( &freqf_tbox[1], freqf_cgad==1 ); - filereq_render( oric ); + if(top < 0) top = 0; + filereq_showfiles(top, cfile); + filereq_drawtbox(&freqf_tbox[0], freqf_cgad==0); + filereq_drawtbox(&freqf_tbox[1], freqf_cgad==1); + filereq_render(oric); break; case ACTION_SELECTITEM: - if( freqf_used <= 0 ) break; - if( cfile<=0 ) // Parent + if(freqf_used <= 0) break; + if(cfile<=0) // Parent { - i = strlen( path )-1; - if( i<=0 ) break; - if( path[i] == PATHSEP ) i--; - while( i > -1 ) + i = strlen(path)-1; + if(i<=0) break; + if(path[i] == PATHSEP) i--; + while(i > -1) { - if( path[i] == PATHSEP ) break; + if(path[i] == PATHSEP) break; i--; } - if( i==-1 ) i++; + if(i==-1) i++; path[i] = 0; - } else if( freqfiles[cfile].isdir ) { - i = strlen( path )-1; - if( i < 0 ) + } + else if(freqfiles[cfile].isdir) + { + i = strlen(path)-1; + if(i < 0) { i++; - } else { - if( path[i] != PATHSEP ) + } + else + { + if(path[i] != PATHSEP) i++; } - if( i > 0 ) path[i++] = PATHSEP; - strncpy( &path[i], freqfiles[cfile].name, 4096-i ); + if(i > 0) path[i++] = PATHSEP; + strncpy(&path[i], freqfiles[cfile].name, 4096-i); path[4095] = 0; - } else { - SDL_COMPAT_EnableUNICODE( wasunicode ); - SDL_COMPAT_EnableKeyRepeat( wasunicode ? SDL_DEFAULT_REPEAT_DELAY : 0, wasunicode ? SDL_DEFAULT_REPEAT_INTERVAL : 0 ); + } + else + { + SDL_COMPAT_EnableUNICODE(wasunicode); + SDL_COMPAT_EnableKeyRepeat(wasunicode ? SDL_DEFAULT_REPEAT_DELAY : 0, wasunicode ? SDL_DEFAULT_REPEAT_INTERVAL : 0); return SDL_TRUE; } cfile = top = 0; - filereq_settbox( &freqf_tbox[0], path ); - if( !filereq_scan( path ) ) + filereq_settbox(&freqf_tbox[0], path); + if(!filereq_scan(path)) { - if( path[0] ) + if(path[0]) { path[0] = 0; - filereq_settbox( &freqf_tbox[0], path ); - if( !filereq_scan( path ) ) + filereq_settbox(&freqf_tbox[0], path); + if(!filereq_scan(path)) { - SDL_COMPAT_EnableUNICODE( wasunicode ); - SDL_COMPAT_EnableKeyRepeat( wasunicode ? SDL_DEFAULT_REPEAT_DELAY : 0, wasunicode ? SDL_DEFAULT_REPEAT_INTERVAL : 0 ); + SDL_COMPAT_EnableUNICODE(wasunicode); + SDL_COMPAT_EnableKeyRepeat(wasunicode ? SDL_DEFAULT_REPEAT_DELAY : 0, wasunicode ? SDL_DEFAULT_REPEAT_INTERVAL : 0); return SDL_FALSE; } - } else { - SDL_COMPAT_EnableUNICODE( wasunicode ); - SDL_COMPAT_EnableKeyRepeat( wasunicode ? SDL_DEFAULT_REPEAT_DELAY : 0, wasunicode ? SDL_DEFAULT_REPEAT_INTERVAL : 0 ); + } + else + { + SDL_COMPAT_EnableUNICODE(wasunicode); + SDL_COMPAT_EnableKeyRepeat(wasunicode ? SDL_DEFAULT_REPEAT_DELAY : 0, wasunicode ? SDL_DEFAULT_REPEAT_INTERVAL : 0); return SDL_FALSE; } } - filereq_showfiles( top, cfile ); - filereq_drawtbox( &freqf_tbox[0], freqf_cgad==0 ); - filereq_drawtbox( &freqf_tbox[1], freqf_cgad==1 ); - filereq_render( oric ); + filereq_showfiles(top, cfile); + filereq_drawtbox(&freqf_tbox[0], freqf_cgad==0); + filereq_drawtbox(&freqf_tbox[1], freqf_cgad==1); + filereq_render(oric); break; } } - SDL_COMPAT_EnableUNICODE( wasunicode ); - SDL_COMPAT_EnableKeyRepeat( wasunicode ? SDL_DEFAULT_REPEAT_DELAY : 0, wasunicode ? SDL_DEFAULT_REPEAT_INTERVAL : 0 ); + SDL_COMPAT_EnableUNICODE(wasunicode); + SDL_COMPAT_EnableKeyRepeat(wasunicode ? SDL_DEFAULT_REPEAT_DELAY : 0, wasunicode ? SDL_DEFAULT_REPEAT_INTERVAL : 0); return SDL_FALSE; } diff --git a/filereq_win32.c b/filereq_win32.c index 19935f7b..da2b735f 100644 --- a/filereq_win32.c +++ b/filereq_win32.c @@ -36,43 +36,43 @@ #include "machine.h" #include "filereq.h" -SDL_bool init_filerequester( struct machine *oric ) +SDL_bool init_filerequester(struct machine *oric) { return SDL_TRUE; } -void shut_filerequester( struct machine *oric ) +void shut_filerequester(struct machine *oric) { } -SDL_bool filerequester( struct machine *oric, char *title, char *path, char *fname, int type ) +SDL_bool filerequester(struct machine *oric, char* title, char* path, char* fname, int type) { SDL_SysWMinfo wmi; OPENFILENAME ofn; HWND hwnd; char tmp[4096]; int i; - char *odir; + char* odir; - strcpy( tmp, fname ); + strcpy(tmp, fname); hwnd = NULL; SDL_VERSION(&wmi.version); - if (SDL_COMPAT_GetWMInfo(&wmi)) + if(SDL_COMPAT_GetWMInfo(&wmi)) #if SDL_MAJOR_VERSION == 1 hwnd = (HWND)wmi.window; #else hwnd = (HWND)wmi.info.win.window; #endif - ZeroMemory( &ofn, sizeof( ofn ) ); - ofn.lStructSize = sizeof( ofn ); + ZeroMemory(&ofn, sizeof(ofn)); + ofn.lStructSize = sizeof(ofn); ofn.hwndOwner = hwnd; ofn.lpstrFile = fname; ofn.nMaxFile = 4096; ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST; - switch( type ) + switch(type) { case FR_DISKSAVE: ofn.Flags = OFN_PATHMUSTEXIST; @@ -80,7 +80,7 @@ SDL_bool filerequester( struct machine *oric, char *title, char *path, char *fna ofn.lpstrFilter = "All Files\0*.*\0Disk Images (*.dsk)\0*.DSK\0"; ofn.nFilterIndex = 2; break; - + case FR_TAPESAVETAP: ofn.Flags = OFN_PATHMUSTEXIST; ofn.lpstrFilter = "All Files\0*.*\0Tape Images (*.tap)\0*.TAP\0"; @@ -109,9 +109,9 @@ SDL_bool filerequester( struct machine *oric, char *title, char *path, char *fna ofn.lpstrFilter = "All Files\0*.*\0Snapshot files (*.sna)\0*.SNA\0"; ofn.nFilterIndex = 2; break; - + case FR_KEYMAPPINGSAVE: - ofn.Flags = OFN_PATHMUSTEXIST; + ofn.Flags = OFN_PATHMUSTEXIST; case FR_KEYMAPPINGLOAD: ofn.lpstrFilter = "All Files\0*.*\0Keyboard Mapping files (*.kma)\0*.KMA\0"; ofn.nFilterIndex = 2; @@ -127,52 +127,54 @@ SDL_bool filerequester( struct machine *oric, char *title, char *path, char *fna ofn.nMaxFileTitle = 0; ofn.lpstrInitialDir = path; - odir = getcwd( NULL, 0 ); + odir = getcwd(NULL, 0); - switch( type ) + switch(type) { case FR_SNAPSHOTSAVE: case FR_DISKSAVE: - if( !GetSaveFileName( &ofn ) ) + if(!GetSaveFileName(&ofn)) { - chdir( odir ); - free( odir ); + chdir(odir); + free(odir); return SDL_FALSE; } break; - + default: - if( !GetOpenFileName( &ofn ) ) + if(!GetOpenFileName(&ofn)) { - chdir( odir ); - free( odir ); + chdir(odir); + free(odir); return SDL_FALSE; } break; } - chdir( odir ); - free( odir ); + chdir(odir); + free(odir); - i = strlen( ofn.lpstrFile ); - if( !i ) return SDL_FALSE; + i = strlen(ofn.lpstrFile); + if(!i) return SDL_FALSE; i--; - while( ofn.lpstrFile[i] != PATHSEP ) + while(ofn.lpstrFile[i] != PATHSEP) { - if( i == 0 ) break; + if(i == 0) break; i--; } - if( ( ofn.lpstrFile[i] == PATHSEP ) && ( i < (strlen(ofn.lpstrFile)-1) ) ) + if((ofn.lpstrFile[i] == PATHSEP) && (i < (strlen(ofn.lpstrFile)-1))) { ofn.lpstrFile[i] = 0; - strcpy( path, ofn.lpstrFile ); - strncpy( fname, &ofn.lpstrFile[i+1], 512 ); + strcpy(path, ofn.lpstrFile); + strncpy(fname, &ofn.lpstrFile[i+1], 512); fname[511] = 0; - } else { + } + else + { path[0] = 0; - strncpy( fname, ofn.lpstrFile, 512 ); + strncpy(fname, ofn.lpstrFile, 512); fname[511] = 0; } diff --git a/font.c b/font.c index 146b7d60..8772f82b 100644 --- a/font.c +++ b/font.c @@ -20,7 +20,7 @@ */ unsigned char thefont[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0 nothing! - 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, // 1 top left + 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, // 1 top left 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, // 2 horizontal 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, // 3 branch down 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, // 4 top right @@ -28,10 +28,10 @@ unsigned char thefont[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, // 6 branch right 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, // 7 cross 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, // 8 branch left - 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, // 9 bottom left + 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, // 9 bottom left 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, // 10 branch up 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, // 11 bottom right - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, // 12 menu seperator + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, // 12 menu separator 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 13 0x00, 0x00, 0x06, 0x06, 0x0c, 0x0c, 0x18, 0xd8, 0xf0, 0x70, 0x60, 0x00, // 14 Tick 0x00, 0xff, 0x80, 0x98, 0xa4, 0xa4, 0x98, 0x80, 0x8f, 0x90, 0xff, 0x00, // 15 Tape left @@ -147,5 +147,5 @@ unsigned char thefont[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 0x00, 0x60, 0x30, 0x30, 0x30, 0x18, 0x18, 0x30, 0x30, 0x30, 0x60, 0x00, // 125 '}' 0x00, 0x36, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 126 '~' 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // 127 '' - -}; + + }; diff --git a/gui.c b/gui.c index 347eaefc..6d5c3886 100644 --- a/gui.c +++ b/gui.c @@ -64,6 +64,7 @@ #include "plugins/ch376/ch376.h" #include "plugins/ch376/oric_ch376_plugin.h" +#include "plugins/twilighte_board/oric_twilighte_board_plugin.h" extern SDL_bool fullscreen; @@ -74,6 +75,7 @@ char pravdiskpath[4096], pravdiskfile[512]; extern char atmosromfile[]; extern char oric1romfile[]; extern char mdiscromfile[]; +extern char bd500romfile[]; extern char jasmnromfile[]; extern char pravetzromfile[2][1024]; extern char telebankfiles[8][1024]; @@ -82,7 +84,7 @@ char mappingpath[4096], mappingfile[512]; char filetmp[4096+512+4]; SDL_bool refreshstatus = SDL_TRUE, refreshdisks = SDL_TRUE, refreshavi = SDL_TRUE, refreshtape = SDL_TRUE, - refreshkeyboard = SDL_TRUE; + refreshkeyboard = SDL_TRUE; extern struct avi_handle *vidcap; extern SDL_bool need_sdl_quit; @@ -96,20 +98,25 @@ extern Uint32 cyclespersample; // Images used in the GUI struct guiimg gimgs[NUM_GIMG] = { { IMAGEPREFIX"statusbar.bmp", 640, 16, NULL }, - { IMAGEPREFIX"disk_ejected.bmp", GIMG_W_DISK, 16, NULL }, - { IMAGEPREFIX"disk_idle.bmp", GIMG_W_DISK, 16, NULL }, - { IMAGEPREFIX"disk_active.bmp", GIMG_W_DISK, 16, NULL }, - { IMAGEPREFIX"disk_modified.bmp", GIMG_W_DISK, 16, NULL }, - { IMAGEPREFIX"disk_modactive.bmp", GIMG_W_DISK, 16, NULL }, - { IMAGEPREFIX"tape_ejected.bmp", GIMG_W_TAPE, 16, NULL }, - { IMAGEPREFIX"tape_pause.bmp", GIMG_W_TAPE, 16, NULL }, - { IMAGEPREFIX"tape_play.bmp", GIMG_W_TAPE, 16, NULL }, - { IMAGEPREFIX"tape_stop.bmp", GIMG_W_TAPE, 16, NULL }, - { IMAGEPREFIX"tape_record.bmp", GIMG_W_TAPE, 16, NULL }, - { IMAGEPREFIX"avirec.bmp", GIMG_W_AVIR, 16, NULL }, - { IMAGEPREFIX"gfx_oric1kbd.bmp", 640, 240, NULL }, - { IMAGEPREFIX"gfx_atmoskbd.bmp", 640, 240, NULL }, - { IMAGEPREFIX"gfx_pravetzkbd.bmp", 640, 240, NULL }}; + { IMAGEPREFIX"disk_ejected.bmp", GIMG_W_DISK, 16, NULL }, + { IMAGEPREFIX"disk_idle.bmp", GIMG_W_DISK, 16, NULL }, + { IMAGEPREFIX"disk_active.bmp", GIMG_W_DISK, 16, NULL }, + { IMAGEPREFIX"disk_modified.bmp", GIMG_W_DISK, 16, NULL }, + { IMAGEPREFIX"disk_modactive.bmp", GIMG_W_DISK, 16, NULL }, + { IMAGEPREFIX"tape_ejected.bmp", GIMG_W_TAPE, 16, NULL }, + { IMAGEPREFIX"tape_pause.bmp", GIMG_W_TAPE, 16, NULL }, + { IMAGEPREFIX"tape_play.bmp", GIMG_W_TAPE, 16, NULL }, + { IMAGEPREFIX"tape_stop.bmp", GIMG_W_TAPE, 16, NULL }, + { IMAGEPREFIX"tape_record.bmp", GIMG_W_TAPE, 16, NULL }, + { IMAGEPREFIX"avirec.bmp", GIMG_W_AVIR, 16, NULL }, +#ifndef WWW_NO_ORIC1 + { IMAGEPREFIX"gfx_oric1kbd.bmp", 640, 240, NULL }, +#endif + { IMAGEPREFIX"gfx_atmoskbd.bmp", 640, 240, NULL }, +#ifndef WWW_NO_PRAVETZ + { IMAGEPREFIX"gfx_pravetzkbd.bmp", 640, 240, NULL } +#endif +}; SDL_bool soundavailable, soundon; #if defined(__linux__) @@ -142,7 +149,7 @@ unsigned char sgpal[] = { 0x00, 0x00, 0x00, // 0 = black 0xff, 0x33, 0x33, // 13 = Telestrat sel 0x99, 0x99, 0x66, // 14 = Pravetz bc 0xcc, 0xcc, 0x99 // 15 = Pravetz sel -}; + }; // Colors for the menu, see sgpal for color index // MACH_ORIC1 = 0, MACH_ORIC1_16K, MACH_ATMOS, MACH_TELESTRAT, MACH_PRAVETZ @@ -172,8 +179,9 @@ SDL_bool warpspeed=SDL_FALSE; struct osdmenu *cmenu = NULL; int cmenuitem = 0; -static char* aciabackends[ACIA_TYPE_LAST] = { - " Serial none ", +static char* aciabackends[ACIA_TYPE_LAST] = +{ + " Serial none ", "\x0e""Serial loopback $xxxx", "\x0e""Serial modem $xxxx", "\x0e""Serial com $xxxx", @@ -181,259 +189,296 @@ static char* aciabackends[ACIA_TYPE_LAST] = { static char aciabackendlabel[32]; -char menufc(SDL_bool bSelected) { return (bSelected ? g_foregroundcsel[g_menu_scheme] : g_foregroundc[g_menu_scheme]); } -char menubc(SDL_bool bSelected) { return (bSelected ? g_backgroundcsel[g_menu_scheme] : g_backgroundc[g_menu_scheme]); } +char menufc(SDL_bool bSelected) +{ + return (bSelected ? g_foregroundcsel[g_menu_scheme] : g_foregroundc[g_menu_scheme]); +} +char menubc(SDL_bool bSelected) +{ + return (bSelected ? g_backgroundcsel[g_menu_scheme] : g_backgroundc[g_menu_scheme]); +} // Menufunctions -void toggletapenoise( struct machine *oric, struct osdmenuitem *mitem, int dummy ); -void togglesound( struct machine *oric, struct osdmenuitem *mitem, int dummy ); -void inserttape( struct machine *oric, struct osdmenuitem *mitem, int dummy ); -void insertdisk( struct machine *oric, struct osdmenuitem *mitem, int drive ); -void resetoric( struct machine *oric, struct osdmenuitem *mitem, int dummy ); -void toggletapeturbo( struct machine *oric, struct osdmenuitem *mitem, int dummy ); +void toggletapenoise(struct machine *oric, struct osdmenuitem *mitem, int dummy); +void togglesound(struct machine *oric, struct osdmenuitem *mitem, int dummy); +void inserttape(struct machine *oric, struct osdmenuitem *mitem, int dummy); +void insertdisk(struct machine *oric, struct osdmenuitem *mitem, int drive); +void resetoric(struct machine *oric, struct osdmenuitem *mitem, int dummy); +void toggletapeturbo(struct machine *oric, struct osdmenuitem *mitem, int dummy); void togglech376(struct machine *oric, struct osdmenuitem *mitem, int dummy); -void toggleautowind( struct machine *oric, struct osdmenuitem *mitem, int dummy ); -void toggleautoinsrt( struct machine *oric, struct osdmenuitem *mitem, int dummy ); -void togglesymbolsauto( struct machine *oric, struct osdmenuitem *mitem, int dummy ); -void togglecasesyms( struct machine *oric, struct osdmenuitem *mitem, int dummy ); -void togglevsynchack( struct machine *oric, struct osdmenuitem *mitem, int dummy ); -void swap_render_mode( struct machine *oric, struct osdmenuitem *mitem, int newrendermode ); -void togglearatio( struct machine *oric, struct osdmenuitem *mitem, int dummy ); -void togglehstretch( struct machine *oric, struct osdmenuitem *mitem, int dummy ); -void togglepalghost( struct machine *oric, struct osdmenuitem *mitem, int dummy ); -void togglescanlines( struct machine *oric, struct osdmenuitem *mitem, int dummy ); -void togglelightpen( struct machine *oric, struct osdmenuitem *mitem, int dummy ); -void toggleaciabackend( struct machine *oric, struct osdmenuitem *mitem, int dummy ); -void setoverclock( struct machine *oric, struct osdmenuitem *mitem, int dummy ); -void savesnap( struct machine *oric, struct osdmenuitem *mitem, int dummy ); -void loadsnap( struct machine *oric, struct osdmenuitem *mitem, int dummy ); -void togglekeyboard( struct machine *oric, struct osdmenuitem *mitem, int dummy ); -void definemapping( struct machine *oric, struct osdmenuitem *mitem, int dummy ); -void togglestickykeys( struct machine *oric, struct osdmenuitem *mitem, int dummy ); -void savemapping( struct machine *oric, struct osdmenuitem *mitem, int dummy ); -void loadmapping( struct machine *oric, struct osdmenuitem *mitem, int dummy ); -void resetmapping( struct machine *oric, struct osdmenuitem *mitem, int dummy ); +void toggletwilighte(struct machine *oric, struct osdmenuitem *mitem, int dummy); +void toggleautowind(struct machine *oric, struct osdmenuitem *mitem, int dummy); +void toggleautoinsrt(struct machine *oric, struct osdmenuitem *mitem, int dummy); +void togglesymbolsauto(struct machine *oric, struct osdmenuitem *mitem, int dummy); +void togglecasesyms(struct machine *oric, struct osdmenuitem *mitem, int dummy); +void togglevsynchack(struct machine *oric, struct osdmenuitem *mitem, int dummy); +void swap_render_mode(struct machine *oric, struct osdmenuitem *mitem, int newrendermode); +void togglearatio(struct machine *oric, struct osdmenuitem *mitem, int dummy); +void togglehstretch(struct machine *oric, struct osdmenuitem *mitem, int dummy); +void togglepalghost(struct machine *oric, struct osdmenuitem *mitem, int dummy); +void togglescanlines(struct machine *oric, struct osdmenuitem *mitem, int dummy); +void togglelightpen(struct machine *oric, struct osdmenuitem *mitem, int dummy); +void toggleaciabackend(struct machine *oric, struct osdmenuitem *mitem, int dummy); +void setoverclock(struct machine *oric, struct osdmenuitem *mitem, int dummy); +void savesnap(struct machine *oric, struct osdmenuitem *mitem, int dummy); +void loadsnap(struct machine *oric, struct osdmenuitem *mitem, int dummy); +void togglekeyboard(struct machine *oric, struct osdmenuitem *mitem, int dummy); +void definemapping(struct machine *oric, struct osdmenuitem *mitem, int dummy); +void togglestickykeys(struct machine *oric, struct osdmenuitem *mitem, int dummy); +void savemapping(struct machine *oric, struct osdmenuitem *mitem, int dummy); +void loadmapping(struct machine *oric, struct osdmenuitem *mitem, int dummy); +void resetmapping(struct machine *oric, struct osdmenuitem *mitem, int dummy); #ifdef __CBCOPY__ -void clipbd_copy_gui( struct machine *oric, struct osdmenuitem *mitem, int dummy ); +void clipbd_copy_gui(struct machine *oric, struct osdmenuitem *mitem, int dummy); #endif #ifdef __CBPASTE__ -void clipbd_paste_gui( struct machine *oric, struct osdmenuitem *mitem, int dummy ); +void clipbd_paste_gui(struct machine *oric, struct osdmenuitem *mitem, int dummy); #endif // Menu definitions. Name, key name, SDL key code, function, parameter // Keys that are also available while emulating should be marked with // square brackets struct osdmenuitem mainitems[] = { { "Insert tape...", "T", 't', inserttape, 0, 0 }, - { "Save tape output...", "[F9]", SDLK_F9, toggletapecap, 0, 0 }, - { "Insert disk 0...", "0", SDLK_0, insertdisk, 0, 0 }, - { "Insert disk 1...", "1", SDLK_1, insertdisk, 1, 0 }, - { "Insert disk 2...", "2", SDLK_2, insertdisk, 2, 0 }, - { "Insert disk 3...", "3", SDLK_3, insertdisk, 3, 0 }, - { OSDMENUBAR, NULL, 0, NULL, 0, 0 }, - { "Save snapshot...", NULL, 0, savesnap, 0, 0 }, - { "Load snapshot...", NULL, 0, loadsnap, 0, 0 }, + { "Save tape output...", "[F9]", SDLK_F9, toggletapecap, 0, 0 }, + { "Insert disk 0...", "0", SDLK_0, insertdisk, 0, 0 }, + { "Insert disk 1...", "1", SDLK_1, insertdisk, 1, 0 }, + { "Insert disk 2...", "2", SDLK_2, insertdisk, 2, 0 }, + { "Insert disk 3...", "3", SDLK_3, insertdisk, 3, 0 }, + { OSDMENUBAR, NULL, 0, NULL, 0, 0 }, + { "Save snapshot...", NULL, 0, savesnap, 0, 0 }, + { "Load snapshot...", NULL, 0, loadsnap, 0, 0 }, #if defined(__CBCOPY__) || defined(__CBPASTE__) - { OSDMENUBAR, NULL, 0, NULL, 0, 0 }, + { OSDMENUBAR, NULL, 0, NULL, 0, 0 }, #endif #if defined(__CBCOPY__) - { "Copy to clipboard", "[F11]",SDLK_F11, clipbd_copy_gui, 0, 0 }, + { "Copy to clipboard", "[F11]",SDLK_F11, clipbd_copy_gui, 0, 0 }, #endif #if defined(__CBPASTE__) - { "Paste from clipboard", "[F12]",SDLK_F12, clipbd_paste_gui,0, 0 }, + { "Paste from clipboard", "[F12]",SDLK_F12, clipbd_paste_gui,0, 0 }, #endif - { OSDMENUBAR, NULL, 0, NULL, 0, 0 }, - { "Hardware options...", "H", 'h', gotomenu, 1, 0 }, - { "Audio options...", "A", 'a', gotomenu, 2, 0 }, - { "Video options...", "V", 'v', gotomenu, 4, 0 }, - { "Keyboard options...", "K", 'k', gotomenu, 7, 0 }, - { "Debug options...", "D", 'd', gotomenu, 3, 0 }, - { "Overclock options...", "C", 'c', gotomenu, 6, 0 }, - { OSDMENUBAR, NULL, 0, NULL, 0, 0 }, - { "Monitor", "[F2]", SDLK_F2, setemumode, EM_DEBUG, 0 }, - { "Reset Button NMI", "[F3]", SDLK_F3, softresetoric, 0, 0 }, - { "Hard Reset", "[F4]", SDLK_F4, resetoric, 0, 0 }, - { "Back", "\x17", SDLK_BACKSPACE,setemumode, EM_RUNNING, 0 }, - { OSDMENUBAR, NULL, 0, NULL, 0, 0 }, - { "About", NULL, 0, gotomenu, 5, 0 }, - { OSDMENUBAR, NULL, 0, NULL, 0, 0 }, - { "Quit", NULL, 0, setemumode, EM_PLEASEQUIT, 0 }, - { NULL, } }; - -struct osdmenuitem hwopitems[] = { { " Oric-1", "1", SDLK_1, swapmach, (0xffff<<16)|MACH_ORIC1, 0 }, - { " Oric-1 16K", "2", SDLK_2, swapmach, (0xffff<<16)|MACH_ORIC1_16K, 0 }, - { " Atmos", "3", SDLK_3, swapmach, (0xffff<<16)|MACH_ATMOS, 0 }, - { " Telestrat", "4", SDLK_4, swapmach, (DRV_NONE<<16)|MACH_TELESTRAT, 0 }, - { " Pravetz 8D", "5", SDLK_5, swapmach, (0xffff<<16)|MACH_PRAVETZ, 0 }, - { OSDMENUBAR, NULL, 0, NULL, 0, 0 }, - { " No disk", "X", 'x', setdrivetype, DRV_NONE, 0 }, - { " Microdisc", "M", 'm', setdrivetype, DRV_MICRODISC, 0 }, - { " Jasmin", "J", 'j', setdrivetype, DRV_JASMIN, 0 }, -// { " Cumana", "C", 'c', NULL, 0, 0 }, - { " Pravetz 8D disk", "P", 'p', setdrivetype, DRV_PRAVETZ, 0 }, - { OSDMENUBAR, NULL, 0, NULL, 0, 0 }, - { " Turbo tape", NULL, 0, toggletapeturbo, 0, 0 }, - { " Autoinsert tape", NULL, 0, toggleautoinsrt, 0, 0 }, - { " Autorewind tape", NULL, 0, toggleautowind, 0, 0 }, - { OSDMENUBAR, NULL, 0, NULL, 0, 0 }, - { " VSync hack", NULL, 0, togglevsynchack, 0, 0 }, - { " Lightpen", NULL, 0, togglelightpen, 0, 0 }, - { " Serial none ", NULL, 0, toggleaciabackend, 0, 0 }, - { " CH376 (Telestrat) ", NULL, 0, togglech376, 0, 0 }, -// { " Mouse", NULL, 0, NULL, 0, 0 }, - { OSDMENUBAR, NULL, 0, NULL, 0, 0 }, - { "Back", "\x17", SDLK_BACKSPACE,gotomenu, 0, 0 }, - { NULL, } }; + { OSDMENUBAR, NULL, 0, NULL, 0, 0 }, + { "Hardware options...", "H", 'h', gotomenu, 1, 0 }, + { "Audio options...", "A", 'a', gotomenu, 2, 0 }, + { "Video options...", "V", 'v', gotomenu, 4, 0 }, + { "Keyboard options...", "K", 'k', gotomenu, 7, 0 }, + { "Debug options...", "D", 'd', gotomenu, 3, 0 }, + { "Overclock options...", "C", 'c', gotomenu, 6, 0 }, + { OSDMENUBAR, NULL, 0, NULL, 0, 0 }, +#ifndef WWW_NO_MONITOR + { "Monitor", "[F2]", SDLK_F2, setemumode, EM_DEBUG, 0 }, +#endif + { "Reset Button NMI", "[F3]", SDLK_F3, softresetoric, 0, 0 }, + { "Hard Reset", "[F4]", SDLK_F4, resetoric, 0, 0 }, + { "Back", "\x17", SDLK_BACKSPACE,setemumode, EM_RUNNING, 0 }, + { OSDMENUBAR, NULL, 0, NULL, 0, 0 }, + { "About", NULL, 0, gotomenu, 5, 0 }, + { OSDMENUBAR, NULL, 0, NULL, 0, 0 }, +#ifndef WWW + { "Quit", NULL, 0, setemumode, EM_PLEASEQUIT, 0 }, +#endif + { NULL, } +}; + +struct osdmenuitem hwopitems[] = { { " Oric-1", "1", SDLK_1, swapmach, (0xffff<<16)|MACH_ORIC1, 0 }, + { " Oric-1 16K", "2", SDLK_2, swapmach, (0xffff<<16)|MACH_ORIC1_16K, 0 }, + { " Atmos", "3", SDLK_3, swapmach, (0xffff<<16)|MACH_ATMOS, 0 }, + { " Telestrat", "4", SDLK_4, swapmach, (DRV_NONE<<16)|MACH_TELESTRAT, 0 }, + { " Pravetz 8D", "5", SDLK_5, swapmach, (0xffff<<16)|MACH_PRAVETZ, 0 }, + { OSDMENUBAR, NULL, 0, NULL, 0, 0 }, + { " No disk", "X", 'x', setdrivetype, DRV_NONE, 0 }, + { " Microdisc", "M", 'm', setdrivetype, DRV_MICRODISC, 0 }, + { " Jasmin", "J", 'j', setdrivetype, DRV_JASMIN, 0 }, + { " BD500", "B", 'b', setdrivetype, DRV_BD500, 0 }, + // { " Cumana", "C", 'c', NULL, 0, 0 }, + { " Pravetz 8D disk", "P", 'p', setdrivetype, DRV_PRAVETZ, 0 }, + { OSDMENUBAR, NULL, 0, NULL, 0, 0 }, + { " Turbo tape", NULL, 0, toggletapeturbo, 0, 0 }, + { " Autoinsert tape", NULL, 0, toggleautoinsrt, 0, 0 }, + { " Autorewind tape", NULL, 0, toggleautowind, 0, 0 }, + { OSDMENUBAR, NULL, 0, NULL, 0, 0 }, + { " VSync hack", NULL, 0, togglevsynchack, 0, 0 }, + { " Lightpen", NULL, 0, togglelightpen, 0, 0 }, + { " Serial none ", NULL, 0, toggleaciabackend, 0, 0 }, + { " CH376 (Telestrat) ", NULL, 0, togglech376, 0, 0 }, + { " Twilighte board ", NULL, 0, toggletwilighte, 0, 0 }, + // { " Mouse", NULL, 0, NULL, 0, 0 }, + { OSDMENUBAR, NULL, 0, NULL, 0, 0 }, + { "Back", "\x17", SDLK_BACKSPACE,gotomenu, 0, 0 }, + { NULL, } +}; struct osdmenuitem auopitems[] = { { " Sound enabled", NULL, 0, togglesound, 0, 0 }, - { " Tape noise", NULL, 0, toggletapenoise, 0, 0 }, - { OSDMENUBAR, NULL, 0, NULL, 0, 0 }, - { "Back", "\x17", SDLK_BACKSPACE,gotomenu, 0, 0 }, - { NULL, } }; + { " Tape noise", NULL, 0, toggletapenoise, 0, 0 }, + { OSDMENUBAR, NULL, 0, NULL, 0, 0 }, + { "Back", "\x17", SDLK_BACKSPACE,gotomenu, 0, 0 }, + { NULL, } +}; struct osdmenuitem keopitems[] = { { " Show keyboard", NULL, 0, togglekeyboard, 0, 0 }, - { " Sticky mod keys", NULL, 0, togglestickykeys,0, 0 }, - { " Define mapping", NULL, 0, definemapping, 0, 0 }, - { "Save mapping...", NULL, 0, savemapping, 0, 0 }, - { "Load mapping...", NULL, 0, loadmapping, 0, 0 }, - { "Reset mapping", NULL, 0, resetmapping, 0, 0 }, - { OSDMENUBAR, NULL, 0, NULL, 0, 0 }, - { "Back", "\x17", SDLK_BACKSPACE,gotomenu, 0, 0 }, - { NULL, } }; + { " Sticky mod keys", NULL, 0, togglestickykeys,0, 0 }, + { " Define mapping", NULL, 0, definemapping, 0, 0 }, + { "Save mapping...", NULL, 0, savemapping, 0, 0 }, + { "Load mapping...", NULL, 0, loadmapping, 0, 0 }, + { "Reset mapping", NULL, 0, resetmapping, 0, 0 }, + { OSDMENUBAR, NULL, 0, NULL, 0, 0 }, + { "Back", "\x17", SDLK_BACKSPACE,gotomenu, 0, 0 }, + { NULL, } +}; struct osdmenuitem dbopitems[] = { { " Autoload symbols file", NULL, 0, togglesymbolsauto, 0, 0 }, - { " Case-sensitive symbols",NULL, 0, togglecasesyms, 0, 0 }, - { OSDMENUBAR, NULL, 0, NULL, 0, 0 }, - { "Back", "\x17", SDLK_BACKSPACE,gotomenu, 0, 0 }, - { NULL, } }; + { " Case-sensitive symbols",NULL, 0, togglecasesyms, 0, 0 }, + { OSDMENUBAR, NULL, 0, NULL, 0, 0 }, + { "Back", "\x17", SDLK_BACKSPACE,gotomenu, 0, 0 }, + { NULL, } +}; #ifdef __OPENGL_AVAILABLE__ struct osdmenuitem vdopitems[] = { { " OpenGL rendering", "O", 'o', swap_render_mode, RENDERMODE_GL, 0 }, - { " Software rendering", "S", 's', swap_render_mode, RENDERMODE_SW, 0 }, - { OSDMENUBAR, NULL, 0, NULL, 0, 0 }, - { " Fullscreen", "[F8]", SDLK_F8, togglefullscreen, 0, 0 }, - { " Scanlines", "C", 'c', togglescanlines, 0, 0 }, - { OSDMENUBAR, NULL, 0, NULL, 0, 0 }, - { "Back", "\x17", SDLK_BACKSPACE,gotomenu, 0, 0 }, - { NULL, } }; + { " Software rendering", "S", 's', swap_render_mode, RENDERMODE_SW, 0 }, + { OSDMENUBAR, NULL, 0, NULL, 0, 0 }, + { " Fullscreen", "[F8]", SDLK_F8, togglefullscreen, 0, 0 }, + { " Scanlines", "C", 'c', togglescanlines, 0, 0 }, + { OSDMENUBAR, NULL, 0, NULL, 0, 0 }, + { "Back", "\x17", SDLK_BACKSPACE,gotomenu, 0, 0 }, + { NULL, } +}; #else struct osdmenuitem vdopitems[] = { { " Fullscreen", "F", 'f', togglefullscreen, 0, 0 }, - { " Scanlines", "C", 'c', togglescanlines, 0, 0 }, - { OSDMENUBAR, NULL, 0, NULL, 0, 0 }, - { "Back", "\x17", SDLK_BACKSPACE,gotomenu, 0, 0 }, - { NULL, } }; + { " Scanlines", "C", 'c', togglescanlines, 0, 0 }, + { OSDMENUBAR, NULL, 0, NULL, 0, 0 }, + { "Back", "\x17", SDLK_BACKSPACE,gotomenu, 0, 0 }, + { NULL, } +}; #endif struct osdmenuitem glopitems[] = { { " OpenGL rendering", "O", 'o', swap_render_mode, RENDERMODE_GL, 0 }, - { " Software rendering", "S", 's', swap_render_mode, RENDERMODE_SW, 0 }, - { OSDMENUBAR, NULL, 0, NULL, 0, 0 }, - { " Fullscreen", "F", 'f', togglefullscreen, 0, 0 }, - { " 50Hz/60Hz aspect ratio", "R", 'r', togglearatio, 0, 0 }, - { " Horizontal stretch", "H", 'h', togglehstretch, 0, 0 }, - { " Scanlines", "C", 'c', togglescanlines, 0, 0 }, - { " PAL ghosting", "P", 'p', togglepalghost, 0, 0 }, - { OSDMENUBAR, NULL, 0, NULL, 0, 0 }, - { "Back", "\x17", SDLK_BACKSPACE,gotomenu, 0, 0 }, - { NULL, } }; + { " Software rendering", "S", 's', swap_render_mode, RENDERMODE_SW, 0 }, + { OSDMENUBAR, NULL, 0, NULL, 0, 0 }, + { " Fullscreen", "F", 'f', togglefullscreen, 0, 0 }, + { " 50Hz/60Hz aspect ratio", "R", 'r', togglearatio, 0, 0 }, + { " Horizontal stretch", "H", 'h', togglehstretch, 0, 0 }, + { " Scanlines", "C", 'c', togglescanlines, 0, 0 }, + { " PAL ghosting", "P", 'p', togglepalghost, 0, 0 }, + { OSDMENUBAR, NULL, 0, NULL, 0, 0 }, + { "Back", "\x17", SDLK_BACKSPACE,gotomenu, 0, 0 }, + { NULL, } +}; struct osdmenuitem aboutitems[] = { { "", NULL, 0, NULL, 0, 0 }, - { APP_NAME_FULL, NULL, 0, NULL, 0, OMIF_BRIGHT|OMIF_CENTRED }, - { "https://github.com/pete-gordon/oricutron",NULL, 0, gotosite, 0, OMIF_CENTRED }, - { "", NULL, 0, NULL, 0, 0 }, - { "(C)" APP_YEAR " Peter Gordon", NULL, 0, NULL, 0, OMIF_BRIGHT|OMIF_CENTRED }, - { "http://www.petergordon.org.uk", NULL, 0, gotosite, 0, OMIF_CENTRED }, - { "", NULL, 0, NULL, 0, 0 }, - { "Additional programming", NULL, 0, NULL, 0, OMIF_BRIGHT|OMIF_CENTRED }, - { "Francois Revol", NULL, 0, NULL, 0, OMIF_CENTRED }, - { "Stefan Haubenthal", NULL, 0, NULL, 0, OMIF_CENTRED }, - { "Alexandre Devert", NULL, 0, NULL, 0, OMIF_CENTRED }, - { "Ibisum", NULL, 0, NULL, 0, OMIF_CENTRED }, - { "Kamel Biskri", NULL, 0, NULL, 0, OMIF_CENTRED }, - { "Iss", NULL, 0, NULL, 0, OMIF_CENTRED }, - { "Patrice Torguet", NULL, 0, NULL, 0, OMIF_CENTRED }, - { "", NULL, 0, NULL, 0, 0 }, - { OSDMENUBAR, NULL, 0, NULL, 0, 0 }, - { "Back", "\x17", SDLK_BACKSPACE, gotomenu, 0, 0 }, - { NULL, } }; + { APP_NAME_FULL, NULL, 0, NULL, 0, OMIF_BRIGHT|OMIF_CENTRED }, + { "https://github.com/pete-gordon/oricutron",NULL, 0, gotosite, 0, OMIF_CENTRED }, + { "", NULL, 0, NULL, 0, 0 }, + { "(C)" APP_YEAR " Peter Gordon", NULL, 0, NULL, 0, OMIF_BRIGHT|OMIF_CENTRED }, + { "http://www.petergordon.org.uk", NULL, 0, gotosite, 0, OMIF_CENTRED }, + { "", NULL, 0, NULL, 0, 0 }, + { "Additional programming", NULL, 0, NULL, 0, OMIF_BRIGHT|OMIF_CENTRED }, + { "Francois Revol", NULL, 0, NULL, 0, OMIF_CENTRED }, + { "Stefan Haubenthal", NULL, 0, NULL, 0, OMIF_CENTRED }, + { "Alexandre Devert", NULL, 0, NULL, 0, OMIF_CENTRED }, + { "Ibisum", NULL, 0, NULL, 0, OMIF_CENTRED }, + { "Kamel Biskri", NULL, 0, NULL, 0, OMIF_CENTRED }, + { "Iss", NULL, 0, NULL, 0, OMIF_CENTRED }, + { "Patrice Torguet", NULL, 0, NULL, 0, OMIF_CENTRED }, + { "", NULL, 0, NULL, 0, 0 }, + { OSDMENUBAR, NULL, 0, NULL, 0, 0 }, + { "Back", "\x17", SDLK_BACKSPACE, gotomenu, 0, 0 }, + { NULL, } +}; struct osdmenuitem ovopitems[] = { { " 1mhz (None)", "1", '1', setoverclock, 0, 0 }, - { " 2mhz", "2", '2', setoverclock, 1, 0 }, - { " 4mhz", "3", '3', setoverclock, 2, 0 }, - { " 8mhz", "4", '4', setoverclock, 3, 0 }, - { " 16mhz", "5", '5', setoverclock, 4, 0 }, - { " 32mhz", "6", '6', setoverclock, 5, 0 }, - { " 64mhz", "7", '7', setoverclock, 6, 0 }, - { OSDMENUBAR, NULL, 0, NULL, 0, 0 }, - { "Back", "\x17", SDLK_BACKSPACE,gotomenu,0, 0 }, - { NULL, } }; + { " 2mhz", "2", '2', setoverclock, 1, 0 }, + { " 4mhz", "3", '3', setoverclock, 2, 0 }, + { " 8mhz", "4", '4', setoverclock, 3, 0 }, + { " 16mhz", "5", '5', setoverclock, 4, 0 }, + { " 32mhz", "6", '6', setoverclock, 5, 0 }, + { " 64mhz", "7", '7', setoverclock, 6, 0 }, + { OSDMENUBAR, NULL, 0, NULL, 0, 0 }, + { "Back", "\x17", SDLK_BACKSPACE,gotomenu,0, 0 }, + { NULL, } +}; #define LAST_ITEM(x) ((sizeof(x)/sizeof(struct osdmenuitem))-2) struct osdmenu menus[] = { { "Main Menu", LAST_ITEM(mainitems)-4, mainitems }, - { "Hardware options", LAST_ITEM(hwopitems), hwopitems }, - { "Audio options", LAST_ITEM(auopitems), auopitems }, - { "Debug options", LAST_ITEM(dbopitems), dbopitems }, - { "Video options", LAST_ITEM(vdopitems), vdopitems }, - { "About Oricutron", LAST_ITEM(aboutitems), aboutitems }, - { "Overclock", LAST_ITEM(ovopitems), ovopitems }, - { "Keyboard options", LAST_ITEM(keopitems), keopitems }}; + { "Hardware options", LAST_ITEM(hwopitems), hwopitems }, + { "Audio options", LAST_ITEM(auopitems), auopitems }, + { "Debug options", LAST_ITEM(dbopitems), dbopitems }, + { "Video options", LAST_ITEM(vdopitems), vdopitems }, + { "About Oricutron", LAST_ITEM(aboutitems), aboutitems }, + { "Overclock", LAST_ITEM(ovopitems), ovopitems }, + { "Keyboard options", LAST_ITEM(keopitems), keopitems } +}; + +#define MKPATH_MAX (1024) + +// Prepend file prefix to filename +static void mkpath(char buf[MKPATH_MAX], const char* filename) +{ + strncpy(buf, get_fileprefix(), MKPATH_MAX-1); + buf[MKPATH_MAX-1] = 0; + strncat(buf, filename, MKPATH_MAX-strlen(buf)-1); +} // Load a 24bit BMP for the GUI -SDL_bool gimg_load( struct guiimg *gi ) +SDL_bool gimg_load(struct guiimg *gi) { SDL_RWops *f; Uint8 hdrbuf[640*3]; Sint32 x, y; SDL_bool fileok; + char path[MKPATH_MAX]; // Get the file - f = SDL_RWFromFile( gi->filename, "rb" ); - if( !f ) + mkpath(path, gi->filename); + f = SDL_RWFromFile(path, "rb"); + if(!f) { - error_printf( "Unable to open '%s'\n", gi->filename ); + error_printf("Unable to open '%s' SDL_Error: %s\n", gi->filename, SDL_GetError()); + return SDL_FALSE; } // Read the header - if( SDL_RWread( f, hdrbuf, 54, 1 ) != 1 ) + if(SDL_RWread(f, hdrbuf, 54, 1) != 1) { - error_printf( "Error reading '%s'\n", gi->filename ); - SDL_RWclose( f ); + error_printf("Error reading '%s'\n", gi->filename); + SDL_RWclose(f); return SDL_FALSE; } fileok = SDL_TRUE; - if( strncmp( (char *)hdrbuf, "BM", 2 ) != 0 ) fileok = SDL_FALSE; // Must start with "BM" - if( ((hdrbuf[21]<<24)|(hdrbuf[20]<<16)|(hdrbuf[19]<<8)|hdrbuf[18]) != gi->w ) fileok = SDL_FALSE; // Must be the correct width - if( ((hdrbuf[25]<<24)|(hdrbuf[24]<<16)|(hdrbuf[23]<<8)|hdrbuf[22]) != gi->h ) fileok = SDL_FALSE; // Must be the correct height - if( ((hdrbuf[27]<<8)|hdrbuf[26]) != 1 ) fileok = SDL_FALSE; // Must contain one plane - if( ((hdrbuf[29]<<8)|hdrbuf[28]) != 24 ) fileok = SDL_FALSE; // Must be 24 bit - if( ((hdrbuf[33]<<24)|(hdrbuf[32]<<16)|(hdrbuf[31]<<8)|hdrbuf[30]) != 0 ) fileok = SDL_FALSE; // Must not be compressed + if(strncmp((char*)hdrbuf, "BM", 2) != 0) fileok = SDL_FALSE; // Must start with "BM" + if(((hdrbuf[21]<<24)|(hdrbuf[20]<<16)|(hdrbuf[19]<<8)|hdrbuf[18]) != gi->w) fileok = SDL_FALSE; // Must be the correct width + if(((hdrbuf[25]<<24)|(hdrbuf[24]<<16)|(hdrbuf[23]<<8)|hdrbuf[22]) != gi->h) fileok = SDL_FALSE; // Must be the correct height + if(((hdrbuf[27]<<8)|hdrbuf[26]) != 1) fileok = SDL_FALSE; // Must contain one plane + if(((hdrbuf[29]<<8)|hdrbuf[28]) != 24) fileok = SDL_FALSE; // Must be 24 bit + if(((hdrbuf[33]<<24)|(hdrbuf[32]<<16)|(hdrbuf[31]<<8)|hdrbuf[30]) != 0) fileok = SDL_FALSE; // Must not be compressed - if( !fileok ) + if(!fileok) { - error_printf( "'%s' needs to be a %dx%d, uncompressed, 24-bit BMP image\n", gi->filename, gi->w, gi->h ); - SDL_RWclose( f ); + error_printf("'%s' needs to be a %dx%d, uncompressed, 24-bit BMP image\n", gi->filename, gi->w, gi->h); + SDL_RWclose(f); return SDL_FALSE; } // Get some RAM! - if( !gi->buf ) - gi->buf = malloc( gi->w * gi->h * 3 ); + if(!gi->buf) + gi->buf = malloc(gi->w * gi->h * 3); - if( !gi->buf ) + if(!gi->buf) { - error_printf( "Out of memory\n" ); - SDL_RWclose( f ); + error_printf("Out of memory\n"); + SDL_RWclose(f); return SDL_FALSE; } // BMPs are upside down! - for( y=gi->h-1; y>=0; y-- ) + for(y=gi->h-1; y>=0; y--) { - SDL_RWread( f, hdrbuf, ((gi->w*3)+3)&0xfffffffc, 1 ); - for( x=0; xw; x++ ) + SDL_RWread(f, hdrbuf, ((gi->w*3)+3)&0xfffffffc, 1); + for(x=0; xw; x++) { gi->buf[(y*gi->w+x)*3+0] = hdrbuf[x*3+2]; gi->buf[(y*gi->w+x)*3+1] = hdrbuf[x*3+1]; @@ -441,192 +486,202 @@ SDL_bool gimg_load( struct guiimg *gi ) } } - SDL_RWclose( f ); + SDL_RWclose(f); return SDL_TRUE; } // Draw the statusbar at the bottom -void draw_statusbar( struct machine *oric ) +void draw_statusbar(struct machine *oric) { - if (oric->statusbar_mode == STATUSBARMODE_NONE) - oric->render_clear_area( 0, GIMG_POS_SBARY, 640, 480-GIMG_POS_SBARY ); - else - oric->render_gimg( GIMG_STATUSBAR, 0, GIMG_POS_SBARY ); + if(oric->statusbar_mode == STATUSBARMODE_NONE) + oric->render_clear_area(0, GIMG_POS_SBARY, 640, 480-GIMG_POS_SBARY); + else + oric->render_gimg(GIMG_STATUSBAR, 0, GIMG_POS_SBARY); } -void draw_keyboard( struct machine *oric ) { - if (oric->show_keyboard) { - switch( oric->type ) +void draw_keyboard(struct machine *oric) +{ + if(oric->show_keyboard) + { + switch(oric->type) { - case MACH_PRAVETZ: - oric->render_gimg( GIMG_PRAVETZ_KEYBOARD, 0, 480); - break; - case MACH_ORIC1: - case MACH_ORIC1_16K: - oric->render_gimg( GIMG_ORIC1_KEYBOARD, 0, 480); - break; - default: - oric->render_gimg( GIMG_ATMOS_KEYBOARD, 0, 480); - break; +#ifndef WWW_NO_PRAVETZ + case MACH_PRAVETZ: + oric->render_gimg(GIMG_PRAVETZ_KEYBOARD, 0, 480); + break; +#endif +#ifndef WWW_NO_ORIC1 + case MACH_ORIC1: + case MACH_ORIC1_16K: + oric->render_gimg(GIMG_ORIC1_KEYBOARD, 0, 480); + break; +#endif + default: + oric->render_gimg(GIMG_ATMOS_KEYBOARD, 0, 480); + break; } } } // Overlay the disk icons onto the status bar -void draw_disks( struct machine *oric ) +void draw_disks(struct machine *oric) { Sint32 i, j; - if( oric->statusbar_mode == STATUSBARMODE_NONE ) + if(oric->statusbar_mode == STATUSBARMODE_NONE) return; - if( oric->drivetype == DRV_NONE ) + if(oric->drivetype == DRV_NONE) { - oric->render_gimgpart( GIMG_STATUSBAR, GIMG_POS_DISKX, GIMG_POS_SBARY, GIMG_POS_DISKX, 0, 18*4, 16 ); + oric->render_gimgpart(GIMG_STATUSBAR, GIMG_POS_DISKX, GIMG_POS_SBARY, GIMG_POS_DISKX, 0, 18*4, 16); return; } - for( i=0; i<4; i++ ) + for(i=0; i<4; i++) { j = GIMG_DISK_EJECTED; - if( oric->wddisk.disk[i] ) + if(oric->wddisk.disk[i]) { j = ((oric->wddisk.c_drive==i)&&(oric->wddisk.currentop!=COP_NUFFINK)) ? GIMG_DISK_ACTIVE : GIMG_DISK_IDLE; - if( oric->wddisk.disk[i]->modified ) j+=2; + if(oric->wddisk.disk[i]->modified) j+=2; } - oric->render_gimg( j, GIMG_POS_DISKX+i*GIMG_W_DISK, GIMG_POS_SBARY ); + oric->render_gimg(j, GIMG_POS_DISKX+i*GIMG_W_DISK, GIMG_POS_SBARY); } } // Overlay the AVI record icon onto the status bar -void draw_avirec( struct machine *oric, SDL_bool recording ) +void draw_avirec(struct machine *oric, SDL_bool recording) { - if( oric->statusbar_mode == STATUSBARMODE_NONE) + if(oric->statusbar_mode == STATUSBARMODE_NONE) return; - if( recording ) + if(recording) { - oric->render_gimg( GIMG_AVI_RECORD, GIMG_POS_AVIRECX, GIMG_POS_SBARY ); + oric->render_gimg(GIMG_AVI_RECORD, GIMG_POS_AVIRECX, GIMG_POS_SBARY); return; } - oric->render_gimgpart( GIMG_STATUSBAR, GIMG_POS_AVIRECX, GIMG_POS_SBARY, GIMG_POS_AVIRECX, 0, 16, 16 ); + oric->render_gimgpart(GIMG_STATUSBAR, GIMG_POS_AVIRECX, GIMG_POS_SBARY, GIMG_POS_AVIRECX, 0, 16, 16); } // Overlay the tape icon onto the status bar -void draw_tape( struct machine *oric ) +void draw_tape(struct machine *oric) { - if( oric->statusbar_mode == STATUSBARMODE_NONE ) + if(oric->statusbar_mode == STATUSBARMODE_NONE) return; - if( oric->tapecap ) + if(oric->tapecap) { - oric->render_gimg( GIMG_TAPE_RECORD, GIMG_POS_TAPEX, GIMG_POS_SBARY ); + oric->render_gimg(GIMG_TAPE_RECORD, GIMG_POS_TAPEX, GIMG_POS_SBARY); return; } - if( !oric->tapebuf ) + if(!oric->tapebuf) { - oric->render_gimg( GIMG_TAPE_EJECTED, GIMG_POS_TAPEX, GIMG_POS_SBARY ); + oric->render_gimg(GIMG_TAPE_EJECTED, GIMG_POS_TAPEX, GIMG_POS_SBARY); return; } - if( oric->tapemotor ) + if(oric->tapemotor) { - oric->render_gimg( GIMG_TAPE_PLAY, GIMG_POS_TAPEX, GIMG_POS_SBARY ); + oric->render_gimg(GIMG_TAPE_PLAY, GIMG_POS_TAPEX, GIMG_POS_SBARY); return; } - if( oric->tapeoffs >= oric->tapelen ) + if(oric->tapeoffs >= oric->tapelen) { - oric->render_gimg( GIMG_TAPE_STOP, GIMG_POS_TAPEX, GIMG_POS_SBARY ); + oric->render_gimg(GIMG_TAPE_STOP, GIMG_POS_TAPEX, GIMG_POS_SBARY); return; } - oric->render_gimg( GIMG_TAPE_PAUSE, GIMG_POS_TAPEX, GIMG_POS_SBARY ); + oric->render_gimg(GIMG_TAPE_PAUSE, GIMG_POS_TAPEX, GIMG_POS_SBARY); } // Pop up some info! -void do_popup( struct machine *oric, char *str ) +void do_popup(struct machine *oric, char* str) { - strncpy( oric->popupstr, str, 40 ); oric->popupstr[39] = 0; + strncpy(oric->popupstr, str, 40); + oric->popupstr[39] = 0; oric->newpopupstr = SDL_TRUE; oric->popuptime = 100; } -void render_status( struct machine *oric ) +void render_status(struct machine *oric) { - if( refreshstatus ) - draw_statusbar( oric ); + if(refreshstatus) + draw_statusbar(oric); - if( refreshdisks || refreshstatus ) + if(refreshdisks || refreshstatus) { - draw_disks( oric ); + draw_disks(oric); refreshdisks = SDL_FALSE; } - if( refreshavi || refreshstatus ) + if(refreshavi || refreshstatus) { - draw_avirec( oric, vidcap != NULL ); + draw_avirec(oric, vidcap != NULL); refreshavi = SDL_FALSE; } - if( refreshtape || refreshstatus ) + if(refreshtape || refreshstatus) { - draw_tape( oric ); + draw_tape(oric); refreshtape = SDL_FALSE; } - if(refreshkeyboard || refreshstatus) { - draw_keyboard( oric ); - refreshkeyboard = SDL_FALSE; - } + if(refreshkeyboard || refreshstatus) + { + draw_keyboard(oric); + refreshkeyboard = SDL_FALSE; + } refreshstatus = SDL_FALSE; } // Top-level rendering routine -void render( struct machine *oric ) +void render(struct machine *oric) { int perc, fps; //, i; - if( oric->emu_mode == EM_DEBUG ) - mon_update( oric ); +#ifndef WWW_NO_MONITOR + if(oric->emu_mode == EM_DEBUG) + mon_update(oric); +#endif - oric->render_begin( oric ); + oric->render_begin(oric); - switch( oric->emu_mode ) + switch(oric->emu_mode) { case EM_MENU: - oric->render_video( oric, SDL_TRUE ); - render_status( oric ); - if( tz[TZ_MENU] ) oric->render_textzone( oric, TZ_MENU ); + oric->render_video(oric, SDL_TRUE); + render_status(oric); + if(tz[TZ_MENU]) oric->render_textzone(oric, TZ_MENU); break; case EM_RUNNING: - oric->render_video( oric, SDL_TRUE ); - render_status( oric ); - if( oric->statusbar_mode == STATUSBARMODE_FULL ) + oric->render_video(oric, SDL_TRUE); + render_status(oric); + if(oric->statusbar_mode == STATUSBARMODE_FULL) { fps = 100000/(frametimeave?frametimeave:1); - if( oric->vid_freq ) + if(oric->vid_freq) perc = 200000/(frametimeave?frametimeave:1); else perc = 166667/(frametimeave?frametimeave:1); #ifdef DEBUG_VSYNC - sprintf( oric->statusstr, "%4d.%02d%% - %4dFPS VSYNC:%3d", perc/100, perc%100, fps/100, oric->vid_offset ); + sprintf(oric->statusstr, "%4d.%02d%% - %4dFPS VSYNC:%3d", perc/100, perc%100, fps/100, oric->vid_offset); #else - sprintf( oric->statusstr, "%4d.%02d%% - %4dFPS", perc/100, perc%100, fps/100 ); + sprintf(oric->statusstr, "%4d.%02d%% - %4dFPS", perc/100, perc%100, fps/100); #endif oric->newstatusstr = SDL_TRUE; } - if( oric->popuptime > 0 ) + if(oric->popuptime > 0) { oric->popuptime--; - if( oric->popuptime == 0 ) + if(oric->popuptime == 0) { oric->popupstr[0] = 0; oric->newpopupstr = SDL_TRUE; @@ -634,26 +689,28 @@ void render( struct machine *oric ) } break; +#ifndef WWW_NO_MONITOR case EM_DEBUG: - mon_render( oric ); + mon_render(oric); break; +#endif } - oric->render_end( oric ); + oric->render_end(oric); } // Draws a box in a textzone (uses the box chars in the font) // ptz = target textzone // x,y,w,h = location and dimensions // fg,bg = colours -void makebox( struct textzone *ptz, int x, int y, int w, int h, int fg, int bg ) +void makebox(struct textzone *ptz, int x, int y, int w, int h, int fg, int bg) { int cx, cy, o, bo; o = y*ptz->w+x; - for( cy=0; cytx[o ] = ' '; ptz->fc[o ] = fg; @@ -667,7 +724,7 @@ void makebox( struct textzone *ptz, int x, int y, int w, int h, int fg, int bg ) o = y*ptz->w+x; bo = o + (h-1)*ptz->w; - for( cx=0; cx<(w-1); cx++ ) + for(cx=0; cx<(w-1); cx++) { ptz->tx[o++] = cx==0?1:2; ptz->tx[bo++] = cx==0?9:2; @@ -679,14 +736,14 @@ void makebox( struct textzone *ptz, int x, int y, int w, int h, int fg, int bg ) } // Write a string to a textzone -void tzstr( struct textzone *ptz, char *text ) +void tzstr(struct textzone *ptz, char* text) { int i, o; o = ptz->py*ptz->w+ptz->px; - for( i=0; text && text[i]; i++ ) + for(i=0; text && text[i]; i++) { - switch( text[i] ) + switch(text[i]) { case 10: ptz->px = 1; @@ -702,7 +759,7 @@ void tzstr( struct textzone *ptz, char *text ) ptz->fc[o ] = ptz->cfc; ptz->bc[o++] = ptz->cbc; ptz->px++; - if( ptz->px >= ptz->w ) + if(ptz->px >= ptz->w) { ptz->px = 1; ptz->py++; @@ -715,78 +772,78 @@ void tzstr( struct textzone *ptz, char *text ) ptz->modified = SDL_TRUE; } -void tzputc( struct textzone *ptz, char c ) +void tzputc(struct textzone *ptz, char c) { char tmp[2]; tmp[0] = c; tmp[1] = 0; - tzstr( ptz, tmp ); + tzstr(ptz, tmp); } // Print a formatted string into a textzone -void tzprintf( struct textzone *ptz, char *fmt, ... ) +void tzprintf(struct textzone *ptz, char* fmt, ...) { va_list ap; - va_start( ap, fmt ); - if( vsnprintf( vsptmp, VSPTMPSIZE, fmt, ap ) != -1 ) + va_start(ap, fmt); + if(vsnprintf(vsptmp, VSPTMPSIZE, fmt, ap) != -1) { vsptmp[VSPTMPSIZE-1] = 0; - tzstr( ptz, vsptmp ); + tzstr(ptz, vsptmp); } - va_end( ap ); + va_end(ap); } // Write a string to a textzone at a specific location -void tzstrpos( struct textzone *ptz, int x, int y, char *text ) +void tzstrpos(struct textzone *ptz, int x, int y, char* text) { ptz->px = x; ptz->py = y; - tzstr( ptz, text ); + tzstr(ptz, text); } // Print a formatted string into a textzone at a specific location -void tzprintfpos( struct textzone *ptz, int x, int y, char *fmt, ... ) +void tzprintfpos(struct textzone *ptz, int x, int y, char* fmt, ...) { va_list ap; - va_start( ap, fmt ); - if( vsnprintf( vsptmp, VSPTMPSIZE, fmt, ap ) != -1 ) + va_start(ap, fmt); + if(vsnprintf(vsptmp, VSPTMPSIZE, fmt, ap) != -1) { vsptmp[VSPTMPSIZE-1] = 0; - tzstrpos( ptz, x, y, vsptmp ); + tzstrpos(ptz, x, y, vsptmp); } - va_end( ap ); + va_end(ap); } // Set the foreground and background colours for printing text into a textzone -void tzsetcol( struct textzone *ptz, int fc, int bc ) +void tzsetcol(struct textzone *ptz, int fc, int bc) { ptz->cfc = fc; ptz->cbc = bc; } // Set the title of a textzone -void tzsettitle( struct textzone *ptz, char *title ) +void tzsettitle(struct textzone *ptz, char* title) { int ox, oy; - makebox( ptz, 0, 0, ptz->w, ptz->h, menufc(SDL_FALSE), menubc(SDL_FALSE)); - if( !title ) return; + makebox(ptz, 0, 0, ptz->w, ptz->h, menufc(SDL_FALSE), menubc(SDL_FALSE)); + if(!title) return; - tzsetcol( ptz, menufc(SDL_FALSE), menubc(SDL_FALSE)); + tzsetcol(ptz, menufc(SDL_FALSE), menubc(SDL_FALSE)); ox = ptz->px; oy = ptz->py; ptz->px = 3; ptz->py = 0; - tzstr( ptz, "[ " ); - tzstr( ptz, title ); - tzstr( ptz, " ]" ); + tzstr(ptz, "[ "); + tzstr(ptz, title); + tzstr(ptz, " ]"); ptz->px = ox; ptz->py = oy; } -SDL_bool in_textzone( struct textzone *tz_, int x, int y ) +SDL_bool in_textzone(struct textzone *tz_, int x, int y) { - if( ( x >= tz_->x ) && ( x < (tz_->x+tz_->w*8) ) && - ( y >= tz_->y ) && ( y < (tz_->y+tz_->h*12) ) ) + if((x >= tz_->x) && (x < (tz_->x+tz_->w*8)) && + (y >= tz_->y) && (y < (tz_->y+tz_->h*12))) { return SDL_TRUE; } @@ -795,23 +852,23 @@ SDL_bool in_textzone( struct textzone *tz_, int x, int y ) } // Allocate a textzone structure -SDL_bool alloc_textzone( struct machine *oric, int i, int x, int y, int w, int h, char *title ) +SDL_bool alloc_textzone(struct machine *oric, int i, int x, int y, int w, int h, char* title) { struct textzone *ntz; - ntz = malloc( sizeof( struct textzone ) + w*h*3 ); - if( !ntz ) return SDL_FALSE; + ntz = malloc(sizeof(struct textzone) + w*h*3); + if(!ntz) return SDL_FALSE; ntz->x = x; ntz->y = y; ntz->w = w; ntz->h = h; - ntz->tx = (unsigned char *)(&ntz[1]); + ntz->tx = (unsigned char*)(&ntz[1]); ntz->fc = &ntz->tx[w*h]; ntz->bc = &ntz->fc[w*h]; - tzsettitle( ntz, title ); + tzsettitle(ntz, title); ntz->px = 1; ntz->py = 1; @@ -819,21 +876,21 @@ SDL_bool alloc_textzone( struct machine *oric, int i, int x, int y, int w, int h ntz->modified = SDL_TRUE; tz[i] = ntz; - oric->render_textzone_alloc( oric, i ); + oric->render_textzone_alloc(oric, i); return SDL_TRUE; } -void clear_textzone( struct machine *oric, int i ) +void clear_textzone(struct machine *oric, int i) { int x, y; struct textzone *ptz = tz[i]; - if (!ptz) return; + if(!ptz) return; - for( y=1; y<(ptz->h-1); y++ ) + for(y=1; y<(ptz->h-1); y++) { - for( x=1; x<(ptz->w-1); x++ ) + for(x=1; x<(ptz->w-1); x++) { ptz->tx[y*ptz->w+x] = ' '; ptz->fc[y*ptz->w+x] = 2; @@ -845,32 +902,32 @@ void clear_textzone( struct machine *oric, int i ) } // Free a textzone structure -void free_textzone( struct machine *oric, int i ) +void free_textzone(struct machine *oric, int i) { - oric->render_textzone_free( oric, i ); - if( !tz[i] ) return; - free( tz[i] ); + oric->render_textzone_free(oric, i); + if(!tz[i]) return; + free(tz[i]); tz[i] = NULL; } // Draw the current menu items into the menu textzone -void drawitems( void ) +void drawitems(void) { int i, j, o; // No menu, or no textzone? - if( ( !cmenu ) || ( !tz[TZ_MENU] ) ) + if((!cmenu) || (!tz[TZ_MENU])) return; // For each item... - for( i=0; cmenu->items[i].name; i++ ) + for(i=0; cmenu->items[i].name; i++) { // Check if its a menu bar - if( cmenu->items[i].name == OSDMENUBAR ) + if(cmenu->items[i].name == OSDMENUBAR) { // Fill it with the menu bar char o = tz[TZ_MENU]->w * (i+1) + 1; - for( j=1; jw-1; j++, o++ ) + for(j=1; jw-1; j++, o++) { tz[TZ_MENU]->tx[o] = 12; tz[TZ_MENU]->fc[o] = menufc(SDL_FALSE); @@ -880,75 +937,77 @@ void drawitems( void ) } // Check if this is the highlighted item, and set the colours accordingly - if( i==cmenu->citem ) - tzsetcol( tz[TZ_MENU], menufc(SDL_TRUE), menubc(SDL_TRUE)); + if(i==cmenu->citem) + tzsetcol(tz[TZ_MENU], menufc(SDL_TRUE), menubc(SDL_TRUE)); else - tzsetcol( tz[TZ_MENU], (cmenu->items[i].flags&OMIF_BRIGHT) ? 1 : menufc(SDL_FALSE), menubc(SDL_FALSE)); + tzsetcol(tz[TZ_MENU], (cmenu->items[i].flags&OMIF_BRIGHT) ? 1 : menufc(SDL_FALSE), menubc(SDL_FALSE)); // Calculate the position in the textzone o = tz[TZ_MENU]->w * (i+1) + 1; // Fill the background colour all the way along - for( j=1; jw-1; j++, o++ ) + for(j=1; jw-1; j++, o++) tz[TZ_MENU]->bc[o] = tz[TZ_MENU]->cbc; // Write the text for the item - if( cmenu->items[i].flags & OMIF_CENTRED ) - tzstrpos( tz[TZ_MENU], (tz[TZ_MENU]->w-(int)strlen(cmenu->items[i].name))/2, i+1, cmenu->items[i].name ); + if(cmenu->items[i].flags & OMIF_CENTRED) + tzstrpos(tz[TZ_MENU], (tz[TZ_MENU]->w-(int)strlen(cmenu->items[i].name))/2, i+1, cmenu->items[i].name); else - tzstrpos( tz[TZ_MENU], 1, i+1, cmenu->items[i].name ); + tzstrpos(tz[TZ_MENU], 1, i+1, cmenu->items[i].name); // And the key (if there is one) - if( cmenu->items[i].key ) - tzstrpos( tz[TZ_MENU], tz[TZ_MENU]->w-(1+(int)strlen(cmenu->items[i].key)), i+1, cmenu->items[i].key ); + if(cmenu->items[i].key) + tzstrpos(tz[TZ_MENU], tz[TZ_MENU]->w-(1+(int)strlen(cmenu->items[i].key)), i+1, cmenu->items[i].key); } } /***************** These functions can be used directly from the menu system ***************/ -void joinpath( char *path, char *file ) +void joinpath(char* path, char* file) { #if defined(__amigaos4__) - strcpy( filetmp, path ); - IDOS->AddPart( filetmp, file, 4096 ); + strcpy(filetmp, path); + IDOS->AddPart(filetmp, file, 4096); #elif defined(WIN32) int i; - strncpy( filetmp, path, 4096 ); filetmp[4095] = 0; - i = strlen( filetmp ); - if( ( i > 0 ) && ( filetmp[i-1] != PATHSEP ) && ( filetmp[i-1] != ':' ) ) + strncpy(filetmp, path, 4096); + filetmp[4095] = 0; + i = strlen(filetmp); + if((i > 0) && (filetmp[i-1] != PATHSEP) && (filetmp[i-1] != ':')) { filetmp[i++] = PATHSEP; filetmp[i++] = 0; } - strncat( filetmp, file, 4096+512 ); + strncat(filetmp, file, 4096+512); filetmp[4096+511] = 0; #else int i; - strncpy( filetmp, path, 4096 ); filetmp[4095] = 0; - i = (int)strlen( filetmp ); - if( ( i > 0 ) && ( filetmp[i-1] != PATHSEP ) ) + strncpy(filetmp, path, 4096); + filetmp[4095] = 0; + i = (int)strlen(filetmp); + if((i > 0) && (filetmp[i-1] != PATHSEP)) { filetmp[i++] = PATHSEP; filetmp[i++] = 0; } - strncat( filetmp, file, 4096+512 ); + strncat(filetmp, file, 4096+512); filetmp[4096+511] = 0; #endif } // "insert" a tape into the virtual tape drive, via filerequester -void inserttape( struct machine *oric, struct osdmenuitem *mitem, int dummy ) +void inserttape(struct machine *oric, struct osdmenuitem *mitem, int dummy) { - if( !filerequester( oric, "Insert tape", tapepath, tapefile, FR_TAPELOAD ) ) return; + if(!filerequester(oric, "Insert tape", tapepath, tapefile, FR_TAPELOAD)) return; oric->lasttapefile[0] = 0; - joinpath( tapepath, tapefile ); + joinpath(tapepath, tapefile); - switch (detect_image_type(filetmp)) + switch(detect_image_type(filetmp)) { case IMG_SNAPSHOT: - if (msgbox(oric, MSGBOX_YES_NO, - "The file you selected appears to be a snapshot file.\n" - "Would you like to load it? (All RAM and machine state will be lost)")) + if(msgbox(oric, MSGBOX_YES_NO, + "The file you selected appears to be a snapshot file.\n" + "Would you like to load it? (All RAM and machine state will be lost)")) { load_snapshot(oric, filetmp); return; @@ -956,195 +1015,197 @@ void inserttape( struct machine *oric, struct osdmenuitem *mitem, int dummy ) break; case IMG_ATMOS_MICRODISC: - if ((oric->type != MACH_ATMOS) && + if((oric->type != MACH_ATMOS) && (oric->type != MACH_ORIC1) && (oric->type != MACH_PRAVETZ)) { - if (msgbox(oric, MSGBOX_YES_NO, - "The file you selected appears to be a disk for an Oric Atmos with Microdisc.\n" - "Would you like to switch to that configuration and insert it as a disk?")) + if(msgbox(oric, MSGBOX_YES_NO, + "The file you selected appears to be a disk for an Oric Atmos with Microdisc.\n" + "Would you like to switch to that configuration and insert it as a disk?")) { - swapmach( oric, NULL, (DRV_MICRODISC<<16)|MACH_ATMOS ); - joinpath( tapepath, tapefile ); - diskimage_load( oric, filetmp, 0 ); + swapmach(oric, NULL, (DRV_MICRODISC<<16)|MACH_ATMOS); + joinpath(tapepath, tapefile); + diskimage_load(oric, filetmp, 0); } - setemumode( oric, NULL, EM_RUNNING ); + setemumode(oric, NULL, EM_RUNNING); return; } - if (oric->drivetype != DRV_MICRODISC) + if(oric->drivetype != DRV_MICRODISC) { - if (msgbox(oric, MSGBOX_YES_NO, - "The file you selected appears to be a disk for a use with the Microdisc controller.\n" - "Would you like to switch to that configuration and insert it as a disk?")) + if(msgbox(oric, MSGBOX_YES_NO, + "The file you selected appears to be a disk for a use with the Microdisc controller.\n" + "Would you like to switch to that configuration and insert it as a disk?")) { - swapmach( oric, NULL, (DRV_MICRODISC<<16)|oric->type ); - joinpath( tapepath, tapefile ); - diskimage_load( oric, filetmp, 0 ); + swapmach(oric, NULL, (DRV_MICRODISC<<16)|oric->type); + joinpath(tapepath, tapefile); + diskimage_load(oric, filetmp, 0); } - setemumode( oric, NULL, EM_RUNNING ); + setemumode(oric, NULL, EM_RUNNING); return; } - if (msgbox(oric, MSGBOX_YES_NO, - "The file you selected appears to be a disk.\n" - "Would you like to insert it in drive 0?")) + if(msgbox(oric, MSGBOX_YES_NO, + "The file you selected appears to be a disk.\n" + "Would you like to insert it in drive 0?")) { - joinpath( tapepath, tapefile ); - diskimage_load( oric, filetmp, 0 ); + joinpath(tapepath, tapefile); + diskimage_load(oric, filetmp, 0); } - setemumode( oric, NULL, EM_RUNNING ); + setemumode(oric, NULL, EM_RUNNING); return; case IMG_ATMOS_JASMIN: - if ((oric->type != MACH_ATMOS) && + if((oric->type != MACH_ATMOS) && (oric->type != MACH_ORIC1) && (oric->type != MACH_PRAVETZ)) { - if (msgbox(oric, MSGBOX_YES_NO, - "The file you selected appears to be a disk for an Oric Atmos with Jasmin.\n" - "Would you like to switch to that configuration and insert it as a disk?")) + if(msgbox(oric, MSGBOX_YES_NO, + "The file you selected appears to be a disk for an Oric Atmos with Jasmin.\n" + "Would you like to switch to that configuration and insert it as a disk?")) { - swapmach( oric, NULL, (DRV_JASMIN<<16)|MACH_ATMOS ); - joinpath( tapepath, tapefile ); - diskimage_load( oric, filetmp, 0 ); + swapmach(oric, NULL, (DRV_JASMIN<<16)|MACH_ATMOS); + joinpath(tapepath, tapefile); + diskimage_load(oric, filetmp, 0); oric->auto_jasmin_reset = SDL_TRUE; } - setemumode( oric, NULL, EM_RUNNING ); + setemumode(oric, NULL, EM_RUNNING); return; } - if (oric->drivetype != DRV_JASMIN) + if(oric->drivetype != DRV_JASMIN) { - if (msgbox(oric, MSGBOX_YES_NO, - "The file you selected appears to be a disk for a use with the Jasmin controller.\n" - "Would you like to switch to that configuration and insert it as a disk?")) + if(msgbox(oric, MSGBOX_YES_NO, + "The file you selected appears to be a disk for a use with the Jasmin controller.\n" + "Would you like to switch to that configuration and insert it as a disk?")) { - swapmach( oric, NULL, (DRV_JASMIN<<16)|oric->type ); - joinpath( tapepath, tapefile ); - diskimage_load( oric, filetmp, 0 ); + swapmach(oric, NULL, (DRV_JASMIN<<16)|oric->type); + joinpath(tapepath, tapefile); + diskimage_load(oric, filetmp, 0); oric->auto_jasmin_reset = SDL_TRUE; } - setemumode( oric, NULL, EM_RUNNING ); + setemumode(oric, NULL, EM_RUNNING); return; } - if (msgbox(oric, MSGBOX_YES_NO, - "The file you selected appears to be a disk.\n" - "Would you like to insert it in drive 0?")) + if(msgbox(oric, MSGBOX_YES_NO, + "The file you selected appears to be a disk.\n" + "Would you like to insert it in drive 0?")) { - joinpath( tapepath, tapefile ); - diskimage_load( oric, filetmp, 0 ); + joinpath(tapepath, tapefile); + diskimage_load(oric, filetmp, 0); } - setemumode( oric, NULL, EM_RUNNING ); + setemumode(oric, NULL, EM_RUNNING); return; case IMG_TELESTRAT_DISK: - if (oric->type != MACH_TELESTRAT) + if(oric->type != MACH_TELESTRAT) { - if (msgbox(oric, MSGBOX_YES_NO, - "The file you selected appears to be a disk for the Telestrat.\n" - "Would you like to switch to that configuration and insert it as a disk?")) + if(msgbox(oric, MSGBOX_YES_NO, + "The file you selected appears to be a disk for the Telestrat.\n" + "Would you like to switch to that configuration and insert it as a disk?")) { - swapmach( oric, NULL, MACH_TELESTRAT ); - joinpath( tapepath, tapefile ); - diskimage_load( oric, filetmp, 0 ); + swapmach(oric, NULL, MACH_TELESTRAT); + joinpath(tapepath, tapefile); + diskimage_load(oric, filetmp, 0); } - setemumode( oric, NULL, EM_RUNNING ); + setemumode(oric, NULL, EM_RUNNING); return; } - if (msgbox(oric, MSGBOX_YES_NO, - "The file you selected appears to be a disk.\n" - "Would you like to insert it in drive 0?")) + if(msgbox(oric, MSGBOX_YES_NO, + "The file you selected appears to be a disk.\n" + "Would you like to insert it in drive 0?")) { - joinpath( tapepath, tapefile ); - diskimage_load( oric, filetmp, 0 ); + joinpath(tapepath, tapefile); + diskimage_load(oric, filetmp, 0); } - setemumode( oric, NULL, EM_RUNNING ); + setemumode(oric, NULL, EM_RUNNING); return; case IMG_PRAVETZ_DISK: - if (oric->type != MACH_PRAVETZ) + if(oric->type != MACH_PRAVETZ) { - if (msgbox(oric, MSGBOX_YES_NO, - "The file you selected appears to be a disk for the Pravetz 8D disk controller.\n" - "Would you like to switch to that configuration and insert it as a disk?")) + if(msgbox(oric, MSGBOX_YES_NO, + "The file you selected appears to be a disk for the Pravetz 8D disk controller.\n" + "Would you like to switch to that configuration and insert it as a disk?")) { - swapmach( oric, NULL, (DRV_PRAVETZ<<16)|MACH_PRAVETZ ); - joinpath( tapepath, tapefile ); - diskimage_load( oric, filetmp, 0 ); - pravdiskboot( oric ); + swapmach(oric, NULL, (DRV_PRAVETZ<<16)|MACH_PRAVETZ); + joinpath(tapepath, tapefile); + diskimage_load(oric, filetmp, 0); + pravdiskboot(oric); } - setemumode( oric, NULL, EM_RUNNING ); + setemumode(oric, NULL, EM_RUNNING); return; } - if (oric->drivetype != DRV_PRAVETZ) + if(oric->drivetype != DRV_PRAVETZ) { - if (msgbox(oric, MSGBOX_YES_NO, - "The file you selected appears to be a disk for the Pravetz disk controller.\n" - "Would you like to switch to that configuration and insert it as a disk?")) + if(msgbox(oric, MSGBOX_YES_NO, + "The file you selected appears to be a disk for the Pravetz disk controller.\n" + "Would you like to switch to that configuration and insert it as a disk?")) { - swapmach( oric, NULL, (DRV_PRAVETZ<<16)|MACH_PRAVETZ ); - joinpath( tapepath, tapefile ); - diskimage_load( oric, filetmp, 0 ); - pravdiskboot( oric ); + swapmach(oric, NULL, (DRV_PRAVETZ<<16)|MACH_PRAVETZ); + joinpath(tapepath, tapefile); + diskimage_load(oric, filetmp, 0); + pravdiskboot(oric); } - setemumode( oric, NULL, EM_RUNNING ); + setemumode(oric, NULL, EM_RUNNING); return; } - if (msgbox(oric, MSGBOX_YES_NO, - "The file you selected appears to be a disk.\n" - "Would you like to insert it in drive 0?")) + if(msgbox(oric, MSGBOX_YES_NO, + "The file you selected appears to be a disk.\n" + "Would you like to insert it in drive 0?")) { - joinpath( tapepath, tapefile ); - diskimage_load( oric, filetmp, 0 ); + joinpath(tapepath, tapefile); + diskimage_load(oric, filetmp, 0); } - setemumode( oric, NULL, EM_RUNNING ); + setemumode(oric, NULL, EM_RUNNING); return; case IMG_GUESS_MICRODISC: - if ((oric->drivetype == DRV_PRAVETZ) || + if((oric->drivetype == DRV_PRAVETZ) || (oric->drivetype == DRV_NONE)) { - if (msgbox(oric, MSGBOX_YES_NO, - "The file you selected appears to be a disk for a Microdisc or Jasmin system.\n" - "Would you like to switch to Microdisc and insert it as a disk?")) + if(msgbox(oric, MSGBOX_YES_NO, + "The file you selected appears to be a disk for a Microdisc or Jasmin system.\n" + "Would you like to switch to Microdisc and insert it as a disk?")) { - swapmach( oric, NULL, (DRV_MICRODISC<<16)|oric->type ); - joinpath( tapepath, tapefile ); - diskimage_load( oric, filetmp, 0 ); + swapmach(oric, NULL, (DRV_MICRODISC<<16)|oric->type); + joinpath(tapepath, tapefile); + diskimage_load(oric, filetmp, 0); } - setemumode( oric, NULL, EM_RUNNING ); + setemumode(oric, NULL, EM_RUNNING); return; } - if (msgbox(oric, MSGBOX_YES_NO, - "The file you selected appears to be a disk.\n" - "Would you like to insert it in drive 0?")) + if(msgbox(oric, MSGBOX_YES_NO, + "The file you selected appears to be a disk.\n" + "Would you like to insert it in drive 0?")) { - joinpath( tapepath, tapefile ); - diskimage_load( oric, filetmp, 0 ); + joinpath(tapepath, tapefile); + diskimage_load(oric, filetmp, 0); } - setemumode( oric, NULL, EM_RUNNING ); + setemumode(oric, NULL, EM_RUNNING); return; } - tape_load_tap( oric, filetmp ); - if( oric->symbolsautoload ) mon_new_symbols( &oric->usersyms, oric, "symbols", SYM_BESTGUESS, SDL_TRUE, SDL_TRUE ); - setemumode( oric, NULL, EM_RUNNING ); + tape_load_tap(oric, filetmp); +#ifndef WWW_NO_MONITOR + if(oric->symbolsautoload) mon_new_symbols(&oric->usersyms, oric, "symbols", SYM_BESTGUESS, SDL_TRUE, SDL_TRUE); +#endif + setemumode(oric, NULL, EM_RUNNING); } // "insert" a disk into the virtual disk drive, via filerequester -void insertdisk( struct machine *oric, struct osdmenuitem *mitem, int drive ) +void insertdisk(struct machine *oric, struct osdmenuitem *mitem, int drive) { - char *dpath, *dfile; + char* dpath, *dfile; - if( oric->type != MACH_TELESTRAT ) + if(oric->type != MACH_TELESTRAT) { - switch (oric->drivetype) + switch(oric->drivetype) { case DRV_PRAVETZ: dpath = pravdiskpath; @@ -1156,20 +1217,22 @@ void insertdisk( struct machine *oric, struct osdmenuitem *mitem, int drive ) dfile = diskfile; break; } - } else { + } + else + { dpath = telediskpath; dfile = telediskfile; } - if( !filerequester( oric, "Insert disk", dpath, dfile, FR_DISKLOAD ) ) return; - joinpath( dpath, dfile ); + if(!filerequester(oric, "Insert disk", dpath, dfile, FR_DISKLOAD)) return; + joinpath(dpath, dfile); - switch (detect_image_type(filetmp)) + switch(detect_image_type(filetmp)) { case IMG_SNAPSHOT: - if (msgbox(oric, MSGBOX_YES_NO, - "The file you selected appears to be a snapshot file.\n" - "Would you like to load it? (All RAM and machine state will be lost)")) + if(msgbox(oric, MSGBOX_YES_NO, + "The file you selected appears to be a snapshot file.\n" + "Would you like to load it? (All RAM and machine state will be lost)")) { load_snapshot(oric, filetmp); return; @@ -1177,61 +1240,61 @@ void insertdisk( struct machine *oric, struct osdmenuitem *mitem, int drive ) break; case IMG_ATMOS_MICRODISC: - if ((oric->type != MACH_ATMOS) && + if((oric->type != MACH_ATMOS) && (oric->type != MACH_ORIC1) && (oric->type != MACH_PRAVETZ)) { - if (msgbox(oric, MSGBOX_YES_NO, - "The file you selected appears to be for an Oric Atmos with Microdisc.\n" - "Would you like to switch to that configuration?")) + if(msgbox(oric, MSGBOX_YES_NO, + "The file you selected appears to be for an Oric Atmos with Microdisc.\n" + "Would you like to switch to that configuration?")) { - swapmach( oric, NULL, (DRV_MICRODISC<<16)|MACH_ATMOS ); + swapmach(oric, NULL, (DRV_MICRODISC<<16)|MACH_ATMOS); } break; } - if ((oric->drivetype != DRV_MICRODISC) && + if((oric->drivetype != DRV_MICRODISC) && (oric->drivetype != DRV_NONE)) { - if (msgbox(oric, MSGBOX_YES_NO, - "The file you selected appears to be for a use with the Microdisc controller.\n" - "Would you like to switch to that configuration?")) + if(msgbox(oric, MSGBOX_YES_NO, + "The file you selected appears to be for a use with the Microdisc controller.\n" + "Would you like to switch to that configuration?")) { - swapmach( oric, NULL, (DRV_MICRODISC<<16)|oric->type ); + swapmach(oric, NULL, (DRV_MICRODISC<<16)|oric->type); } break; } break; case IMG_ATMOS_JASMIN: - if ((oric->type != MACH_ATMOS) && + if((oric->type != MACH_ATMOS) && (oric->type != MACH_ORIC1) && (oric->type != MACH_PRAVETZ)) { - if (msgbox(oric, MSGBOX_YES_NO, - "The file you selected appears to be for an Oric Atmos with Jasmin.\n" - "Would you like to switch to that configuration?")) + if(msgbox(oric, MSGBOX_YES_NO, + "The file you selected appears to be for an Oric Atmos with Jasmin.\n" + "Would you like to switch to that configuration?")) { - swapmach( oric, NULL, (DRV_JASMIN<<16)|MACH_ATMOS ); + swapmach(oric, NULL, (DRV_JASMIN<<16)|MACH_ATMOS); oric->auto_jasmin_reset = SDL_TRUE; } break; } - if (oric->drivetype == DRV_NONE) + if(oric->drivetype == DRV_NONE) { - swapmach( oric, NULL, (DRV_JASMIN<<16)|oric->type); + swapmach(oric, NULL, (DRV_JASMIN<<16)|oric->type); oric->auto_jasmin_reset = SDL_TRUE; break; } - if (oric->drivetype != DRV_JASMIN) + if(oric->drivetype != DRV_JASMIN) { - if (msgbox(oric, MSGBOX_YES_NO, - "The file you selected appears to be for a use with the Jasmin controller.\n" - "Would you like to switch to that configuration?")) + if(msgbox(oric, MSGBOX_YES_NO, + "The file you selected appears to be for a use with the Jasmin controller.\n" + "Would you like to switch to that configuration?")) { - swapmach( oric, NULL, (DRV_JASMIN<<16)|oric->type ); + swapmach(oric, NULL, (DRV_JASMIN<<16)|oric->type); oric->auto_jasmin_reset = SDL_TRUE; } break; @@ -1239,101 +1302,104 @@ void insertdisk( struct machine *oric, struct osdmenuitem *mitem, int drive ) break; case IMG_TELESTRAT_DISK: - if (oric->type != MACH_TELESTRAT) + if(oric->type != MACH_TELESTRAT) { - if (msgbox(oric, MSGBOX_YES_NO, - "The file you selected appears to be for a Telestrat.\n" - "Would you like to switch to that configuration?")) + if(msgbox(oric, MSGBOX_YES_NO, + "The file you selected appears to be for a Telestrat.\n" + "Would you like to switch to that configuration?")) { - swapmach( oric, NULL, MACH_TELESTRAT ); + swapmach(oric, NULL, MACH_TELESTRAT); } break; } break; case IMG_PRAVETZ_DISK: - if (oric->type != MACH_PRAVETZ) + if(oric->type != MACH_PRAVETZ) { - if (msgbox(oric, MSGBOX_YES_NO, - "The file you selected appears to be for a Pravetz 8D disk controller.\n" - "Would you like to switch to that configuration?")) + if(msgbox(oric, MSGBOX_YES_NO, + "The file you selected appears to be for a Pravetz 8D disk controller.\n" + "Would you like to switch to that configuration?")) { - swapmach( oric, NULL, (DRV_PRAVETZ<<16)|MACH_PRAVETZ ); - pravdiskboot( oric ); + swapmach(oric, NULL, (DRV_PRAVETZ<<16)|MACH_PRAVETZ); + pravdiskboot(oric); } break; } - if (oric->drivetype == DRV_NONE) + if(oric->drivetype == DRV_NONE) { - swapmach( oric, NULL, (DRV_PRAVETZ<<16)|MACH_PRAVETZ ); - pravdiskboot( oric ); + swapmach(oric, NULL, (DRV_PRAVETZ<<16)|MACH_PRAVETZ); + pravdiskboot(oric); break; } - if (oric->drivetype != DRV_PRAVETZ) + if(oric->drivetype != DRV_PRAVETZ) { - if (msgbox(oric, MSGBOX_YES_NO, - "The file you selected appears to be for a use with the Pravetz disk controller.\n" - "Would you like to switch to that configuration?")) + if(msgbox(oric, MSGBOX_YES_NO, + "The file you selected appears to be for a use with the Pravetz disk controller.\n" + "Would you like to switch to that configuration?")) { - swapmach( oric, NULL, (DRV_PRAVETZ<<16)|MACH_PRAVETZ ); - pravdiskboot( oric ); + swapmach(oric, NULL, (DRV_PRAVETZ<<16)|MACH_PRAVETZ); + pravdiskboot(oric); } break; } break; case IMG_GUESS_MICRODISC: - if (oric->drivetype == DRV_PRAVETZ) + if(oric->drivetype == DRV_PRAVETZ) { - if (msgbox(oric, MSGBOX_YES_NO, - "The file you selected appears to be for a Microdisc or Jasmin system.\n" - "Would you like to switch to Microdisc?")) + if(msgbox(oric, MSGBOX_YES_NO, + "The file you selected appears to be for a Microdisc or Jasmin system.\n" + "Would you like to switch to Microdisc?")) { - swapmach( oric, NULL, (DRV_MICRODISC<<16)|oric->type ); + swapmach(oric, NULL, (DRV_MICRODISC<<16)|oric->type); } break; } break; case IMG_TAPE: - if (msgbox(oric, MSGBOX_YES_NO, - "This appears to be a tape image...\n" - "Would you like to insert it as a tape?")) + if(msgbox(oric, MSGBOX_YES_NO, + "This appears to be a tape image...\n" + "Would you like to insert it as a tape?")) { oric->lasttapefile[0] = 0; - tape_load_tap( oric, filetmp ); - if( oric->symbolsautoload ) mon_new_symbols( &oric->usersyms, oric, "symbols", SYM_BESTGUESS, SDL_TRUE, SDL_TRUE ); + tape_load_tap(oric, filetmp); +#ifndef WWW_NO_MONITOR + if(oric->symbolsautoload) mon_new_symbols(&oric->usersyms, oric, "symbols", SYM_BESTGUESS, SDL_TRUE, SDL_TRUE); +#endif } - setemumode( oric, NULL, EM_RUNNING ); + setemumode(oric, NULL, EM_RUNNING); return; } - joinpath( dpath, dfile ); - diskimage_load( oric, filetmp, drive ); + joinpath(dpath, dfile); + diskimage_load(oric, filetmp, drive); - if( oric->drivetype == DRV_NONE ) + if(oric->drivetype == DRV_NONE) { - swapmach( oric, NULL, (DRV_MICRODISC<<16)|oric->type ); -// setemumode( oric, NULL, EM_DEBUG ); + if(!oric->twilighteboard_activated) + swapmach(oric, NULL, (DRV_MICRODISC<<16)|oric->type); + // setemumode( oric, NULL, EM_DEBUG ); return; } - setemumode( oric, NULL, EM_RUNNING ); + setemumode(oric, NULL, EM_RUNNING); } -void savesnap( struct machine *oric, struct osdmenuitem *mitem, int dummy ) +void savesnap(struct machine *oric, struct osdmenuitem *mitem, int dummy) { - if( !filerequester( oric, "Save Snapshot", snappath, snapfile, FR_SNAPSHOTSAVE ) ) return; - joinpath( snappath, snapfile ); - save_snapshot( oric, filetmp ); + if(!filerequester(oric, "Save Snapshot", snappath, snapfile, FR_SNAPSHOTSAVE)) return; + joinpath(snappath, snapfile); + save_snapshot(oric, filetmp); } -void loadsnap( struct machine *oric, struct osdmenuitem *mitem, int dummy ) +void loadsnap(struct machine *oric, struct osdmenuitem *mitem, int dummy) { - if( !filerequester( oric, "Load Snapshot", snappath, snapfile, FR_SNAPSHOTLOAD ) ) return; - joinpath( snappath, snapfile ); - load_snapshot( oric, filetmp ); + if(!filerequester(oric, "Load Snapshot", snappath, snapfile, FR_SNAPSHOTLOAD)) return; + joinpath(snappath, snapfile); + load_snapshot(oric, filetmp); } void softresetoric(struct machine *oric, struct osdmenuitem *mitem, int dummy) @@ -1344,13 +1410,13 @@ void softresetoric(struct machine *oric, struct osdmenuitem *mitem, int dummy) } // Reset the oric -void resetoric( struct machine *oric, struct osdmenuitem *mitem, int dummy ) +void resetoric(struct machine *oric, struct osdmenuitem *mitem, int dummy) { - switch( oric->drivetype ) + switch(oric->drivetype) { case DRV_MICRODISC: oric->romdis = SDL_TRUE; - microdisc_init( &oric->md, &oric->wddisk, oric ); + microdisc_init(&oric->md, &oric->wddisk, oric); break; case DRV_JASMIN: @@ -1361,36 +1427,36 @@ void resetoric( struct machine *oric, struct osdmenuitem *mitem, int dummy ) oric->romdis = SDL_FALSE; break; } - setromon( oric ); - m6502_reset( &oric->cpu ); - via_init( &oric->via, oric, VIA_MAIN ); - via_init( &oric->tele_via, oric, VIA_TELESTRAT ); - ay_init( &oric->ay, oric ); + setromon(oric); + m6502_reset(&oric->cpu); + via_init(&oric->via, oric, VIA_MAIN); + via_init(&oric->tele_via, oric, VIA_TELESTRAT); + ay_init(&oric->ay, oric); oric->cpu.rastercycles = oric->cyclesperraster; oric->frames = 0; - if( oric->autorewind ) tape_rewind( oric ); - setemumode( oric, NULL, EM_RUNNING ); + if(oric->autorewind) tape_rewind(oric); + setemumode(oric, NULL, EM_RUNNING); } -struct osdmenuitem *find_item_by_function(struct osdmenuitem *menu, void *function) +struct osdmenuitem *find_item_by_function(struct osdmenuitem *menu, void* function) { int i; static struct osdmenuitem dummyitem; /* So we can always return non-NULL */ - for (i=0; menu[i].name; i++) - if (menu[i].func == function) + for(i=0; menu[i].name; i++) + if(menu[i].func == function) return &menu[i]; return &dummyitem; } -struct osdmenuitem *find_item_by_function_and_arg(struct osdmenuitem *menu, void *function, int arg) +struct osdmenuitem *find_item_by_function_and_arg(struct osdmenuitem *menu, void* function, int arg) { int i; static struct osdmenuitem dummyitem; /* So we can always return non-NULL */ - for (i=0; menu[i].name; i++) - if ((menu[i].func == function) && (menu[i].arg == arg)) + for(i=0; menu[i].name; i++) + if((menu[i].func == function) && (menu[i].arg == arg)) return &menu[i]; return &dummyitem; @@ -1401,17 +1467,17 @@ struct osdmenuitem *find_item_by_key(struct osdmenuitem *menu, int sdlkey) int i; static struct osdmenuitem dummyitem; /* So we can always return non-NULL */ - for (i=0; menu[i].name; i++) - if (menu[i].sdlkey == sdlkey) + for(i=0; menu[i].name; i++) + if(menu[i].sdlkey == sdlkey) return &menu[i]; return &dummyitem; } // Turn tape noise on/off -void toggletapenoise( struct machine *oric, struct osdmenuitem *mitem, int dummy ) +void toggletapenoise(struct machine *oric, struct osdmenuitem *mitem, int dummy) { - if( oric->tapenoise ) + if(oric->tapenoise) { oric->ay.tapeout = 0; oric->tapenoise = SDL_FALSE; @@ -1424,29 +1490,29 @@ void toggletapenoise( struct machine *oric, struct osdmenuitem *mitem, int dummy } // Toggle sound on/off -void togglesound( struct machine *oric, struct osdmenuitem *mitem, int dummy ) +void togglesound(struct machine *oric, struct osdmenuitem *mitem, int dummy) { - if( ( soundon ) || (!soundavailable) ) + if((soundon) || (!soundavailable)) { soundon = SDL_FALSE; oric->ay.soundon = SDL_FALSE; mitem->name = " Sound enabled"; - if( soundavailable ) SDL_PauseAudio( 1 ); + if(soundavailable) SDL_PauseAudio(1); return; } soundon = SDL_TRUE; oric->ay.soundon = !warpspeed; mitem->name = "\x0e""Sound enabled"; - if( oric->emu_mode == EM_RUNNING ) SDL_PauseAudio( !warpspeed ); + if(oric->emu_mode == EM_RUNNING) SDL_PauseAudio(!warpspeed); } // Toggle turbotape on/off -void toggletapeturbo( struct machine *oric, struct osdmenuitem *mitem, int dummy ) +void toggletapeturbo(struct machine *oric, struct osdmenuitem *mitem, int dummy) { oric->tapeturbo_forceoff = SDL_FALSE; - if( oric->tapeturbo ) + if(oric->tapeturbo) { oric->tapeturbo = SDL_FALSE; mitem->name = " Turbo tape"; @@ -1458,9 +1524,9 @@ void toggletapeturbo( struct machine *oric, struct osdmenuitem *mitem, int dummy } // Toggle VSync Hack -void togglevsynchack( struct machine *oric, struct osdmenuitem *mitem, int dummy ) +void togglevsynchack(struct machine *oric, struct osdmenuitem *mitem, int dummy) { - if( oric->vsynchack ) + if(oric->vsynchack) { oric->vsynchack = SDL_FALSE; mitem->name = " VSync hack"; @@ -1472,9 +1538,9 @@ void togglevsynchack( struct machine *oric, struct osdmenuitem *mitem, int dummy } // Toggle lightpen -void togglelightpen( struct machine *oric, struct osdmenuitem *mitem, int dummy ) +void togglelightpen(struct machine *oric, struct osdmenuitem *mitem, int dummy) { - if( oric->lightpen ) + if(oric->lightpen) { oric->lightpen = SDL_FALSE; oric->cpu.read = oric->read_not_lightpen; @@ -1488,9 +1554,9 @@ void togglelightpen( struct machine *oric, struct osdmenuitem *mitem, int dummy } // Toggle tele acia (Serial card) -void toggleaciabackend( struct machine *oric, struct osdmenuitem *mitem, int dummy ) +void toggleaciabackend(struct machine *oric, struct osdmenuitem *mitem, int dummy) { - if( oric->aciabackend ) + if(oric->aciabackend) { oric->aciabackend = ACIA_TYPE_NONE; mitem->name = aciabackends[oric->aciabackend]; @@ -1501,31 +1567,57 @@ void toggleaciabackend( struct machine *oric, struct osdmenuitem *mitem, int dum mitem->name = aciabackendlabel; } - acia_init( &oric->tele_acia, oric ); + acia_init(&oric->tele_acia, oric); } // Toggle ch376 on/off void togglech376(struct machine *oric, struct osdmenuitem *mitem, int dummy) { - if (oric->ch376_activated) - { - oric->ch376_activated = SDL_FALSE; - mitem->name = " CH376 (Telestrat)"; - return; - } + if(oric->ch376_activated) + { + oric->ch376_activated = SDL_FALSE; + mitem->name = " CH376 (Telestrat)"; + return; + } + + oric->ch376_activated = SDL_TRUE; + mitem->name = "\x0e""CH376 (Telestrat)"; + oric->ch376 = ch376_oric_init(); + if(oric->ch376 != NULL) + ch376_oric_config(oric->ch376); +} + +// Toggle twilighte on/off +void toggletwilighte(struct machine *oric, struct osdmenuitem *mitem, int dummy) +{ + + if(oric->twilighteboard_activated) + { + oric->twilighteboard_activated = SDL_FALSE; + mitem->name = " Twilighte board"; + return; + } + + oric->twilighteboard_activated = SDL_TRUE; + mitem->name = "\x0e""Twilighte board"; + oric->twilighte = twilighte_oric_init(); + if(oric->twilighte == NULL) + { + oric->twilighteboard_activated = SDL_FALSE; // Impossible to create struct, we did not activate twilighteboard + } + else + { + oric->ch376_activated = SDL_TRUE; + } + - oric->ch376_activated = SDL_TRUE; - mitem->name = "\x0e""CH376 (Telestrat)"; - oric->ch376 = ch376_oric_init(); - if (oric->ch376 != NULL) - ch376_oric_config(oric->ch376); } // Toggle symbols autoload -void togglesymbolsauto( struct machine *oric, struct osdmenuitem *mitem, int dummy ) +void togglesymbolsauto(struct machine *oric, struct osdmenuitem *mitem, int dummy) { - if( oric->symbolsautoload ) + if(oric->symbolsautoload) { oric->symbolsautoload = SDL_FALSE; mitem->name = " Autoload symbols file"; @@ -1537,9 +1629,9 @@ void togglesymbolsauto( struct machine *oric, struct osdmenuitem *mitem, int dum } // Toggle case sensitive symbols -void togglecasesyms( struct machine *oric, struct osdmenuitem *mitem, int dummy ) +void togglecasesyms(struct machine *oric, struct osdmenuitem *mitem, int dummy) { - if( oric->symbolscase ) + if(oric->symbolscase) { oric->symbolscase = SDL_FALSE; mitem->name = " Case-sensitive symbols"; @@ -1551,9 +1643,9 @@ void togglecasesyms( struct machine *oric, struct osdmenuitem *mitem, int dummy } // Toggle autorewind on/off -void toggleautowind( struct machine *oric, struct osdmenuitem *mitem, int dummy ) +void toggleautowind(struct machine *oric, struct osdmenuitem *mitem, int dummy) { - if( oric->autorewind ) + if(oric->autorewind) { oric->autorewind = SDL_FALSE; mitem->name = " Autorewind tape"; @@ -1565,9 +1657,9 @@ void toggleautowind( struct machine *oric, struct osdmenuitem *mitem, int dummy } // Toggle autoinsert on/off -void toggleautoinsrt( struct machine *oric, struct osdmenuitem *mitem, int dummy ) +void toggleautoinsrt(struct machine *oric, struct osdmenuitem *mitem, int dummy) { - if( oric->autoinsert ) + if(oric->autoinsert) { oric->autoinsert = SDL_FALSE; mitem->name = " Autoinsert tape"; @@ -1579,11 +1671,11 @@ void toggleautoinsrt( struct machine *oric, struct osdmenuitem *mitem, int dummy } // Toggle fullscreen on/off -void togglefullscreen( struct machine *oric, struct osdmenuitem *mitem, int dummy ) +void togglefullscreen(struct machine *oric, struct osdmenuitem *mitem, int dummy) { - if( !oric->render_togglefullscreen( oric ) ) return; // Failed :-( + if(!oric->render_togglefullscreen(oric)) return; // Failed :-( - if( fullscreen ) + if(fullscreen) { find_item_by_function(vdopitems, togglefullscreen)->name = "\x0e""Fullscreen"; find_item_by_function(glopitems, togglefullscreen)->name = "\x0e""Fullscreen"; @@ -1595,9 +1687,9 @@ void togglefullscreen( struct machine *oric, struct osdmenuitem *mitem, int dumm } // Toggle 50Hz/60Hz aspect ratio -void togglearatio( struct machine *oric, struct osdmenuitem *mitem, int dummy ) +void togglearatio(struct machine *oric, struct osdmenuitem *mitem, int dummy) { - if( oric->aratio ) + if(oric->aratio) { oric->aratio = SDL_FALSE; mitem->name = " 50Hz/60Hz aspect ratio"; @@ -1609,9 +1701,9 @@ void togglearatio( struct machine *oric, struct osdmenuitem *mitem, int dummy ) } // Toggle hstretch on/off -void togglehstretch( struct machine *oric, struct osdmenuitem *mitem, int dummy ) +void togglehstretch(struct machine *oric, struct osdmenuitem *mitem, int dummy) { - if( oric->hstretch ) + if(oric->hstretch) { oric->hstretch = SDL_FALSE; mitem->name = " Horizontal stretch"; @@ -1623,9 +1715,9 @@ void togglehstretch( struct machine *oric, struct osdmenuitem *mitem, int dummy } // Toggle PAL ghosting on/off -void togglepalghost( struct machine *oric, struct osdmenuitem *mitem, int dummy ) +void togglepalghost(struct machine *oric, struct osdmenuitem *mitem, int dummy) { - if( oric->palghost ) + if(oric->palghost) { oric->palghost = SDL_FALSE; mitem->name = " PAL ghosting"; @@ -1637,9 +1729,9 @@ void togglepalghost( struct machine *oric, struct osdmenuitem *mitem, int dummy } // Toggle scanlines on/off -void togglescanlines( struct machine *oric, struct osdmenuitem *mitem, int dummy ) +void togglescanlines(struct machine *oric, struct osdmenuitem *mitem, int dummy) { - if( oric->scanlines ) + if(oric->scanlines) { oric->scanlines = SDL_FALSE; find_item_by_function(vdopitems, togglescanlines)->name = " Scanlines"; @@ -1652,21 +1744,23 @@ void togglescanlines( struct machine *oric, struct osdmenuitem *mitem, int dummy find_item_by_function(glopitems, togglescanlines)->name = "\x0e""Scanlines"; } -void setoverclock( struct machine *oric, struct osdmenuitem *mitem, int value ) +void setoverclock(struct machine *oric, struct osdmenuitem *mitem, int value) { int i; /* Don't want to just modify name[0], since */ /* string constants are supposed to be constant.. */ - char *setnames[] = { "\x0e"" 1MHz (None)", "\x0e"" 2MHz", "\x0e"" 4MHz", "\x0e"" 8MHz", - "\x0e""16MHz", "\x0e""32MHz", "\x0e""64MHz" }; - char *unsetnames[] = { " 1MHz (None)", " 2MHz", " 4MHz", " 8MHz", - " 16MHz", " 32MHz", " 64MHz" }; + char* setnames[] = { "\x0e"" 1MHz (None)", "\x0e"" 2MHz", "\x0e"" 4MHz", "\x0e"" 8MHz", + "\x0e""16MHz", "\x0e""32MHz", "\x0e""64MHz" + }; + char* unsetnames[] = { " 1MHz (None)", " 2MHz", " 4MHz", " 8MHz", + " 16MHz", " 32MHz", " 64MHz" + }; oric->overclockmult = 1<overclockshift = value; - for( i=0; i<7; i++ ) + for(i=0; i<7; i++) { if(i == value) ovopitems[i].name = setnames[i]; @@ -1676,63 +1770,63 @@ void setoverclock( struct machine *oric, struct osdmenuitem *mitem, int value ) } // Go to internet site -void gotosite( struct machine *oric, struct osdmenuitem *mitem, int dummy ) +void gotosite(struct machine *oric, struct osdmenuitem *mitem, int dummy) { -/* TODO: mode those to their own gui_*.c */ + /* TODO: mode those to their own gui_*.c */ #if defined(__MORPHOS__) || defined(__AROS__) - struct Library *OpenURLBase = OpenLibrary( "openurl.library", 0 ); + struct Library *OpenURLBase = OpenLibrary("openurl.library", 0); static const struct TagItem URLTags[] = {{TAG_DONE, (ULONG) NULL}}; - if( OpenURLBase ) + if(OpenURLBase) { URL_OpenA(mitem->name, (struct TagItem*) URLTags); - CloseLibrary( OpenURLBase ); + CloseLibrary(OpenURLBase); } #elif defined(__amigaos4__) char tmp[256]; BPTR h; - sprintf( tmp, "URL:%s", mitem->name ); - if( ( h = IDOS->Open( tmp, MODE_OLDFILE ) ) ) IDOS->Close( h ); + sprintf(tmp, "URL:%s", mitem->name); + if((h = IDOS->Open(tmp, MODE_OLDFILE))) IDOS->Close(h); #elif defined(WIN32) || defined(__APPLE__) || defined(__BEOS__) || defined(__HAIKU__) - gui_open_url( mitem->name ); + gui_open_url(mitem->name); #else -/* default: assume XDG-compliant desktop */ + /* default: assume XDG-compliant desktop */ char tmp[256]; - sprintf( tmp, "xdg-open '%s'", mitem->name ); - system( tmp ); + sprintf(tmp, "xdg-open '%s'", mitem->name); + system(tmp); #endif } // Go to a different menu -void gotomenu( struct machine *oric, struct osdmenuitem *mitem, int menunum ) +void gotomenu(struct machine *oric, struct osdmenuitem *mitem, int menunum) { int i, w, keyw; - if( tz[TZ_MENU] ) free_textzone( oric, TZ_MENU ); + if(tz[TZ_MENU]) free_textzone(oric, TZ_MENU); cmenu = &menus[menunum]; - w = (int)strlen( cmenu->title )+8; + w = (int)strlen(cmenu->title)+8; keyw = 0; - for( i=0; cmenu->items[i].name; i++ ) + for(i=0; cmenu->items[i].name; i++) { - if( cmenu->items[i].name == OSDMENUBAR ) + if(cmenu->items[i].name == OSDMENUBAR) continue; - if( strlen( cmenu->items[i].name ) > w ) - w = (int)strlen( cmenu->items[i].name ); - if( cmenu->items[i].key ) + if(strlen(cmenu->items[i].name) > w) + w = (int)strlen(cmenu->items[i].name); + if(cmenu->items[i].key) { - if( (strlen( cmenu->items[i].key )+1) > keyw ) - keyw = (int)strlen( cmenu->items[i].key )+1; + if((strlen(cmenu->items[i].key)+1) > keyw) + keyw = (int)strlen(cmenu->items[i].key)+1; } } + w+=keyw+2; + i+=2; - w+=keyw+2; i+=2; - - if( !alloc_textzone( oric, TZ_MENU, 320-w*4, 240-i*6, w, i, cmenu->title ) ) + if(!alloc_textzone(oric, TZ_MENU, 320-w*4, 240-i*6, w, i, cmenu->title)) { cmenu = NULL; oric->emu_mode = EM_RUNNING; @@ -1742,97 +1836,98 @@ void gotomenu( struct machine *oric, struct osdmenuitem *mitem, int menunum ) drawitems(); } -void togglekeyboard( struct machine *oric, struct osdmenuitem *mitem, int dummy ) +void togglekeyboard(struct machine *oric, struct osdmenuitem *mitem, int dummy) { - if( oric->show_keyboard ) - { - oric->show_keyboard = SDL_FALSE; - mitem->name = " Show keyboard"; - oric->shut_render(oric); - oric->init_render(oric); - return; - } - - oric->show_keyboard = SDL_TRUE; - mitem->name = "\x0e""Show keyboard"; + if(oric->show_keyboard) + { + oric->show_keyboard = SDL_FALSE; + mitem->name = " Show keyboard"; oric->shut_render(oric); oric->init_render(oric); - setemumode( oric, NULL, EM_RUNNING ); + return; + } + + oric->show_keyboard = SDL_TRUE; + mitem->name = "\x0e""Show keyboard"; + oric->shut_render(oric); + oric->init_render(oric); + setemumode(oric, NULL, EM_RUNNING); } -void definemapping( struct machine *oric, struct osdmenuitem *mitem, int dummy ) +void definemapping(struct machine *oric, struct osdmenuitem *mitem, int dummy) { - if( oric->define_mapping ) - { - oric->define_mapping = SDL_FALSE; - mitem->name = " Define mapping"; - return; - } + if(oric->define_mapping) + { + oric->define_mapping = SDL_FALSE; + mitem->name = " Define mapping"; + return; + } - oric->define_mapping = SDL_TRUE; - mitem->name = "\x0e""Define mapping"; - if(!oric->show_keyboard) { - find_item_by_function(keopitems, togglekeyboard)->name = "\x0e""Show keyboard"; - oric->show_keyboard = SDL_TRUE; - oric->shut_render(oric); - oric->init_render(oric); - } - cmenu = NULL; - oric->emu_mode = EM_RUNNING; - do_popup( oric, "Click on an Oric key." ); - setemumode( oric, NULL, EM_RUNNING ); + oric->define_mapping = SDL_TRUE; + mitem->name = "\x0e""Define mapping"; + if(!oric->show_keyboard) + { + find_item_by_function(keopitems, togglekeyboard)->name = "\x0e""Show keyboard"; + oric->show_keyboard = SDL_TRUE; + oric->shut_render(oric); + oric->init_render(oric); + } + cmenu = NULL; + oric->emu_mode = EM_RUNNING; + do_popup(oric, "Click on an Oric key."); + setemumode(oric, NULL, EM_RUNNING); } -void togglestickykeys( struct machine *oric, struct osdmenuitem *mitem, int dummy ) +void togglestickykeys(struct machine *oric, struct osdmenuitem *mitem, int dummy) { - if( oric->sticky_mod_keys ) - { - oric->sticky_mod_keys = SDL_FALSE; - mitem->name = " Sticky mod keys"; - release_sticky_keys(); - return; - } + if(oric->sticky_mod_keys) + { + oric->sticky_mod_keys = SDL_FALSE; + mitem->name = " Sticky mod keys"; + release_sticky_keys(); + return; + } - oric->sticky_mod_keys = SDL_TRUE; - mitem->name = "\x0e""Sticky mod keys"; - setemumode( oric, NULL, EM_RUNNING ); + oric->sticky_mod_keys = SDL_TRUE; + mitem->name = "\x0e""Sticky mod keys"; + setemumode(oric, NULL, EM_RUNNING); } -void savemapping( struct machine *oric, struct osdmenuitem *mitem, int dummy ) +void savemapping(struct machine *oric, struct osdmenuitem *mitem, int dummy) { - if( !filerequester( oric, "Save Keyboard Mapping", mappingpath, mappingfile, FR_KEYMAPPINGSAVE ) ) return; - joinpath( mappingpath, mappingfile ); - save_keyboard_mapping(oric, filetmp); - setemumode( oric, NULL, EM_RUNNING ); + if(!filerequester(oric, "Save Keyboard Mapping", mappingpath, mappingfile, FR_KEYMAPPINGSAVE)) return; + joinpath(mappingpath, mappingfile); + save_keyboard_mapping(oric, filetmp); + setemumode(oric, NULL, EM_RUNNING); } -void loadmapping( struct machine *oric, struct osdmenuitem *mitem, int dummy ) +void loadmapping(struct machine *oric, struct osdmenuitem *mitem, int dummy) { - if( !filerequester( oric, "Load Keyboard Mapping", mappingpath, mappingfile, FR_KEYMAPPINGLOAD ) ) return; - joinpath( mappingpath, mappingfile ); - load_keyboard_mapping(oric, filetmp); - setemumode( oric, NULL, EM_RUNNING ); + if(!filerequester(oric, "Load Keyboard Mapping", mappingpath, mappingfile, FR_KEYMAPPINGLOAD)) return; + joinpath(mappingpath, mappingfile); + load_keyboard_mapping(oric, filetmp); + setemumode(oric, NULL, EM_RUNNING); } -void resetmapping( struct machine *oric, struct osdmenuitem *mitem, int dummy ) +void resetmapping(struct machine *oric, struct osdmenuitem *mitem, int dummy) { - reset_keyboard_mapping(&(oric->keyboard_mapping)); - setemumode( oric, NULL, EM_RUNNING ); + reset_keyboard_mapping(&(oric->keyboard_mapping)); + setemumode(oric, NULL, EM_RUNNING); } #ifdef __CBCOPY__ -void clipbd_copy_gui( struct machine *oric, struct osdmenuitem *mitem, int dummy ) +void clipbd_copy_gui(struct machine *oric, struct osdmenuitem *mitem, int dummy) { - clipboard_copy(oric); - setemumode( oric, NULL, EM_RUNNING ); + clipboard_copy(oric); + setemumode(oric, NULL, EM_RUNNING); } #endif #ifdef __CBPASTE__ -void clipbd_paste_gui( struct machine *oric, struct osdmenuitem *mitem, int dummy ) +void clipbd_paste_gui(struct machine *oric, struct osdmenuitem *mitem, int dummy) { - clipboard_paste(oric); - setemumode( oric, NULL, EM_RUNNING ); + clipboard_paste(oric); + setemumode(oric, NULL, EM_RUNNING); } #endif @@ -1840,18 +1935,16 @@ void clipbd_paste_gui( struct machine *oric, struct osdmenuitem *mitem, int dumm /************************* End of menu callable funcs *******************************/ // This is the event handler for when you are in the menus -SDL_bool menu_event( SDL_Event *ev, struct machine *oric, SDL_bool *needrender ) +SDL_bool menu_event(SDL_Event *ev, struct machine *oric, SDL_bool *needrender) { SDL_bool done = SDL_FALSE; int i, x, y; - // Wot, no menu?! - if( ( !cmenu ) || ( !tz[TZ_MENU] ) ) + if((!cmenu) || (!tz[TZ_MENU])) return done; - x = -1; y = -1; - switch( ev->type ) + switch(ev->type) { case SDL_MOUSEMOTION: x = (ev->motion.x - tz[TZ_MENU]->x)/8; @@ -1859,7 +1952,7 @@ SDL_bool menu_event( SDL_Event *ev, struct machine *oric, SDL_bool *needrender ) break; case SDL_MOUSEBUTTONDOWN: - if( ev->button.button == SDL_BUTTON_LEFT ) + if(ev->button.button == SDL_BUTTON_LEFT) { x = (ev->button.x - tz[TZ_MENU]->x)/8; y = (ev->button.y - tz[TZ_MENU]->y)/12-1; @@ -1867,11 +1960,12 @@ SDL_bool menu_event( SDL_Event *ev, struct machine *oric, SDL_bool *needrender ) break; } - switch( ev->type ) + switch(ev->type) { case SDL_COMPAT_ACTIVEEVENT: - if(SDL_COMPAT_IsAppFocused(ev)) { - *needrender = SDL_TRUE; + if(SDL_COMPAT_IsAppFocused(ev)) + { + *needrender = SDL_TRUE; } break; @@ -1880,56 +1974,56 @@ SDL_bool menu_event( SDL_Event *ev, struct machine *oric, SDL_bool *needrender ) x = (ev->motion.x - tz[TZ_MENU]->x)/8; y = (ev->motion.y - tz[TZ_MENU]->y)/12-1; - if( ( x < 0 ) || ( y < 0 ) || - ( x >= tz[TZ_MENU]->w ) ) + if((x < 0) || (y < 0) || + (x >= tz[TZ_MENU]->w)) break; - for( i=0; iitems[i].name == NULL ) + for(i=0; iitems[i].name == NULL) break; - if( ( i != y ) || ( cmenu->items[y].name == OSDMENUBAR ) || ( cmenu->items[y].func == NULL ) ) + if((i != y) || (cmenu->items[y].name == OSDMENUBAR) || (cmenu->items[y].func == NULL)) break; cmenu->citem = y; - if( ( ev->type == SDL_MOUSEBUTTONDOWN ) && - ( (ev->button.button==SDL_BUTTON_LEFT) || - (ev->button.button==SDL_BUTTON_RIGHT) ) ) - cmenu->items[cmenu->citem].func( oric, &cmenu->items[cmenu->citem], cmenu->items[cmenu->citem].arg ); + if((ev->type == SDL_MOUSEBUTTONDOWN) && + ((ev->button.button==SDL_BUTTON_LEFT) || + (ev->button.button==SDL_BUTTON_RIGHT))) + cmenu->items[cmenu->citem].func(oric, &cmenu->items[cmenu->citem], cmenu->items[cmenu->citem].arg); drawitems(); *needrender = SDL_TRUE; break; case SDL_KEYDOWN: - switch( ev->key.keysym.sym ) + switch(ev->key.keysym.sym) { case SDLK_UP: // Find the next selectable item above this one i = cmenu->citem-1; - while( ( cmenu->items[i].name == OSDMENUBAR ) || - ( cmenu->items[i].func == NULL ) ) + while((cmenu->items[i].name == OSDMENUBAR) || + (cmenu->items[i].func == NULL)) { - if( i < 0 ) break; + if(i < 0) break; i--; } // Hit the top? - if( ( i < 0 ) || ( cmenu->items[i].name == OSDMENUBAR ) ) + if((i < 0) || (cmenu->items[i].name == OSDMENUBAR)) { // Start the search again from the last item - for( i=0; cmenu->items[i].name; i++ ) ; + for(i=0; cmenu->items[i].name; i++) ; i--; // Find the first selectable item from here - while( ( cmenu->items[i].name == OSDMENUBAR ) || - ( cmenu->items[i].func == NULL ) ) + while((cmenu->items[i].name == OSDMENUBAR) || + (cmenu->items[i].func == NULL)) { - if( i < 0 ) break; + if(i < 0) break; i--; } - if( ( i < 0 ) || ( cmenu->items[i].name == OSDMENUBAR ) ) break; + if((i < 0) || (cmenu->items[i].name == OSDMENUBAR)) break; } cmenu->citem = i; drawitems(); @@ -1938,25 +2032,25 @@ SDL_bool menu_event( SDL_Event *ev, struct machine *oric, SDL_bool *needrender ) case SDLK_DOWN: i = cmenu->citem+1; - while( ( cmenu->items[i].name == OSDMENUBAR ) || - ( cmenu->items[i].func == NULL ) ) + while((cmenu->items[i].name == OSDMENUBAR) || + (cmenu->items[i].func == NULL)) { - if( cmenu->items[i].name == NULL ) break; + if(cmenu->items[i].name == NULL) break; i++; } - if( ( cmenu->items[i].name == NULL ) || ( cmenu->items[i].name == OSDMENUBAR ) ) + if((cmenu->items[i].name == NULL) || (cmenu->items[i].name == OSDMENUBAR)) { i=0; - while( ( cmenu->items[i].name == OSDMENUBAR ) || - ( cmenu->items[i].func == NULL ) ) + while((cmenu->items[i].name == OSDMENUBAR) || + (cmenu->items[i].func == NULL)) { - if( cmenu->items[i].name == NULL ) break; + if(cmenu->items[i].name == NULL) break; i++; } - if( ( cmenu->items[i].name == NULL ) || ( cmenu->items[i].name == OSDMENUBAR ) ) + if((cmenu->items[i].name == NULL) || (cmenu->items[i].name == OSDMENUBAR)) break; } @@ -1971,33 +2065,39 @@ SDL_bool menu_event( SDL_Event *ev, struct machine *oric, SDL_bool *needrender ) break; case SDL_KEYUP: - switch( ev->key.keysym.sym ) + switch(ev->key.keysym.sym) { case SDLK_RETURN: case SDLK_KP_ENTER: - if( !cmenu->items[cmenu->citem].func ) break; - cmenu->items[cmenu->citem].func( oric, &cmenu->items[cmenu->citem], cmenu->items[cmenu->citem].arg ); + if(!cmenu->items[cmenu->citem].func) break; + cmenu->items[cmenu->citem].func(oric, &cmenu->items[cmenu->citem], cmenu->items[cmenu->citem].arg); drawitems(); *needrender = SDL_TRUE; break; case SDLK_ESCAPE: - setemumode( oric, NULL, EM_RUNNING ); + setemumode(oric, NULL, EM_RUNNING); +#ifdef WWW + if(oric->ay.soundon) + { + SDL_PauseAudio(0); + } +#endif *needrender = SDL_TRUE; break; default: - for( i=0; cmenu->items[i].name; i++ ) + for(i=0; cmenu->items[i].name; i++) { - if( ( cmenu->items[i].sdlkey ) && - ( cmenu->items[i].sdlkey == ev->key.keysym.sym ) && - ( cmenu->items[i].func ) ) + if((cmenu->items[i].sdlkey) && + (cmenu->items[i].sdlkey == ev->key.keysym.sym) && + (cmenu->items[i].func)) break; } - if( !cmenu->items[i].name ) break; + if(!cmenu->items[i].name) break; - cmenu->items[i].func( oric, &cmenu->items[i], cmenu->items[i].arg ); + cmenu->items[i].func(oric, &cmenu->items[i], cmenu->items[i].arg); drawitems(); *needrender = SDL_TRUE; break; @@ -2005,17 +2105,17 @@ SDL_bool menu_event( SDL_Event *ev, struct machine *oric, SDL_bool *needrender ) break; } - if (*needrender) ula_set_dirty(oric); + if(*needrender) ula_set_dirty(oric); return done; } -void set_render_mode( struct machine *oric, int whichrendermode ) +void set_render_mode(struct machine *oric, int whichrendermode) { oric->rendermode = whichrendermode; - switch( whichrendermode ) + switch(whichrendermode) { case RENDERMODE_SW: - if (oric->sw_depth == 8) + if(oric->sw_depth == 8) { oric->render_begin = render_begin_sw8; oric->render_end = render_end_sw8; @@ -2111,107 +2211,111 @@ void set_render_mode( struct machine *oric, int whichrendermode ) } } -void swap_render_mode( struct machine *oric, struct osdmenuitem *mitem, int newrendermode ) +void swap_render_mode(struct machine *oric, struct osdmenuitem *mitem, int newrendermode) { - if( oric->rendermode == newrendermode ) return; + if(oric->rendermode == newrendermode) return; - shut_gui( oric ); - shut_joy( oric ); - SDL_COMPAT_Quit(); + shut_gui(oric); + shut_joy(oric); + SDL_COMPAT_Quit(SDL_FALSE); need_sdl_quit = SDL_FALSE; // Go SDL! - if( SDL_Init( SDL_INIT_VIDEO | SDL_INIT_AUDIO ) < 0 ) + if(SDL_COMPAT_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0) { - error_printf( "SDL init failed\n" ); oric->emu_mode = EM_PLEASEQUIT; return; } need_sdl_quit = SDL_TRUE; -#ifndef __APPLE__ - SDL_COMPAT_WM_SetIcon( SDL_LoadBMP( IMAGEPREFIX"winicon.bmp" ), NULL ); -#endif - - if( !init_joy( oric ) ) + if(!init_gui(oric, newrendermode)) { oric->emu_mode = EM_PLEASEQUIT; return; } - if( !init_gui( oric, newrendermode ) ) + if(!ay_init(&oric->ay, oric)) { oric->emu_mode = EM_PLEASEQUIT; return; } - if( !ay_init( &oric->ay, oric ) ) + if(!init_joy(oric)) { oric->emu_mode = EM_PLEASEQUIT; return; } - if( !init_filerequester( oric ) ) + if(!init_filerequester(oric)) { oric->emu_mode = EM_PLEASEQUIT; return; } - if( !init_msgbox( oric ) ) + if(!init_msgbox(oric)) { oric->emu_mode = EM_PLEASEQUIT; return; } - joy_setup( oric ); - mon_warminit( oric ); + joy_setup(oric); +#ifdef WWW_MONITOR + mon_warminit(oric); +#endif - setemumode( oric, NULL, EM_RUNNING ); + setemumode(oric, NULL, EM_RUNNING); } - // Set things to default that can't fail -void preinit_gui( struct machine *oric ) +void preinit_gui(struct machine *oric) { int i; - for( i=0; idrivetype) + switch(oric->drivetype) { case DRV_JASMIN: case DRV_MICRODISC: + case DRV_BD500: find_item_by_key(mainitems, SDLK_0)->func = insertdisk; find_item_by_key(mainitems, SDLK_1)->func = insertdisk; find_item_by_key(mainitems, SDLK_2)->func = insertdisk; @@ -2227,42 +2331,42 @@ void setmenutoggles( struct machine *oric ) break; } - if( soundavailable && soundon ) + if(soundavailable && soundon) find_item_by_function(auopitems, togglesound)->name = "\x0e""Sound enabled"; else find_item_by_function(auopitems, togglesound)->name = " Sound enabled"; - if( oric->tapenoise ) + if(oric->tapenoise) find_item_by_function(auopitems, toggletapenoise)->name = "\x0e""Tape noise"; else find_item_by_function(auopitems, toggletapenoise)->name = " Tape noise"; - if( oric->tapeturbo ) + if(oric->tapeturbo) find_item_by_function(hwopitems, toggletapeturbo)->name = "\x0e""Turbo tape"; else find_item_by_function(hwopitems, toggletapeturbo)->name = " Turbo tape"; - if( oric->autoinsert ) + if(oric->autoinsert) find_item_by_function(hwopitems, toggleautoinsrt)->name = "\x0e""Autoinsert tape"; else find_item_by_function(hwopitems, toggleautoinsrt)->name = " Autoinsert tape"; - if( oric->autorewind ) + if(oric->autorewind) find_item_by_function(hwopitems, toggleautowind)->name = "\x0e""Autorewind tape"; else find_item_by_function(hwopitems, toggleautowind)->name = " Autorewind tape"; - if( oric->vsynchack ) + if(oric->vsynchack) find_item_by_function(hwopitems, togglevsynchack)->name = "\x0e""VSync hack"; else find_item_by_function(hwopitems, togglevsynchack)->name = " VSync hack"; - if( oric->lightpen ) + if(oric->lightpen) find_item_by_function(hwopitems, togglelightpen)->name = "\x0e""Lightpen"; else find_item_by_function(hwopitems, togglelightpen)->name = " Lightpen"; - if( oric->aciabackend ) + if(oric->aciabackend) { strcpy(aciabackendlabel, aciabackends[oric->aciabackend]); sprintf(aciabackendlabel+18, "%.4X", oric->aciaoffset); @@ -2271,101 +2375,110 @@ void setmenutoggles( struct machine *oric ) else find_item_by_function(hwopitems, toggleaciabackend)->name = aciabackends[oric->aciabackend]; - if( oric->symbolsautoload ) + if(oric->symbolsautoload) find_item_by_function(dbopitems, togglesymbolsauto)->name = "\x0e""Autoload symbols file"; else find_item_by_function(dbopitems, togglesymbolsauto)->name = " Autoload symbols file"; - if( oric->symbolscase ) + if(oric->symbolscase) find_item_by_function(dbopitems, togglecasesyms)->name = "\x0e""Case-sensitive symbols"; else find_item_by_function(dbopitems, togglecasesyms)->name = " Case-sensitive symbols"; - if( fullscreen ) + if(fullscreen) { find_item_by_function(vdopitems, togglefullscreen)->name = "\x0e""Fullscreen"; find_item_by_function(glopitems, togglefullscreen)->name = "\x0e""Fullscreen"; - } else { + } + else + { find_item_by_function(vdopitems, togglefullscreen)->name = " Fullscreen"; find_item_by_function(glopitems, togglefullscreen)->name = " Fullscreen"; } - if( oric->aratio ) + if(oric->aratio) find_item_by_function(glopitems, togglearatio)->name = "\x0e""50Hz/60Hz aspect ratio"; else find_item_by_function(glopitems, togglearatio)->name = " 50Hz/60Hz aspect ratio"; - if( oric->hstretch ) + if(oric->hstretch) find_item_by_function(glopitems, togglehstretch)->name = "\x0e""Horizontal stretch"; else find_item_by_function(glopitems, togglehstretch)->name = " Horizontal stretch"; - if( oric->scanlines ) + if(oric->scanlines) { find_item_by_function(vdopitems, togglescanlines)->name = "\x0e""Scanlines"; find_item_by_function(glopitems, togglescanlines)->name = "\x0e""Scanlines"; - } else { + } + else + { find_item_by_function(vdopitems, togglescanlines)->name = " Scanlines"; find_item_by_function(glopitems, togglescanlines)->name = " Scanlines"; } - if( oric->palghost ) + if(oric->palghost) find_item_by_function(glopitems, togglepalghost)->name = "\x0e""PAL ghosting"; else find_item_by_function(glopitems, togglepalghost)->name = " PAL ghosting"; - find_item_by_function_and_arg(hwopitems, swapmach, (0xffff<<16)|MACH_ORIC1 )->name = oric->type==MACH_ORIC1 ? "\x0e""Oric-1" : " Oric-1"; - find_item_by_function_and_arg(hwopitems, swapmach, (0xffff<<16)|MACH_ORIC1_16K )->name = oric->type==MACH_ORIC1_16K ? "\x0e""Oric-1 16K" : " Oric-1 16K"; - find_item_by_function_and_arg(hwopitems, swapmach, (0xffff<<16)|MACH_ATMOS )->name = oric->type==MACH_ATMOS ? "\x0e""Atmos" : " Atmos"; + find_item_by_function_and_arg(hwopitems, swapmach, (0xffff<<16)|MACH_ORIC1)->name = oric->type==MACH_ORIC1 ? "\x0e""Oric-1" : " Oric-1"; + find_item_by_function_and_arg(hwopitems, swapmach, (0xffff<<16)|MACH_ORIC1_16K)->name = oric->type==MACH_ORIC1_16K ? "\x0e""Oric-1 16K" : " Oric-1 16K"; + find_item_by_function_and_arg(hwopitems, swapmach, (0xffff<<16)|MACH_ATMOS)->name = oric->type==MACH_ATMOS ? "\x0e""Atmos" : " Atmos"; find_item_by_function_and_arg(hwopitems, swapmach, (DRV_NONE<<16)|MACH_TELESTRAT)->name = oric->type==MACH_TELESTRAT ? "\x0e""Telestrat" : " Telestrat"; - find_item_by_function_and_arg(hwopitems, swapmach, (0xffff<<16)|MACH_PRAVETZ )->name = oric->type==MACH_PRAVETZ ? "\x0e""Pravetz 8D" : " Pravetz 8D"; + find_item_by_function_and_arg(hwopitems, swapmach, (0xffff<<16)|MACH_PRAVETZ)->name = oric->type==MACH_PRAVETZ ? "\x0e""Pravetz 8D" : " Pravetz 8D"; find_item_by_key(hwopitems, 'm')->func = microdiscrom_valid ? setdrivetype : NULL; find_item_by_key(hwopitems, 'j')->func = jasminrom_valid ? setdrivetype : NULL; find_item_by_key(hwopitems, 'p')->func = pravetzrom_valid ? setdrivetype : NULL; - find_item_by_key(hwopitems, 'x')->name = oric->drivetype==DRV_NONE ? "\x0e""No disk" : " No disk"; - find_item_by_key(hwopitems, 'm')->name = oric->drivetype==DRV_MICRODISC ? "\x0e""Microdisc" : " Microdisc"; - find_item_by_key(hwopitems, 'j')->name = oric->drivetype==DRV_JASMIN ? "\x0e""Jasmin" : " Jasmin"; - find_item_by_key(hwopitems, 'p')->name = oric->drivetype==DRV_PRAVETZ ? "\x0e""Pravetz 8D disk": " Pravetz 8D disk"; + find_item_by_key(hwopitems, 'x')->name = oric->drivetype==DRV_NONE ? "\x0e""No disk" : " No disk"; + find_item_by_key(hwopitems, 'm')->name = oric->drivetype==DRV_MICRODISC ? "\x0e""Microdisc" : " Microdisc"; + find_item_by_key(hwopitems, 'b')->name = oric->drivetype==DRV_BD500 ? "\x0e""BD500" : " BD500"; + find_item_by_key(hwopitems, 'j')->name = oric->drivetype==DRV_JASMIN ? "\x0e""Jasmin" : " Jasmin"; + find_item_by_key(hwopitems, 'p')->name = oric->drivetype==DRV_PRAVETZ ? "\x0e""Pravetz 8D disk" : " Pravetz 8D disk"; if(oric->show_keyboard) - find_item_by_function(keopitems, togglekeyboard)->name = "\x0e""Show keyboard"; + find_item_by_function(keopitems, togglekeyboard)->name = "\x0e""Show keyboard"; else - find_item_by_function(keopitems, togglekeyboard)->name = " Show keyboard"; + find_item_by_function(keopitems, togglekeyboard)->name = " Show keyboard"; if(oric->show_keyboard) - find_item_by_function(keopitems, togglestickykeys)->name = "\x0e""Sticky mod keys"; + find_item_by_function(keopitems, togglestickykeys)->name = "\x0e""Sticky mod keys"; else - find_item_by_function(keopitems, togglestickykeys)->name = " Sticky mod keys"; + find_item_by_function(keopitems, togglestickykeys)->name = " Sticky mod keys"; + + g_menu_scheme = oric->disable_menuscheme? 5 : oric->type; find_item_by_function(hwopitems, togglech376)->name = oric->ch376_activated ? "\x0e""CH376 (Telestrat)" : " CH376 (Telestrat) "; + find_item_by_function(hwopitems, toggletwilighte)->name = oric->twilighteboard_activated ? "\x0e""Twilighte board" : " Twilighte board"; } // Initialise the GUI -SDL_bool init_gui( struct machine *oric, Sint32 rendermode ) +SDL_bool init_gui(struct machine *oric, Sint32 rendermode) { int i; SDL_AudioSpec wanted; - for( i=0; iinit_render( oric ) ) return SDL_FALSE; + set_render_mode(oric, rendermode); + if(!oric->init_render(oric)) return SDL_FALSE; // Allocate all text zones - if( !alloc_textzone( oric, TZ_MONITOR, 0, 228, 50, 21, "Monitor" ) ) return SDL_FALSE; - if( !alloc_textzone( oric, TZ_DEBUG, 0, 228, 50, 21, "Debug console" ) ) return SDL_FALSE; - if( !alloc_textzone( oric, TZ_MEMWATCH, 0, 228, 50, 21, "Memory watch" ) ) return SDL_FALSE; - if( !alloc_textzone( oric, TZ_REGS, 240, 0, 50, 19, "6502 Status" ) ) return SDL_FALSE; - if( !alloc_textzone( oric, TZ_VIA, 400, 228, 30, 21, "VIA Status" ) ) return SDL_FALSE; - if( !alloc_textzone( oric, TZ_VIA2, 400, 228, 30, 21, "Telestrat VIA Status" ) ) return SDL_FALSE; - if( !alloc_textzone( oric, TZ_AY, 400, 228, 30, 21, "AY Status" ) ) return SDL_FALSE; - if( !alloc_textzone( oric, TZ_DISK, 400, 228, 30, 21, "Disk Status" ) ) return SDL_FALSE; + if(!alloc_textzone(oric, TZ_MONITOR, 0, 228, 50, 21, "Monitor")) return SDL_FALSE; + if(!alloc_textzone(oric, TZ_DEBUG, 0, 228, 50, 21, "Debug console")) return SDL_FALSE; + if(!alloc_textzone(oric, TZ_MEMWATCH, 0, 228, 50, 21, "Memory watch")) return SDL_FALSE; + if(!alloc_textzone(oric, TZ_REGS, 240, 0, 50, 19, "6502 Status")) return SDL_FALSE; + if(!alloc_textzone(oric, TZ_VIA, 400, 228, 30, 21, "VIA Status")) return SDL_FALSE; + if(!alloc_textzone(oric, TZ_VIA2, 400, 228, 30, 21, "Telestrat VIA Status")) return SDL_FALSE; + if(!alloc_textzone(oric, TZ_AY, 400, 228, 30, 21, "AY Status")) return SDL_FALSE; + if(!alloc_textzone(oric, TZ_DISK, 400, 228, 30, 21, "Disk Status")) return SDL_FALSE; + if(!alloc_textzone(oric, TZ_TWIL, 400, 228, 30, 21, "Twilighte Status")) return SDL_FALSE; // Set up SDL audio wanted.freq = AUDIO_FREQ; @@ -2378,7 +2491,7 @@ SDL_bool init_gui( struct machine *oric, Sint32 rendermode ) soundavailable = SDL_FALSE; soundon = SDL_FALSE; - if( SDL_OpenAudio( &wanted, &obtained ) >= 0 ) + if(SDL_OpenAudio(&wanted, &obtained) >= 0) { soundon = SDL_TRUE; soundavailable = SDL_TRUE; @@ -2386,45 +2499,45 @@ SDL_bool init_gui( struct machine *oric, Sint32 rendermode ) cyclespersample = ((CYCLESPERSECOND<shut_render( oric ); + oric->shut_render(oric); - for( i=0; ipravdiskautoboot ) + if(oric->pravdiskautoboot) { - queuekeys( "CALL800\x0d" ); + queuekeys("CALL800\x0d"); } } diff --git a/gui.h b/gui.h index da1e491e..28fceac3 100644 --- a/gui.h +++ b/gui.h @@ -38,6 +38,7 @@ enum TZ_VIA2, TZ_AY, TZ_DISK, + TZ_TWIL, TZ_MENU, TZ_MSGBOX, TZ_FILEREQ, @@ -56,8 +57,8 @@ struct textzone { int x, y, w, h; // Dimensions int px, py, cfc, cbc; // Current position and text colours - unsigned char *tx; // Text buffer - unsigned char *fc, *bc; // Colour buffers + unsigned char* tx; // Text buffer + unsigned char* fc, *bc; // Colour buffers SDL_bool modified; }; @@ -72,8 +73,8 @@ struct textzone struct osdmenuitem { - char *name; - char *key; + char* name; + char* key; int sdlkey; void (*func)(struct machine *,struct osdmenuitem *,int); int arg; @@ -82,7 +83,7 @@ struct osdmenuitem struct osdmenu { - char *title; + char* title; int citem; struct osdmenuitem *items; }; @@ -91,7 +92,7 @@ struct osdmenu struct guiimg { - char *filename; + char* filename; Uint16 w, h; Uint8 *buf; }; @@ -110,66 +111,70 @@ enum GIMG_TAPE_STOP, GIMG_TAPE_RECORD, GIMG_AVI_RECORD, +#ifndef WWW_NO_ORIC1 GIMG_ORIC1_KEYBOARD, +#endif GIMG_ATMOS_KEYBOARD, +#ifndef WWW_NO_PRAVETZ GIMG_PRAVETZ_KEYBOARD, +#endif NUM_GIMG }; #define NUM_GUI_COLS 16 -SDL_bool alloc_textzone( struct machine *oric, int i, int x, int y, int w, int h, char *title ); -void free_textzone( struct machine *oric, int i ); -SDL_bool in_textzone( struct textzone *tz, int x, int y ); - -void do_popup( struct machine *oric, char *str ); -void makebox( struct textzone *ptz, int x, int y, int w, int h, int fg, int bg ); -void tzsettitle( struct textzone *ptz, char *title ); -void tzstr( struct textzone *ptz, char *text ); -void tzputc( struct textzone *ptz, char c ); -void tzstrpos( struct textzone *ptz, int x, int y, char *text ); -void tzsetcol( struct textzone *ptz, int fc, int bc ); -void tzprintf( struct textzone *ptz, char *fmt, ... ); -void tzprintfpos( struct textzone *ptz, int x, int y, char *fmt, ... ); -void draw_textzone( struct textzone *ptz ); -void printstr( int x, int y, Uint32 fc, Uint32 bc, char *str ); -void gotosite( struct machine *oric, struct osdmenuitem *mitem, int dummy ); -void gotomenu( struct machine *oric, struct osdmenuitem *mitem, int menunum ); -SDL_bool menu_event( SDL_Event *ev, struct machine *oric, SDL_bool *needrender ); -void setmenutoggles( struct machine *oric ); -void set_render_mode( struct machine *oric, int whichrendermode ); - -void render( struct machine *oric ); -void preinit_gui( struct machine *oric ); -SDL_bool init_gui( struct machine *oric, Sint32 rendermode ); -void shut_gui( struct machine *oric ); - -void draw_statusbar( struct machine *oric ); -void draw_disks( struct machine *oric ); -void draw_avirec( struct machine *oric, SDL_bool recording ); -void draw_tape( struct machine *oric ); - -void draw_keyboard( struct machine *oric ); - - -void statusprintstr( int x, Uint32 fc, char *str ); -void joinpath( char *path, char *file ); +SDL_bool alloc_textzone(struct machine *oric, int i, int x, int y, int w, int h, char* title); +void free_textzone(struct machine *oric, int i); +SDL_bool in_textzone(struct textzone *tz, int x, int y); + +void do_popup(struct machine *oric, char* str); +void makebox(struct textzone *ptz, int x, int y, int w, int h, int fg, int bg); +void tzsettitle(struct textzone *ptz, char* title); +void tzstr(struct textzone *ptz, char* text); +void tzputc(struct textzone *ptz, char c); +void tzstrpos(struct textzone *ptz, int x, int y, char* text); +void tzsetcol(struct textzone *ptz, int fc, int bc); +void tzprintf(struct textzone *ptz, char* fmt, ...); +void tzprintfpos(struct textzone *ptz, int x, int y, char* fmt, ...); +void draw_textzone(struct textzone *ptz); +void printstr(int x, int y, Uint32 fc, Uint32 bc, char* str); +void gotosite(struct machine *oric, struct osdmenuitem *mitem, int dummy); +void gotomenu(struct machine *oric, struct osdmenuitem *mitem, int menunum); +SDL_bool menu_event(SDL_Event *ev, struct machine *oric, SDL_bool *needrender); +void setmenutoggles(struct machine *oric); +void set_render_mode(struct machine *oric, int whichrendermode); + +void render(struct machine *oric); +void preinit_gui(struct machine *oric); +SDL_bool init_gui(struct machine *oric, Sint32 rendermode); +void shut_gui(struct machine *oric); + +void draw_statusbar(struct machine *oric); +void draw_disks(struct machine *oric); +void draw_avirec(struct machine *oric, SDL_bool recording); +void draw_tape(struct machine *oric); + +void draw_keyboard(struct machine *oric); + + +void statusprintstr(int x, Uint32 fc, char* str); +void joinpath(char* path, char* file); /* implemented by OS-specific backends */ -SDL_bool init_gui_native( struct machine *oric ); -void shut_gui_native( struct machine *oric ); -void gui_open_url( const char *url ); -SDL_bool clipboard_copy( struct machine *oric ); -SDL_bool clipboard_paste( struct machine *oric ); +SDL_bool init_gui_native(struct machine *oric); +void shut_gui_native(struct machine *oric); +void gui_open_url(const char* url); +SDL_bool clipboard_copy(struct machine *oric); +SDL_bool clipboard_paste(struct machine *oric); -void setoverclock( struct machine *oric, struct osdmenuitem *mitem, int value ); -void clear_textzone( struct machine *oric, int i ); +void setoverclock(struct machine *oric, struct osdmenuitem *mitem, int value); +void clear_textzone(struct machine *oric, int i); -struct osdmenuitem *find_item_by_function(struct osdmenuitem *menu, void *function); +struct osdmenuitem *find_item_by_function(struct osdmenuitem *menu, void* function); -void togglefullscreen( struct machine *oric, struct osdmenuitem *mitem, int dummy ); +void togglefullscreen(struct machine *oric, struct osdmenuitem *mitem, int dummy); -void softresetoric( struct machine *oric, struct osdmenuitem *mitem, int dummy ); +void softresetoric(struct machine *oric, struct osdmenuitem *mitem, int dummy); -void pravdiskboot( struct machine *oric ); +void pravdiskboot(struct machine *oric); diff --git a/gui_android.c b/gui_android.c new file mode 100644 index 00000000..a2f92d18 --- /dev/null +++ b/gui_android.c @@ -0,0 +1,57 @@ +/* + ** Oricutron + ** Copyright (C) 2009-2014 Peter Gordon + ** + ** This program is free software; you can redistribute it and/or + ** modify it under the terms of the GNU General Public License + ** as published by the Free Software Foundation, version 2 + ** of the License. + ** + ** This program is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with this program; if not, write to the Free Software + ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + ** + */ + +/* + * android helper by iss + */ + + +#include "system.h" +#include "6502.h" +#include "via.h" +#include "8912.h" +#include "gui.h" +#include "disk.h" +#include "monitor.h" +#include "6551.h" +#include "machine.h" + +static SDL_bool initialized = SDL_FALSE; + +SDL_bool init_gui_native(struct machine *oric) +{ + if(!initialized) + initialized = SDL_TRUE; + + /* FIXME: ... */ + return initialized; +} + +void shut_gui_native(struct machine *oric) +{ + /* FIXME: ... */ + initialized = SDL_FALSE; +} + +void gui_open_url(const char* url) +{ + /* FIXME: ... */ + return; +} diff --git a/gui_beos.cpp b/gui_beos.cpp index 31b3cdac..1216d417 100644 --- a/gui_beos.cpp +++ b/gui_beos.cpp @@ -48,282 +48,317 @@ extern "C" { #include "machine.h" } -static rgb_color oric_colors[] = { - { 0, 0, 0, 255 }, - { 255, 0, 0, 255 }, - { 0, 255, 0, 255 }, - { 255, 255, 0, 255 }, - { 0, 0, 255, 255 }, - { 255, 0, 255, 255 }, - { 0, 255, 255, 255 }, - { 255, 255, 255, 255 } +static rgb_color oric_colors[] = +{ + { 0, 0, 0, 255 }, + { 255, 0, 0, 255 }, + { 0, 255, 0, 255 }, + { 255, 255, 0, 255 }, + { 0, 0, 255, 255 }, + { 255, 0, 255, 255 }, + { 0, 255, 255, 255 }, + { 255, 255, 255, 255 } }; extern struct osdmenu menus[]; extern struct osdmenuitem aboutitems[]; //static BPopUpMenu *sPopup; -class OSDMenuItem : public BMenuItem { -public: - OSDMenuItem(struct osdmenuitem *desc, const char *name, BMessage *message) - : BMenuItem(name, message), fItem(desc) - { - if (desc->name[0] == '\x0e') - SetMarked(true); - if (desc->key) - SetTrigger(desc->key[0]); - }; - virtual ~OSDMenuItem() {}; - struct osdmenuitem *fItem; +class OSDMenuItem : public BMenuItem +{ + public: + OSDMenuItem(struct osdmenuitem *desc, const char* name, BMessage *message) + : BMenuItem(name, message), fItem(desc) + { + if(desc->name[0] == '\x0e') + SetMarked(true); + if(desc->key) + SetTrigger(desc->key[0]); + }; + virtual ~OSDMenuItem() {}; + struct osdmenuitem *fItem; }; -static void build_native_menus( struct osdmenu *menu, BMenu *m ) +static void build_native_menus(struct osdmenu *menu, BMenu *m) { - struct osdmenuitem *item = menu->items; - - printf("menu '%s': {\n", menu->title); - for (; item->name; item++) { - BMenuItem *mi; - const char *name = item->name; - if (name == OSDMENUBAR) { - name = "------------"; - // skip separators before back since it will also be ignored - if (item[1].sdlkey == SDLK_BACKSPACE) - continue; - mi = new BSeparatorItem(); - } else if (item->func == gotomenu) { - if (item->arg == 0) - continue; - // about item is special - if (menus[item->arg].items == aboutitems) { - mi = new BMenuItem(name, new BMessage(B_ABOUT_REQUESTED)); - } else { - BMenu *subMenu = new BMenu(name); - mi = new BMenuItem(subMenu); - build_native_menus( &menus[item->arg], subMenu ); - } - } else { - if (name[0] == ' ' || name[0] == '\x0e') - name = &name[1]; - mi = new OSDMenuItem(item, name, NULL); - } - - //printf("item '%s' key '%s'\n", name, item->key); - - m->AddItem(mi); - } - printf("}\n"); + struct osdmenuitem *item = menu->items; + + printf("menu '%s': {\n", menu->title); + for(; item->name; item++) + { + BMenuItem *mi; + const char* name = item->name; + if(name == OSDMENUBAR) + { + name = "------------"; + // skip separators before back since it will also be ignored + if(item[1].sdlkey == SDLK_BACKSPACE) + continue; + mi = new BSeparatorItem(); + } + else if(item->func == gotomenu) + { + if(item->arg == 0) + continue; + // about item is special + if(menus[item->arg].items == aboutitems) + { + mi = new BMenuItem(name, new BMessage(B_ABOUT_REQUESTED)); + } + else + { + BMenu *subMenu = new BMenu(name); + mi = new BMenuItem(subMenu); + build_native_menus(&menus[item->arg], subMenu); + } + } + else + { + if(name[0] == ' ' || name[0] == '\x0e') + name = &name[1]; + mi = new OSDMenuItem(item, name, NULL); + } + + //printf("item '%s' key '%s'\n", name, item->key); + + m->AddItem(mi); + } + printf("}\n"); } #if 0 -static void run_native_about( void ) +static void run_native_about(void) { - struct osdmenuitem *item = aboutitems; - BString text; - for (; item->name; item++) { - if (item->name == OSDMENUBAR) - break; - text << item->name; - text << "\n"; - } - BAlert *alert = new BAlert("About", text.String(), "Ok"); - alert->Go(); + struct osdmenuitem *item = aboutitems; + BString text; + for(; item->name; item++) + { + if(item->name == OSDMENUBAR) + break; + text << item->name; + text << "\n"; + } + BAlert *alert = new BAlert("About", text.String(), "Ok"); + alert->Go(); } #endif -SDL_bool init_gui_native( struct machine *oric ) +SDL_bool init_gui_native(struct machine *oric) { - BMimeType tapeType("application/x-oric-tape"); - if (!tapeType.IsInstalled()) - tapeType.Install(); - BMessage exts; - if (tapeType.GetFileExtensions(&exts) != B_OK) { - exts.AddString("extensions", "tap"); - tapeType.SetShortDescription("ORIC Tape"); - tapeType.SetLongDescription("ORIC Tape Image for emulators"); - tapeType.SetPreferredApp("application/x-vnd.oricutron"); - tapeType.SetFileExtensions(&exts); - tapeType.SetSnifferRule("0.40 [0:8](\"\\026\\026\\026\\044\")"); - } - exts.MakeEmpty(); - BMimeType diskType("application/x-oric-disk"); - if (!diskType.IsInstalled()) - diskType.Install(); - if (diskType.GetFileExtensions(&exts) != B_OK) { - exts.AddString("extensions", "dsk"); - diskType.Install(); - diskType.SetShortDescription("ORIC Disk"); - diskType.SetLongDescription("ORIC Disk Image for emulators"); - diskType.SetPreferredApp("application/x-vnd.oricutron"); - diskType.SetFileExtensions(&exts); - diskType.SetSnifferRule("0.80 (\"MFM_DISK\")"); - } - //BMimeType romType("application/x-oric-rom"); - - //sPopup = new BPopUpMenu("main"); - //build_native_menus( menus, sPopup ); - //TEST - //sPopup->Go( BPoint(0, 0), false, true); - - //run_native_about(); - - return SDL_TRUE; + BMimeType tapeType("application/x-oric-tape"); + if(!tapeType.IsInstalled()) + tapeType.Install(); + BMessage exts; + if(tapeType.GetFileExtensions(&exts) != B_OK) + { + exts.AddString("extensions", "tap"); + tapeType.SetShortDescription("ORIC Tape"); + tapeType.SetLongDescription("ORIC Tape Image for emulators"); + tapeType.SetPreferredApp("application/x-vnd.oricutron"); + tapeType.SetFileExtensions(&exts); + tapeType.SetSnifferRule("0.40 [0:8](\"\\026\\026\\026\\044\")"); + } + exts.MakeEmpty(); + BMimeType diskType("application/x-oric-disk"); + if(!diskType.IsInstalled()) + diskType.Install(); + if(diskType.GetFileExtensions(&exts) != B_OK) + { + exts.AddString("extensions", "dsk"); + diskType.Install(); + diskType.SetShortDescription("ORIC Disk"); + diskType.SetLongDescription("ORIC Disk Image for emulators"); + diskType.SetPreferredApp("application/x-vnd.oricutron"); + diskType.SetFileExtensions(&exts); + diskType.SetSnifferRule("0.80 (\"MFM_DISK\")"); + } + //BMimeType romType("application/x-oric-rom"); + + //sPopup = new BPopUpMenu("main"); + //build_native_menus( menus, sPopup ); + //TEST + //sPopup->Go( BPoint(0, 0), false, true); + + //run_native_about(); + + return SDL_TRUE; } -void shut_gui_native( struct machine *oric ) +void shut_gui_native(struct machine *oric) { } -extern "C" SDL_bool clipboard_copy( struct machine *oric ); -extern "C" SDL_bool clipboard_paste( struct machine *oric ); +extern "C" SDL_bool clipboard_copy(struct machine *oric); +extern "C" SDL_bool clipboard_paste(struct machine *oric); text_run *new_run(int32 offset, int color) { - BFont font(be_fixed_font); - text_run *run = new text_run; - run->offset = offset; - run->font = font; - run->color = oric_colors[color]; - return run; + BFont font(be_fixed_font); + text_run *run = new text_run; + run->offset = offset; + run->font = font; + run->color = oric_colors[color]; + return run; } -SDL_bool clipboard_copy_text( struct machine *oric ) +SDL_bool clipboard_copy_text(struct machine *oric) { - unsigned char *vidmem = (&oric->mem[oric->vid_addr]); - int line, col; - // TEXT - BString text; - BList textruns; - - textruns.AddItem(new_run(0, 0)); - - for (line = 0; line < 28; line++) { - for (col = 0; col < 40; col++) { - unsigned char c = vidmem[line * 40 + col]; - - if (c > 127) { - c -= 128; - } - - if (c < 8) { - textruns.AddItem(new_run(text.Length(), c)); - text << ' '; - } else if (c < ' ' || c == 127) { - text << ' '; - } else if (c == 0x60) { - text << B_UTF8_COPYRIGHT; - } else - text << (char)c; - } - text << '\n'; - } - //printf("%s\n", text.String()); - - - BMessage *clip = NULL; - if (be_clipboard->Lock()) { - be_clipboard->Clear(); - clip = be_clipboard->Data(); - if (clip) { - clip->AddData("text/plain", B_MIME_TYPE, text.String(), text.Length()); - - int arraySize = sizeof(text_run_array) - + textruns.CountItems() * sizeof(text_run); - text_run_array *array = (text_run_array *)malloc(arraySize); - array->count = textruns.CountItems(); - for (int i = 0; i < array->count; i++) { - memcpy(&array->runs[i], textruns.ItemAt(i), sizeof(text_run)); - } - clip->AddData("application/x-vnd.Be-text_run_array", B_MIME_TYPE, - array, arraySize); - free(array); - - be_clipboard->Commit(); - } - be_clipboard->Unlock(); - } - - for (int i = 0; i < textruns.CountItems(); i++) { - delete (text_run *)(textruns.ItemAt(i)); - } - textruns.MakeEmpty(); - - return SDL_TRUE; + unsigned char* vidmem = (&oric->mem[oric->vid_addr]); + int line, col; + // TEXT + BString text; + BList textruns; + + textruns.AddItem(new_run(0, 0)); + + for(line = 0; line < 28; line++) + { + for(col = 0; col < 40; col++) + { + unsigned char c = vidmem[line * 40 + col]; + + if(c > 127) + { + c -= 128; + } + + if(c < 8) + { + textruns.AddItem(new_run(text.Length(), c)); + text << ' '; + } + else if(c < ' ' || c == 127) + { + text << ' '; + } + else if(c == 0x60) + { + text << B_UTF8_COPYRIGHT; + } + else + text << (char)c; + } + text << '\n'; + } + //printf("%s\n", text.String()); + + + BMessage *clip = NULL; + if(be_clipboard->Lock()) + { + be_clipboard->Clear(); + clip = be_clipboard->Data(); + if(clip) + { + clip->AddData("text/plain", B_MIME_TYPE, text.String(), text.Length()); + + int arraySize = sizeof(text_run_array) + + textruns.CountItems() * sizeof(text_run); + text_run_array *array = (text_run_array *)malloc(arraySize); + array->count = textruns.CountItems(); + for(int i = 0; i < array->count; i++) + { + memcpy(&array->runs[i], textruns.ItemAt(i), sizeof(text_run)); + } + clip->AddData("application/x-vnd.Be-text_run_array", B_MIME_TYPE, + array, arraySize); + free(array); + + be_clipboard->Commit(); + } + be_clipboard->Unlock(); + } + + for(int i = 0; i < textruns.CountItems(); i++) + { + delete(text_run *)(textruns.ItemAt(i)); + } + textruns.MakeEmpty(); + + return SDL_TRUE; } -SDL_bool clipboard_copy( struct machine *oric ) +SDL_bool clipboard_copy(struct machine *oric) { - //unsigned char *vidmem = (&oric->mem[oric->vid_addr]); - if (oric->vid_addr == oric->vidbases[0]) { - // HIRES - } else if (oric->vid_addr == oric->vidbases[2]) { - // TEXT - return clipboard_copy_text( oric ); - } - - return SDL_TRUE; + //unsigned char *vidmem = (&oric->mem[oric->vid_addr]); + if(oric->vid_addr == oric->vidbases[0]) + { + // HIRES + } + else if(oric->vid_addr == oric->vidbases[2]) + { + // TEXT + return clipboard_copy_text(oric); + } + + return SDL_TRUE; } -SDL_bool clipboard_paste( struct machine *oric ) +SDL_bool clipboard_paste(struct machine *oric) { - const char *text; - int32 textLen; - BMessage *clip = NULL; - - if (be_clipboard->Lock()) { - clip = be_clipboard->Data(); - if (clip && clip->FindData("text/plain", B_MIME_TYPE, (const void **)&text, &textLen) == B_OK) { - printf("clip: tlen %ld\n", textLen); - BString t(text, textLen); - t.ReplaceAll('\n', '\r'); - t.ReplaceAll('\t', ' '); - queuekeys( (char *)t.String() ); - } - be_clipboard->Unlock(); - } + const char* text; + int32 textLen; + BMessage *clip = NULL; + + if(be_clipboard->Lock()) + { + clip = be_clipboard->Data(); + if(clip && clip->FindData("text/plain", B_MIME_TYPE, (const void**)&text, &textLen) == B_OK) + { + printf("clip: tlen %ld\n", textLen); + BString t(text, textLen); + t.ReplaceAll('\n', '\r'); + t.ReplaceAll('\t', ' '); + queuekeys((char*)t.String()); + } + be_clipboard->Unlock(); + } return SDL_TRUE; } // SDL version doesn't work due to cpu speed -SDL_bool clipboard_paste_sdl( struct machine *oric ) +SDL_bool clipboard_paste_sdl(struct machine *oric) { - const char *text; - int32 textLen; - BMessage *clip = NULL; - SDL_Event ev; - ev.key.keysym.scancode = 0; - ev.key.keysym.mod = (SDLMod)0; - ev.key.keysym.sym = (SDLKey)0; - - if (be_clipboard->Lock()) { - clip = be_clipboard->Data(); - if (clip && clip->FindData("text/plain", B_MIME_TYPE, (const void **)&text, &textLen) == B_OK) { - for (int i = 0; i < textLen; i++) { - fprintf(stderr, "pushing key '%c'\n", text[i]); - ev.key.keysym.sym = (SDLKey)text[i]; - ev.key.keysym.unicode = text[i]; - ev.type = SDL_KEYDOWN; - ev.key.state = SDL_PRESSED; - SDL_PushEvent(&ev); - ev.type = SDL_KEYUP; - ev.key.state = SDL_RELEASED; - SDL_PushEvent(&ev); - } - } - be_clipboard->Unlock(); - } + const char* text; + int32 textLen; + BMessage *clip = NULL; + SDL_Event ev; + ev.key.keysym.scancode = 0; + ev.key.keysym.mod = (SDLMod)0; + ev.key.keysym.sym = (SDLKey)0; + + if(be_clipboard->Lock()) + { + clip = be_clipboard->Data(); + if(clip && clip->FindData("text/plain", B_MIME_TYPE, (const void**)&text, &textLen) == B_OK) + { + for(int i = 0; i < textLen; i++) + { + fprintf(stderr, "pushing key '%c'\n", text[i]); + ev.key.keysym.sym = (SDLKey)text[i]; + ev.key.keysym.unicode = text[i]; + ev.type = SDL_KEYDOWN; + ev.key.state = SDL_PRESSED; + SDL_PushEvent(&ev); + ev.type = SDL_KEYUP; + ev.key.state = SDL_RELEASED; + SDL_PushEvent(&ev); + } + } + be_clipboard->Unlock(); + } return SDL_TRUE; } -void gui_open_url( const char *url ) +void gui_open_url(const char* url) { - // BUrl is not really public yet, and I'm lazy. - // It's a bit dangerous but we trust the caller. - BString command("/bin/open '"); - command << url << "'"; - system(command.String()); + // BUrl is not really public yet, and I'm lazy. + // It's a bit dangerous but we trust the caller. + BString command("/bin/open '"); + command << url << "'"; + system(command.String()); } diff --git a/gui_win.c b/gui_win.c index f5423109..6e6d6896 100644 --- a/gui_win.c +++ b/gui_win.c @@ -49,11 +49,11 @@ static void init_clipboard(void) { if(initialized) return; - + /* Grab the window manager specific information */ SDL_SysWMinfo info; SDL_VERSION(&info.version); - if (SDL_COMPAT_GetWMInfo(&info)) + if(SDL_COMPAT_GetWMInfo(&info)) { /* Save the information for later use */ #if SDL_MAJOR_VERSION == 1 @@ -62,21 +62,21 @@ static void init_clipboard(void) g_SDL_Window = info.info.win.window; #endif initialized = SDL_TRUE; - } + } } char* get_clipboard_text_win(void) { - if (!initialized) + if(!initialized) return NULL; - - if (IsClipboardFormatAvailable(CF_TEXT) && OpenClipboard(g_SDL_Window)) + + if(IsClipboardFormatAvailable(CF_TEXT) && OpenClipboard(g_SDL_Window)) { const HANDLE hMem = GetClipboardData(CF_TEXT); - if (hMem) + if(hMem) { - char *src = (char*)GlobalLock(hMem); - if (src) + char* src = (char*)GlobalLock(hMem); + if(src) { free(text); text = strdup(src); @@ -85,40 +85,40 @@ char* get_clipboard_text_win(void) } CloseClipboard(); } - + return text; } static void set_clipboard_text_win(const char* text_) { - if (!initialized) - return; - - if ( text_ != NULL ) + if(!initialized) + return; + + if(text_ != NULL) + { + if(OpenClipboard(g_SDL_Window)) { - if ( OpenClipboard(g_SDL_Window) ) - { - HANDLE hMem = GlobalAlloc((GMEM_MOVEABLE|GMEM_DDESHARE), strlen(text_)+1); - if ( hMem != NULL ) - { - char* dst = (char*)GlobalLock(hMem); - memcpy(dst, text_, strlen(text_)+1); - GlobalUnlock(hMem); - EmptyClipboard(); - SetClipboardData(CF_TEXT, hMem); - } - CloseClipboard(); - } + HANDLE hMem = GlobalAlloc((GMEM_MOVEABLE|GMEM_DDESHARE), strlen(text_)+1); + if(hMem != NULL) + { + char* dst = (char*)GlobalLock(hMem); + memcpy(dst, text_, strlen(text_)+1); + GlobalUnlock(hMem); + EmptyClipboard(); + SetClipboardData(CF_TEXT, hMem); + } + CloseClipboard(); } + } } -SDL_bool init_gui_native( struct machine *oric ) +SDL_bool init_gui_native(struct machine *oric) { init_clipboard(); return initialized; } -void shut_gui_native( struct machine *oric ) +void shut_gui_native(struct machine *oric) { if(text) { @@ -127,46 +127,51 @@ void shut_gui_native( struct machine *oric ) } } -void gui_open_url( const char *url ) +void gui_open_url(const char* url) { ShellExecute(NULL, "open", url, - NULL, NULL, SW_SHOWNORMAL); + NULL, NULL, SW_SHOWNORMAL); return; } -SDL_bool clipboard_copy( struct machine *oric ) +SDL_bool clipboard_copy(struct machine *oric) { - // HIRES - if (oric->vid_addr != oric->vidbases[2]) - return SDL_FALSE; - - int line, col, i; - char text_[40 * 28 + 28 + 1]; - unsigned char *vidmem = (&oric->mem[oric->vid_addr]); - - for (i = 0, line = 0; line < 28; line++) { - for (col = 0; col < 40; col++) { - unsigned char c = vidmem[line * 40 + col]; - - if (c > 127) { - c -= 128; - } - - if (c < ' ' || c == 127) { - text_[i++] = ' '; - } else - text_[i++] = (char)c; - } - text_[i++] = '\n'; + // HIRES + if(oric->vid_addr != oric->vidbases[2]) + return SDL_FALSE; + + int line, col, i; + char text_[40 * 28 + 28 + 1]; + unsigned char* vidmem = (&oric->mem[oric->vid_addr]); + + for(i = 0, line = 0; line < 28; line++) + { + for(col = 0; col < 40; col++) + { + unsigned char c = vidmem[line * 40 + col]; + + if(c > 127) + { + c -= 128; + } + + if(c < ' ' || c == 127) + { + text_[i++] = ' '; + } + else + text_[i++] = (char)c; } - text_[i++] = '\0'; - //printf("%s\n", text_); - - set_clipboard_text_win(text_); - return SDL_TRUE; + text_[i++] = '\n'; + } + text_[i++] = '\0'; + //printf("%s\n", text_); + + set_clipboard_text_win(text_); + return SDL_TRUE; } -SDL_bool clipboard_paste( struct machine *oric ) +SDL_bool clipboard_paste(struct machine *oric) { if(get_clipboard_text_win()) { @@ -175,8 +180,12 @@ SDL_bool clipboard_paste( struct machine *oric ) { switch(*p) { - case '\t': *p = ' '; break; - case '\n': *p = '\r'; break; + case '\t': + *p = ' '; + break; + case '\n': + *p = '\r'; + break; default: *p = (*p < 0x20 || 127 < *p)? ' ' : *p; break; diff --git a/gui_x11.c b/gui_x11.c index 35c7bd84..971c852a 100644 --- a/gui_x11.c +++ b/gui_x11.c @@ -63,54 +63,54 @@ static void Unlock_Display(void) static int clipboard_filter(const SDL_Event *event) { /* Post all non-window manager specific events */ - if ( event->type == SDL_SYSWMEVENT && event->syswm.msg != NULL) + if(event->type == SDL_SYSWMEVENT && event->syswm.msg != NULL) { XEvent xevent = event->syswm.msg->event.xevent; /* Handle window-manager specific clipboard events */ - switch (xevent.type) + switch(xevent.type) { /* Copy the selection from XA_CUT_BUFFER0 to the requested property */ case SelectionRequest: - { - XEvent sevent; - XSelectionRequestEvent *req; - int seln_format; - unsigned long nbytes; - unsigned long overflow; - unsigned char *seln_data; - - req = &xevent.xselectionrequest; - sevent.xselection.type = SelectionNotify; - sevent.xselection.display = req->display; - sevent.xselection.selection = req->selection; - sevent.xselection.target = None; - sevent.xselection.property = None; - sevent.xselection.requestor = req->requestor; - sevent.xselection.time = req->time; - if ( XGetWindowProperty(display, DefaultRootWindow(display), - XA_CUT_BUFFER0, 0, INT_MAX/4, False, req->target, - &sevent.xselection.target, &seln_format, - &nbytes, &overflow, &seln_data) == Success ) { - if ( sevent.xselection.target == req->target ) + XEvent sevent; + XSelectionRequestEvent *req; + int seln_format; + unsigned long nbytes; + unsigned long overflow; + unsigned char* seln_data; + + req = &xevent.xselectionrequest; + sevent.xselection.type = SelectionNotify; + sevent.xselection.display = req->display; + sevent.xselection.selection = req->selection; + sevent.xselection.target = None; + sevent.xselection.property = None; + sevent.xselection.requestor = req->requestor; + sevent.xselection.time = req->time; + if(XGetWindowProperty(display, DefaultRootWindow(display), + XA_CUT_BUFFER0, 0, INT_MAX/4, False, req->target, + &sevent.xselection.target, &seln_format, + &nbytes, &overflow, &seln_data) == Success) { - if ( sevent.xselection.target == XA_STRING ) + if(sevent.xselection.target == req->target) { - if ( seln_data[nbytes-1] == '\0' ) - --nbytes; + if(sevent.xselection.target == XA_STRING) + { + if(seln_data[nbytes-1] == '\0') + --nbytes; + } + XChangeProperty(display, req->requestor, req->property, + sevent.xselection.target, seln_format, PropModeReplace, + seln_data, nbytes); + sevent.xselection.property = req->property; } - XChangeProperty(display, req->requestor, req->property, - sevent.xselection.target, seln_format, PropModeReplace, - seln_data, nbytes); - sevent.xselection.property = req->property; + XFree(seln_data); } - XFree(seln_data); + XSendEvent(display,req->requestor,False,0, &sevent); + XSync(display, False); } - XSendEvent(display,req->requestor,False,0,&sevent); - XSync(display, False); - } - break; + break; } } @@ -126,17 +126,17 @@ static char* get_clipboard_text_x11(void) int seln_format; unsigned long nbytes; unsigned long overflow; - char *src; - char *text = NULL; + char* src; + char* text = NULL; - if (!initialized) + if(!initialized) return NULL; Lock_Display(); owner = XGetSelectionOwner(display, XA_PRIMARY); Unlock_Display(); - if (owner == None || owner == window) + if(owner == None || owner == window) { owner = DefaultRootWindow(display); selection = XA_CUT_BUFFER0; @@ -153,25 +153,25 @@ static char* get_clipboard_text_x11(void) XConvertSelection(display, XA_PRIMARY, XA_STRING, selection, owner, CurrentTime); Unlock_Display(); - while (!selection_response) + while(!selection_response) { SDL_WaitEvent(&event); - if (event.type == SDL_SYSWMEVENT && event.syswm.msg != NULL) + if(event.type == SDL_SYSWMEVENT && event.syswm.msg != NULL) { XEvent xevent = event.syswm.msg->event.xevent; - if ( (xevent.type == SelectionNotify) && - (xevent.xselection.requestor == owner) ) + if((xevent.type == SelectionNotify) && + (xevent.xselection.requestor == owner)) selection_response = 1; } } } Lock_Display(); - if (XGetWindowProperty(display, owner, selection, 0, - INT_MAX/4, False, XA_STRING, &seln_type, &seln_format, - &nbytes, &overflow, (unsigned char **)&src) == Success) + if(XGetWindowProperty(display, owner, selection, 0, + INT_MAX/4, False, XA_STRING, &seln_type, &seln_format, + &nbytes, &overflow, (unsigned char**)&src) == Success) { - if (seln_type == XA_STRING) + if(seln_type == XA_STRING) { text = strdup(src); } @@ -184,18 +184,18 @@ static char* get_clipboard_text_x11(void) static void set_clipboard_text_x11(const char* text) { - if (!initialized) - return; + if(!initialized) + return; - if ( text != NULL ) - { - Lock_Display(); - XChangeProperty(display, DefaultRootWindow(display), - (Atom)XA_CUT_BUFFER0, XA_STRING, 8, PropModeReplace, (unsigned char*)text, strlen(text)+1); - if ( XGetSelectionOwner(display, XA_PRIMARY) != window ) - XSetSelectionOwner(display, XA_PRIMARY, window, CurrentTime); - Unlock_Display(); - } + if(text != NULL) + { + Lock_Display(); + XChangeProperty(display, DefaultRootWindow(display), + (Atom)XA_CUT_BUFFER0, XA_STRING, 8, PropModeReplace, (unsigned char*)text, strlen(text)+1); + if(XGetSelectionOwner(display, XA_PRIMARY) != window) + XSetSelectionOwner(display, XA_PRIMARY, window, CurrentTime); + Unlock_Display(); + } } static void init_clipboard(void) @@ -206,10 +206,10 @@ static void init_clipboard(void) /* Grab the window manager specific information */ SDL_SysWMinfo info; SDL_VERSION(&info.version); - if (SDL_COMPAT_GetWMInfo(&info)) + if(SDL_COMPAT_GetWMInfo(&info)) { /* Save the information for later use */ - if (info.subsystem == SDL_SYSWM_X11) + if(info.subsystem == SDL_SYSWM_X11) { display = info.info.x11.display; window = info.info.x11.window; @@ -235,10 +235,10 @@ static void init_clipboard(void) /* Grab the window manager specific information */ SDL_SysWMinfo info; SDL_VERSION(&info.version); - if (SDL_COMPAT_GetWMInfo(&info)) + if(SDL_COMPAT_GetWMInfo(&info)) { /* Save the information for later use */ - if (info.subsystem == SDL_SYSWM_X11) + if(info.subsystem == SDL_SYSWM_X11) { display = info.info.x11.display; window = info.info.x11.window; @@ -250,61 +250,66 @@ static void init_clipboard(void) #endif /* SDL_MAJOR_VERSION == 1 */ -SDL_bool init_gui_native( struct machine *oric ) +SDL_bool init_gui_native(struct machine *oric) { init_clipboard(); return initialized; } -void shut_gui_native( struct machine *oric ) +void shut_gui_native(struct machine *oric) { return; } -void gui_open_url( const char *url ) +void gui_open_url(const char* url) { return; } -SDL_bool clipboard_copy( struct machine *oric ) +SDL_bool clipboard_copy(struct machine *oric) { - // HIRES - if (oric->vid_addr != oric->vidbases[2]) - return SDL_FALSE; + // HIRES + if(oric->vid_addr != oric->vidbases[2]) + return SDL_FALSE; - int line, col, i; - char text[40 * 28 + 28 + 1]; - unsigned char *vidmem = (&oric->mem[oric->vid_addr]); + int line, col, i; + char text[40 * 28 + 28 + 1]; + unsigned char* vidmem = (&oric->mem[oric->vid_addr]); - for (i = 0, line = 0; line < 28; line++) { - for (col = 0; col < 40; col++) { - unsigned char c = vidmem[line * 40 + col]; + for(i = 0, line = 0; line < 28; line++) + { + for(col = 0; col < 40; col++) + { + unsigned char c = vidmem[line * 40 + col]; - if (c > 127) { - c -= 128; - } + if(c > 127) + { + c -= 128; + } - if (c < ' ' || c == 127) { - text[i++] = ' '; - } else - text[i++] = (char)c; - } - text[i++] = '\n'; + if(c < ' ' || c == 127) + { + text[i++] = ' '; + } + else + text[i++] = (char)c; } - text[i++] = '\0'; - //printf("%s\n", text); + text[i++] = '\n'; + } + text[i++] = '\0'; + //printf("%s\n", text); #if SDL_MAJOR_VERSION == 1 - set_clipboard_text_x11(text); + set_clipboard_text_x11(text); #else - SDL_SetClipboardText(text); + SDL_SetClipboardText(text); #endif - return SDL_TRUE; + return SDL_TRUE; } -SDL_bool clipboard_paste( struct machine *oric ) +SDL_bool clipboard_paste(struct machine *oric) { - char *text = NULL; + char* text = NULL; #if SDL_MAJOR_VERSION == 1 text = get_clipboard_text_x11(); @@ -320,8 +325,12 @@ SDL_bool clipboard_paste( struct machine *oric ) { switch(*p) { - case '\t': *p = ' '; break; - case '\n': *p = '\r'; break; + case '\t': + *p = ' '; + break; + case '\n': + *p = '\r'; + break; default: *p = (*p < 0x20 || 128 <= *p)? ' ' : *p; break; diff --git a/images/gfx_atmoskbd.psd b/images/gfx_atmoskbd.psd deleted file mode 100644 index c1da28d5..00000000 Binary files a/images/gfx_atmoskbd.psd and /dev/null differ diff --git a/images/status_bar.bmp b/images/status_bar.bmp new file mode 100644 index 00000000..67d3e31a Binary files /dev/null and b/images/status_bar.bmp differ diff --git a/joystick.c b/joystick.c index ec114630..35e70cc8 100644 --- a/joystick.c +++ b/joystick.c @@ -35,152 +35,171 @@ #include "machine.h" #include "joystick.h" +#include "plugins/twilighte_board/oric_twilighte_board_plugin.h" + struct keyjoydef { - char *id; + char* id; SDL_COMPAT_KEY sym; }; static struct keyjoydef keyjoytab[] = { { "BACKSPACE", SDLK_BACKSPACE }, - { "TAB", SDLK_TAB }, - { "CLEAR", SDLK_CLEAR }, - { "RETURN", SDLK_RETURN }, - { "ENTER", SDLK_RETURN }, - { "PAUSE", SDLK_PAUSE }, - { "ESCAPE", SDLK_ESCAPE }, - { "SPACE", SDLK_SPACE }, - { "HELP", SDLK_HELP }, - { "DELETE", SDLK_DELETE }, - { "DEL", SDLK_DELETE }, - { "LSHIFT", SDLK_LSHIFT }, - { "RSHIFT", SDLK_RSHIFT }, - { "RCTRL", SDLK_RCTRL }, - { "LCTRL", SDLK_LCTRL }, - { "RALT", SDLK_RALT }, - { "LALT", SDLK_LALT }, - { "KP0", SDLK_KP0 }, - { "KP1", SDLK_KP1 }, - { "KP2", SDLK_KP2 }, - { "KP3", SDLK_KP3 }, - { "KP4", SDLK_KP4 }, - { "KP5", SDLK_KP5 }, - { "KP6", SDLK_KP6 }, - { "KP7", SDLK_KP7 }, - { "KP8", SDLK_KP8 }, - { "KP9", SDLK_KP9 }, - { "KP_PERIOD", SDLK_KP_PERIOD }, - { "KP_FULLSTOP", SDLK_KP_PERIOD }, - { "KP_DIVIDE", SDLK_KP_DIVIDE }, - { "KP_MULTIPLY", SDLK_KP_MULTIPLY }, - { "KP_MINUS", SDLK_KP_MINUS }, - { "KP_PLUS", SDLK_KP_PLUS }, - { "KP_ENTER", SDLK_KP_ENTER }, - { "KP_EQUALS", SDLK_KP_EQUALS }, - { "UP", SDLK_UP }, - { "DOWN", SDLK_DOWN }, - { "LEFT", SDLK_LEFT }, - { "RIGHT", SDLK_RIGHT }, - { "INSERT", SDLK_INSERT }, - { "HOME", SDLK_HOME }, - { "END", SDLK_END }, - { "PAGEUP", SDLK_PAGEUP }, - { "PAGEDOWN", SDLK_PAGEDOWN }, - { NULL, 0 } }; + { "TAB", SDLK_TAB }, + { "CLEAR", SDLK_CLEAR }, + { "RETURN", SDLK_RETURN }, + { "ENTER", SDLK_RETURN }, + { "PAUSE", SDLK_PAUSE }, + { "ESCAPE", SDLK_ESCAPE }, + { "SPACE", SDLK_SPACE }, + { "HELP", SDLK_HELP }, + { "DELETE", SDLK_DELETE }, + { "DEL", SDLK_DELETE }, + { "LSHIFT", SDLK_LSHIFT }, + { "RSHIFT", SDLK_RSHIFT }, + { "RCTRL", SDLK_RCTRL }, + { "LCTRL", SDLK_LCTRL }, + { "RALT", SDLK_RALT }, + { "LALT", SDLK_LALT }, + { "KP0", SDLK_KP0 }, + { "KP1", SDLK_KP1 }, + { "KP2", SDLK_KP2 }, + { "KP3", SDLK_KP3 }, + { "KP4", SDLK_KP4 }, + { "KP5", SDLK_KP5 }, + { "KP6", SDLK_KP6 }, + { "KP7", SDLK_KP7 }, + { "KP8", SDLK_KP8 }, + { "KP9", SDLK_KP9 }, + { "KP_PERIOD", SDLK_KP_PERIOD }, + { "KP_FULLSTOP", SDLK_KP_PERIOD }, + { "KP_DIVIDE", SDLK_KP_DIVIDE }, + { "KP_MULTIPLY", SDLK_KP_MULTIPLY }, + { "KP_MINUS", SDLK_KP_MINUS }, + { "KP_PLUS", SDLK_KP_PLUS }, + { "KP_ENTER", SDLK_KP_ENTER }, + { "KP_EQUALS", SDLK_KP_EQUALS }, + { "UP", SDLK_UP }, + { "DOWN", SDLK_DOWN }, + { "LEFT", SDLK_LEFT }, + { "RIGHT", SDLK_RIGHT }, + { "INSERT", SDLK_INSERT }, + { "HOME", SDLK_HOME }, + { "END", SDLK_END }, + { "PAGEUP", SDLK_PAGEUP }, + { "PAGEDOWN", SDLK_PAGEDOWN }, + { "NONE", 0 }, + { NULL, 0 } +}; static SDL_bool joysubinited = SDL_FALSE; -Uint8 joystate_a[7], joystate_b[7]; +Uint8 joystate_a[JOYSTATE_LAST], joystate_b[JOYSTATE_LAST]; -static SDL_bool is_real_joystick( Sint16 joymode ) +static SDL_bool is_real_joystick(Sint16 joymode) { - if( ( joymode >= JOYMODE_SDL0 ) && ( joymode <= JOYMODE_SDL9 ) ) + if((joymode >= JOYMODE_SDL0) && (joymode <= JOYMODE_SDL9)) return SDL_TRUE; return SDL_FALSE; } -static void close_joysticks( struct machine *oric ) +static void close_joysticks(struct machine *oric) { - if( joysubinited ) + if(joysubinited) { - if( oric->sdljoy_a ) + if(oric->sdljoy_a) { - SDL_JoystickClose( oric->sdljoy_a ); - if( oric->sdljoy_b == oric->sdljoy_a ) + SDL_JoystickClose(oric->sdljoy_a); + if(oric->sdljoy_b == oric->sdljoy_a) oric->sdljoy_b = NULL; oric->sdljoy_a = NULL; } - if( oric->sdljoy_b ) + if(oric->sdljoy_b) { - SDL_JoystickClose( oric->sdljoy_b ); + SDL_JoystickClose(oric->sdljoy_b); oric->sdljoy_b = NULL; } - SDL_JoystickEventState( SDL_FALSE ); + SDL_JoystickEventState(SDL_FALSE); + } +} + + +// Returns the type of controller. +// Most of the code should be controller agnostic, but in certain cases it can be useful to know more precisely which controller is used. +// Typical example would be the handling of additional or non standard buttons and axis. +Uint8 get_joystick_type(SDL_Joystick* joystick) +{ + if(joystick) + { + // @iss: SDL_JoystickName unsupported under SDL 1.x - returns NULL + const char* joy_name = SDL_COMPAT_JoystickName(joystick); + if(joy_name) + { + // Examples of strings returned by SDL_JoystickName: + // - "DualSense Wireless Controller" + // - "SPEED-LINK Competition Pro" (USB variant of the old four direction joystick, that one has many more buttons) + // + if(strcmp(joy_name, "DualSense Wireless Controller") == 0) + { + return JOYTYPE_DUALSENSE; + } + return JOYTYPE_DEFAULT; + } } + return JOYTYPE_NONE; } + // Return an SDL keysym corresponding to the specified name (or 0) -Sint16 joy_keyname_to_sym( char *name ) +SDL_COMPAT_KEY joy_keyname_to_sym(char* name) { Sint32 i; char c; // Just a single char? - if( name[1] == 0 ) + if(name[1] == 0) { - c = tolower( name[0] ); - if( ( c >= 32 ) && ( c < 127 ) ) return c; + c = tolower(name[0]); + if((c >= 32) && (c < 127)) return c; return 0; } // Look for a matching named key - for( i=0; keyjoytab[i].id; i++ ) + for(i=0; keyjoytab[i].id; i++) { - if( strcasecmp( keyjoytab[i].id, name ) == 0 ) + if(strcasecmp(keyjoytab[i].id, name) == 0) + { + // dbg_printf("%s => %s = %.8X\n", name, keyjoytab[i].id, keyjoytab[i].sym); return keyjoytab[i].sym; + } } return 0; } -static SDL_bool dojoyevent( SDL_Event *ev, struct machine *oric, Sint16 mode, Uint8 *joystate, SDL_Joystick *sjoy ) +static SDL_bool dojoyevent(SDL_Event *ev, struct machine *oric, Sint32 mode, Uint8 *joystate, SDL_Joystick *sjoy) { - Sint32 i; - SDL_COMPAT_KEY *kbtab; SDL_bool swallowit = SDL_FALSE; - kbtab = oric->kbjoy2; - switch( mode ) + switch(mode) { case JOYMODE_NONE: case JOYMODE_MOUSE: // Telestrat only return SDL_FALSE; case JOYMODE_KB1: - kbtab = oric->kbjoy1; case JOYMODE_KB2: - switch( ev->type ) { - case SDL_KEYDOWN: - for( i=0; i<7; i++ ) + SDL_COMPAT_KEY *kbtab = mode == JOYMODE_KB1? oric->kbjoy1 : oric->kbjoy2; + int i, st = ev->type == SDL_KEYDOWN? 1 : 0; + for(i=0; i< JOYSTATE_LAST; i++) + { + if(ev->key.keysym.sym == kbtab[i]) { - if( ev->key.keysym.sym == kbtab[i] ) - { - joystate[i] = 1; - swallowit = SDL_TRUE; - } + // dbg_printf("%d: %.8X <> %.8X => %d\n", i, kbtab[i], ev->key.keysym.sym, st); + joystate[i] = st; + swallowit = SDL_TRUE; } - break; - - case SDL_KEYUP: - for( i=0; i<7; i++ ) - { - if( ev->key.keysym.sym == kbtab[i] ) - { - joystate[i] = 0; - swallowit = SDL_TRUE; - } - } - break; + } } break; @@ -194,54 +213,145 @@ static SDL_bool dojoyevent( SDL_Event *ev, struct machine *oric, Sint16 mode, Ui case JOYMODE_SDL7: case JOYMODE_SDL8: case JOYMODE_SDL9: - if( !sjoy ) return SDL_FALSE; - - switch( ev->type ) + if(!sjoy) return SDL_FALSE; + + // + // The way the controllers report the 4 direction digital values can change: + // - Some will report them as a set if two SDL_JOYAXISMOTION (one for horizontal movement and one for vertical movement) + // - Some will instead report them as SDL_JOYHATMOTION using a bit field to indicate which directions are set + // - And some (like the Sony DualSense) report them as SDL_JOYBUTTONDOWN/SDL_JOYBUTTONUP events + // + // The current SDL implementation is using the Joystick API, which unfortunately does not know much about the various controllers. + // Ideally this code should be revamped to use the SDL GameController API (see the article at https://blog.rubenwardy.com/2023/01/24/using_sdl_gamecontroller/ for an example), + // but that require a significant amount of changes are would have to be tested extensively to make sure it works properly in every situation. + // + switch(ev->type) { + case SDL_JOYHATMOTION: + if(ev->jhat.which != (mode-JOYMODE_SDL0)) return SDL_FALSE; + swallowit = SDL_TRUE; + + joystate[JOYSTATE_UP] = (ev->jhat.value & SDL_HAT_UP) ? 1 : 0; + joystate[JOYSTATE_DOWN] = (ev->jhat.value & SDL_HAT_DOWN) ? 1 : 0; + joystate[JOYSTATE_LEFT] = (ev->jhat.value & SDL_HAT_LEFT) ? 1 : 0; + joystate[JOYSTATE_RIGHT] = (ev->jhat.value & SDL_HAT_RIGHT) ? 1 : 0; + break; + case SDL_JOYAXISMOTION: - if( ev->jaxis.which != (mode-JOYMODE_SDL0) ) return SDL_FALSE; + if(ev->jaxis.which != (mode-JOYMODE_SDL0)) return SDL_FALSE; swallowit = SDL_TRUE; - switch( ev->jaxis.axis ) + + switch(ev->jaxis.axis) { case 0: // left/right - if( ev->jaxis.value < -3200 ) + case 2: // secondary analog stick on modern controllers + if(ev->jaxis.value < -AXIS_THRESHOLD) + { + joystate[JOYSTATE_LEFT] = 1; // left + joystate[JOYSTATE_RIGHT] = 0; + } + else if(ev->jaxis.value > AXIS_THRESHOLD) + { + joystate[JOYSTATE_LEFT] = 0; // right + joystate[JOYSTATE_RIGHT] = 1; + } + else { - joystate[2] = 1; // left - joystate[3] = 0; - } else if( ev->jaxis.value > 3200 ) { - joystate[2] = 0; // right - joystate[3] = 1; - } else { - joystate[2] = 0; - joystate[3] = 0; + joystate[JOYSTATE_LEFT] = 0; + joystate[JOYSTATE_RIGHT] = 0; } break; case 1: // up/down - if( ev->jaxis.value < -3200 ) + case 3: // secondary analog stick on modern controllers + if(ev->jaxis.value < -AXIS_THRESHOLD) { - joystate[0] = 1; // up - joystate[1] = 0; - } else if( ev->jaxis.value > 3200 ) { - joystate[0] = 0; // down - joystate[1] = 1; - } else { - joystate[0] = 0; - joystate[1] = 0; + joystate[JOYSTATE_UP] = 1; // up + joystate[JOYSTATE_DOWN] = 0; } + else if(ev->jaxis.value > AXIS_THRESHOLD) + { + joystate[JOYSTATE_UP] = 0; // down + joystate[JOYSTATE_DOWN] = 1; + } + else + { + joystate[JOYSTATE_UP] = 0; + joystate[JOYSTATE_DOWN] = 0; + } + break; + + case 4: // analog trigger on modern controllers + case 5: // analog trigger on modern controllers + // Trigger a fire action if the analog value passes over the threshold + joystate[JOYSTATE_FIRE1] = (ev->jaxis.value > AXIS_THRESHOLD) ? 1 : 0; + break; + + default: break; } break; case SDL_JOYBUTTONDOWN: - if( ev->jbutton.which != (mode-JOYMODE_SDL0) ) return SDL_FALSE; - joystate[4+(ev->jbutton.button % 3)] = 1; - swallowit = SDL_TRUE; + { + if(ev->jbutton.which != (mode-JOYMODE_SDL0)) return SDL_FALSE; + if((joystate[JOYSTATE_TYPE] == JOYTYPE_DUALSENSE) && + ((ev->jbutton.button>=11) && (ev->jbutton.button<=14))) + { + // Specific code path for the Sony PS5 DualSense d-pad + switch(ev->jbutton.button) + { + case 11: + joystate[JOYSTATE_UP] = 1; + break; // Up + case 12: + joystate[JOYSTATE_DOWN] = 1; + break; // Down + case 13: + joystate[JOYSTATE_LEFT] = 1; + break; // Left + case 14: + joystate[JOYSTATE_RIGHT] = 1; + break; // Right + } + } + else + { + // Standard code path to handle button press on most controllers + joystate[JOYSTATE_FIRE1 + (ev->jbutton.button % 3)] = 1; + } + swallowit = SDL_TRUE; + } + break; case SDL_JOYBUTTONUP: - if( ev->jbutton.which != (mode-JOYMODE_SDL0) ) return SDL_FALSE; - joystate[4+(ev->jbutton.button % 3)] = 0; + if(ev->jbutton.which != (mode-JOYMODE_SDL0)) return SDL_FALSE; + if((joystate[JOYSTATE_TYPE] == JOYTYPE_DUALSENSE) && + ((ev->jbutton.button >= 11) && (ev->jbutton.button <= 14))) + { + // Specific code path for the Sony PS5 DualSense d-pad + switch(ev->jbutton.button) + { + case 11: + joystate[JOYSTATE_UP] = 0; + break; // Up + case 12: + joystate[JOYSTATE_DOWN] = 0; + break; // Down + case 13: + joystate[JOYSTATE_LEFT] = 0; + break; // Left + case 14: + joystate[JOYSTATE_RIGHT] = 0; + break; // Right + } + } + else + { + // Standard code path to handle button release on most controllers + joystate[JOYSTATE_FIRE1 + (ev->jbutton.button % 3)] = 0; + } swallowit = SDL_TRUE; break; } @@ -251,212 +361,272 @@ static SDL_bool dojoyevent( SDL_Event *ev, struct machine *oric, Sint16 mode, Ui return swallowit; } -void joy_buildmask( struct machine *oric ) +void joy_buildmask(struct machine *oric) { Uint8 mkmask = 0xff; Uint8 mkmask_f = 0xff; - Uint8 joysel = oric->via.read_port_a( &oric->via ); - Uint8 telestrat_joysel = oric->tele_via.read_port_b( &oric->tele_via ); + Uint8 joysel = oric->via.read_port_a(&oric->via); + Uint8 telestrat_joysel = oric->tele_via.read_port_b(&oric->tele_via); + Uint8 twilighteboard_joysel = 0; + SDL_bool gimme_port_a = SDL_FALSE; SDL_bool gimme_port_b = SDL_FALSE; - if (oric->type == MACH_TELESTRAT) + if(oric->twilighteboard_activated) + twilighteboard_joysel= twilighteboard_oric_read(oric->twilighte,0x320); + + if(oric->type == MACH_ATMOS && oric->twilighteboard_activated) { - if ( telestrat_joysel & 0x80 ) + if(twilighteboard_joysel & 0x80) { // Right Port - if( joystate_a[0] ) mkmask &= 0xef; - if( joystate_a[1] ) mkmask &= 0xf7; - if( joystate_a[2] ) mkmask &= 0xfd; - if( joystate_a[3] ) mkmask &= 0xfe; - if( joystate_a[4] ) mkmask &= 0xfb; + if(joystate_a[JOYSTATE_UP]) mkmask &= 0xef; + if(joystate_a[JOYSTATE_DOWN]) mkmask &= 0xf7; + if(joystate_a[JOYSTATE_LEFT]) mkmask &= 0xfd; + if(joystate_a[JOYSTATE_RIGHT]) mkmask &= 0xfe; + if(joystate_a[JOYSTATE_FIRE1]) mkmask &= 0xfb; - if( joystate_a[5] ) mkmask_f &= 0x7f; // PA7 - fire 2 - if( joystate_a[6] ) mkmask_f &= 0xdf; // PA5 - fire 3 + if(joystate_a[JOYSTATE_FIRE2]) mkmask_f &= 0x7f; // PA7 - fire 2 + if(joystate_a[JOYSTATE_FIRE3]) mkmask_f &= 0xdf; // PA5 - fire 3 gimme_port_a = SDL_TRUE; gimme_port_b = SDL_TRUE; } - if ( telestrat_joysel & 0x40 ) + if(twilighteboard_joysel & 0x40) { // Left Port - if( joystate_b[0] ) mkmask &= 0xef; // 0x10 - up - if( joystate_b[1] ) mkmask &= 0xf7; // 0x08 - down - if( joystate_b[2] ) mkmask &= 0xfd; // 0x02 - left - if( joystate_b[3] ) mkmask &= 0xfe; // 0x01 - right - if( joystate_b[4] ) mkmask &= 0xfb; // 0x04 - fire + if(joystate_b[JOYSTATE_UP]) mkmask &= 0xef; // 0x10 - up + if(joystate_b[JOYSTATE_DOWN]) mkmask &= 0xf7; // 0x08 - down + if(joystate_b[JOYSTATE_LEFT]) mkmask &= 0xfd; // 0x02 - left + if(joystate_b[JOYSTATE_RIGHT]) mkmask &= 0xfe; // 0x01 - right + if(joystate_b[JOYSTATE_FIRE1]) mkmask &= 0xfb; // 0x04 - fire gimme_port_b = SDL_TRUE; } - if( gimme_port_a ) + if(gimme_port_a) { - oric->tele_via.write_port_a( &oric->tele_via, 0xff, mkmask_f ); + twilighteboard_oric_write(oric->twilighte, 0x321, 0xff, mkmask_f); } - if( gimme_port_b ) + if(gimme_port_b) { - oric->tele_via.write_port_b( &oric->tele_via, 0xff, mkmask ); + // port B + twilighteboard_oric_write(oric->twilighte, 0x320, 0xff, mkmask); } } + else if(oric->type == MACH_TELESTRAT) + { + if(telestrat_joysel & 0x80) + { + // Right Port + if(joystate_a[JOYSTATE_UP]) mkmask &= 0xef; + if(joystate_a[JOYSTATE_DOWN]) mkmask &= 0xf7; + if(joystate_a[JOYSTATE_LEFT]) mkmask &= 0xfd; + if(joystate_a[JOYSTATE_RIGHT]) mkmask &= 0xfe; + if(joystate_a[JOYSTATE_FIRE1]) mkmask &= 0xfb; + + if(joystate_a[JOYSTATE_FIRE2]) mkmask_f &= 0x7f; // PA7 - fire 2 + if(joystate_a[JOYSTATE_FIRE3]) mkmask_f &= 0xdf; // PA5 - fire 3 + gimme_port_a = SDL_TRUE; + gimme_port_b = SDL_TRUE; + } + + if(telestrat_joysel & 0x40) + { + // Left Port + if(joystate_b[JOYSTATE_UP]) mkmask &= 0xef; // 0x10 - up + if(joystate_b[JOYSTATE_DOWN]) mkmask &= 0xf7; // 0x08 - down + if(joystate_b[JOYSTATE_LEFT]) mkmask &= 0xfd; // 0x02 - left + if(joystate_b[JOYSTATE_RIGHT ]) mkmask &= 0xfe; // 0x01 - right + if(joystate_b[JOYSTATE_FIRE1 ]) mkmask &= 0xfb; // 0x04 - fire + gimme_port_b = SDL_TRUE; + } + + if(gimme_port_a) + { + oric->tele_via.write_port_a(&oric->tele_via, 0xff, mkmask_f); + } + + if(gimme_port_b) + { + oric->tele_via.write_port_b(&oric->tele_via, 0xff, mkmask); + } + } else { - switch( oric->joy_iface ) + switch(oric->joy_iface) { case JOYIFACE_ALTAI: - if( joysel & 0x80 ) + if(joysel & 0x80) { - if( joystate_a[0] ) mkmask &= 0xef; - if( joystate_a[1] ) mkmask &= 0xf7; - if( joystate_a[2] ) mkmask &= 0xfe; - if( joystate_a[3] ) mkmask &= 0xfd; - if( joystate_a[4] ) mkmask &= 0xdf; + if(joystate_a[JOYSTATE_UP]) mkmask &= 0xef; + if(joystate_a[JOYSTATE_DOWN]) mkmask &= 0xf7; + if(joystate_a[JOYSTATE_LEFT]) mkmask &= 0xfe; + if(joystate_a[JOYSTATE_RIGHT]) mkmask &= 0xfd; + if(joystate_a[JOYSTATE_FIRE1] || + joystate_a[JOYSTATE_FIRE2] || + joystate_a[JOYSTATE_FIRE3]) mkmask &= 0xdf; gimme_port_a = SDL_TRUE; } - if( joysel & 0x40 ) + if(joysel & 0x40) { - if( joystate_b[0] ) mkmask &= 0xef; // 0x10 - up - if( joystate_b[1] ) mkmask &= 0xf7; // 0x08 - down - if( joystate_b[2] ) mkmask &= 0xfe; // 0x01 - left - if( joystate_b[3] ) mkmask &= 0xfd; // 0x02 - right - if( joystate_b[4] ) mkmask &= 0xdf; // 0x20 - fire + if(joystate_b[JOYSTATE_UP]) mkmask &= 0xef; // 0x10 - up + if(joystate_b[JOYSTATE_DOWN]) mkmask &= 0xf7; // 0x08 - down + if(joystate_b[JOYSTATE_LEFT]) mkmask &= 0xfe; // 0x01 - left + if(joystate_b[JOYSTATE_RIGHT]) mkmask &= 0xfd; // 0x02 - right + if(joystate_b[JOYSTATE_FIRE1] || + joystate_b[JOYSTATE_FIRE2] || + joystate_b[JOYSTATE_FIRE3]) mkmask &= 0xdf; // 0x20 - fire gimme_port_a = SDL_TRUE; } break; case JOYIFACE_IJK: - mkmask &= 0xdf; + mkmask &= 0xdf; - if( ((oric->via.ddrb & 0x10)==0) || - ((oric->via.read_port_b( &oric->via )&0x10)!=0) ) + if(((oric->via.ddrb & 0x10)==0) || + ((oric->via.read_port_b(&oric->via)&0x10)!=0)) break; gimme_port_a = SDL_TRUE; - if( ( joysel & 0xc0 ) == 0xc0 ) break; + if((joysel & 0xc0) == 0xc0) break; - if( joysel & 0x40 ) + if(joysel & 0x40) { - if( joystate_a[0] ) mkmask &= 0xef; - if( joystate_a[1] ) mkmask &= 0xf7; - if( joystate_a[2] ) mkmask &= 0xfd; - if( joystate_a[3] ) mkmask &= 0xfe; - if( joystate_a[4] ) mkmask &= 0xfb; + if(joystate_a[JOYSTATE_UP]) mkmask &= 0xef; + if(joystate_a[JOYSTATE_DOWN]) mkmask &= 0xf7; + if(joystate_a[JOYSTATE_LEFT]) mkmask &= 0xfd; + if(joystate_a[JOYSTATE_RIGHT]) mkmask &= 0xfe; + if(joystate_a[JOYSTATE_FIRE1] || + joystate_a[JOYSTATE_FIRE2] || + joystate_a[JOYSTATE_FIRE3]) mkmask &= 0xfb; } - if( joysel & 0x80 ) + if(joysel & 0x80) { - if( joystate_b[0] ) mkmask &= 0xef; // 0x10 - up - if( joystate_b[1] ) mkmask &= 0xf7; // 0x08 - down - if( joystate_b[2] ) mkmask &= 0xfd; // 0x02 - left - if( joystate_b[3] ) mkmask &= 0xfe; // 0x01 - right - if( joystate_b[4] ) mkmask &= 0xfb; // 0x04 - fire + if(joystate_b[JOYSTATE_UP]) mkmask &= 0xef; // 0x10 - up + if(joystate_b[JOYSTATE_DOWN]) mkmask &= 0xf7; // 0x08 - down + if(joystate_b[JOYSTATE_LEFT]) mkmask &= 0xfd; // 0x02 - left + if(joystate_b[JOYSTATE_RIGHT]) mkmask &= 0xfe; // 0x01 - right + if(joystate_b[JOYSTATE_FIRE1] || + joystate_b[JOYSTATE_FIRE2] || + joystate_b[JOYSTATE_FIRE3]) mkmask &= 0xfb; // 0x04 - fire } break; } oric->porta_joy = mkmask; - if( gimme_port_a ) + if(gimme_port_a) { - oric->via.write_port_a( &oric->via, 0xff, mkmask ); + oric->via.write_port_a(&oric->via, 0xff, mkmask); oric->porta_is_ay = SDL_FALSE; - } else { - if( !oric->porta_is_ay ) + } + else + { + if(!oric->porta_is_ay) { - oric->via.write_port_a( &oric->via, 0xff, oric->porta_ay ); + oric->via.write_port_a(&oric->via, 0xff, oric->porta_ay); oric->porta_is_ay = SDL_TRUE; } } } } -SDL_bool joy_filter_event( SDL_Event *ev, struct machine *oric ) +SDL_bool joy_filter_event(SDL_Event *ev, struct machine *oric) { SDL_bool swallow_event; + SDL_bool mode = (oric->type==MACH_TELESTRAT || (oric->twilighteboard_activated && oric->type==MACH_ATMOS))? SDL_TRUE : SDL_FALSE; - swallow_event = dojoyevent( ev, oric, (oric->type==MACH_TELESTRAT) ? oric->telejoymode_a : oric->joymode_a, joystate_a, oric->sdljoy_a ); - swallow_event |= dojoyevent( ev, oric, (oric->type==MACH_TELESTRAT) ? oric->telejoymode_b : oric->joymode_b, joystate_b, oric->sdljoy_b ); + swallow_event = dojoyevent(ev, oric, mode ? oric->telejoymode_a : oric->joymode_a, joystate_a, oric->sdljoy_a); + swallow_event |= dojoyevent(ev, oric, mode ? oric->telejoymode_b : oric->joymode_b, joystate_b, oric->sdljoy_b); - if( swallow_event ) + if(swallow_event) { -// char testytesttest[64]; - - joy_buildmask( oric ); -/* - sprintf( testytesttest, "A: %d%d%d%d-%d%d B: %d%d%d%d-%d%d", - joystate_a[0], joystate_a[1], joystate_a[2], joystate_a[3], - joystate_a[4], joystate_a[5], - joystate_b[0], joystate_b[1], joystate_b[2], joystate_b[3], - joystate_b[4], joystate_b[5] ); - SDL_WM_SetCaption( testytesttest, testytesttest ); -*/ + joy_buildmask(oric); + // { + // char testytesttest[64]; + // sprintf( testytesttest, "A: %d%d%d%d-%d%d B: %d%d%d%d-%d%d", + // joystate_a[0], joystate_a[1], joystate_a[2], joystate_a[3], + // joystate_a[4], joystate_a[5], + // joystate_b[0], joystate_b[1], joystate_b[2], joystate_b[3], + // joystate_b[4], joystate_b[5] ); + // SDL_WM_SetCaption( testytesttest, testytesttest ); + // } } return swallow_event; } -static void dojoysetup( struct machine *oric, Sint16 mode_a, Sint16 mode_b ) +static void dojoysetup(struct machine *oric, Sint16 mode_a, Sint16 mode_b) { Sint32 i; - close_joysticks( oric ); + close_joysticks(oric); - for( i=0; i<6; i++ ) + for(i=0; i< JOYSTATE_LAST; i++) { joystate_a[i] = 0; joystate_b[i] = 0; } + joystate_a[JOYSTATE_TYPE] = JOYTYPE_NONE; + joystate_b[JOYSTATE_TYPE] = JOYTYPE_NONE; - if( (!is_real_joystick( mode_a )) && (!is_real_joystick( mode_b )) ) + if((!is_real_joystick(mode_a)) && (!is_real_joystick(mode_b))) return; - if( !joysubinited ) + if(!joysubinited) { //dbg_printf( "Initialising joysubsystem" ); - if( SDL_InitSubSystem( SDL_INIT_JOYSTICK ) != 0 ) + if(SDL_InitSubSystem(SDL_INIT_JOYSTICK) != 0) return; //dbg_printf( "Success!" ); joysubinited = SDL_TRUE; } - if( is_real_joystick( mode_a ) ) + if(is_real_joystick(mode_a)) { - oric->sdljoy_a = SDL_JoystickOpen( mode_a - JOYMODE_SDL0 ); + oric->sdljoy_a = SDL_JoystickOpen(mode_a - JOYMODE_SDL0); + joystate_a[JOYSTATE_TYPE] = get_joystick_type(oric->sdljoy_a); //dbg_printf( "Joy0 = %p", oric->sdljoy_a ); - SDL_JoystickEventState( SDL_TRUE ); + SDL_JoystickEventState(SDL_TRUE); } - if( is_real_joystick( mode_b ) ) + if(is_real_joystick(mode_b)) { - if( mode_b == mode_a ) + if(mode_b == mode_a) { oric->sdljoy_b = oric->sdljoy_a; - } else { - oric->sdljoy_b = SDL_JoystickOpen( mode_b - JOYMODE_SDL0 ); - SDL_JoystickEventState( SDL_TRUE ); + } + else + { + oric->sdljoy_b = SDL_JoystickOpen(mode_b - JOYMODE_SDL0); + joystate_b[JOYSTATE_TYPE] = get_joystick_type(oric->sdljoy_b); + SDL_JoystickEventState(SDL_TRUE); } } } -void joy_setup( struct machine *oric ) +void joy_setup(struct machine *oric) { - if( oric->type == MACH_TELESTRAT ) - dojoysetup( oric, oric->telejoymode_a, oric->telejoymode_b ); + if(oric->type == MACH_TELESTRAT || (oric->type == MACH_ATMOS && oric->twilighteboard_activated)) + dojoysetup(oric, oric->telejoymode_a, oric->telejoymode_b); else - dojoysetup( oric, oric->joymode_a, oric->joymode_b ); + dojoysetup(oric, oric->joymode_a, oric->joymode_b); } -SDL_bool init_joy( struct machine *oric ) +SDL_bool init_joy(struct machine *oric) { return SDL_TRUE; } -void shut_joy( struct machine *oric ) +void shut_joy(struct machine *oric) { - close_joysticks( oric ); + close_joysticks(oric); } diff --git a/joystick.h b/joystick.h index f1bd63a1..a08b1d52 100644 --- a/joystick.h +++ b/joystick.h @@ -19,6 +19,8 @@ ** Joystick definitions */ +#define AXIS_THRESHOLD 8000 // How far the user needs to push an analog axis before it triggers a digital impulse. (was previously defined as 3200, but was too sensitive and made it almost impossible to accurately go in one direction) + // Joystick interface types enum { @@ -46,10 +48,31 @@ enum JOYMODE_MOUSE }; -SDL_bool init_joy( struct machine *oric ); -void shut_joy( struct machine *oric ); +enum +{ + JOYSTATE_UP = 0, + JOYSTATE_DOWN, + JOYSTATE_LEFT, + JOYSTATE_RIGHT, + JOYSTATE_FIRE1, + JOYSTATE_FIRE2, + JOYSTATE_FIRE3, + JOYSTATE_TYPE, + JOYSTATE_LAST +}; + +// Hacked joystick detection mode +enum +{ + JOYTYPE_NONE = 0, + JOYTYPE_DEFAULT, + JOYTYPE_DUALSENSE, +}; + +SDL_bool init_joy(struct machine *oric); +void shut_joy(struct machine *oric); -Sint16 joy_keyname_to_sym( char *name ); -void joy_setup( struct machine *oric ); -SDL_bool joy_filter_event( SDL_Event *ev, struct machine *oric ); -void joy_buildmask( struct machine *oric ); +SDL_COMPAT_KEY joy_keyname_to_sym(char* name); +void joy_setup(struct machine *oric); +SDL_bool joy_filter_event(SDL_Event *ev, struct machine *oric); +void joy_buildmask(struct machine *oric); diff --git a/keyboard.c b/keyboard.c index 5a2bb053..90e24c6c 100644 --- a/keyboard.c +++ b/keyboard.c @@ -48,31 +48,31 @@ static struct kbdkey kbd_atmos[65], kbd_oric1[65], kbd_pravetz[65]; -SDL_Surface* CreateSurface( int width , int height ) +SDL_Surface* CreateSurface(int width, int height) { - uint32_t rmask , gmask , bmask , amask; - SDL_Surface* surface; + uint32_t rmask, gmask, bmask, amask; + SDL_Surface* surface; - /* SDL interprets each pixel as a 32-bit number, so our masks must depend - on the endianness (byte order) of the machine */ + /* SDL interprets each pixel as a 32-bit number, so our masks must depend + on the endianness (byte order) of the machine */ #if SDL_BYTEORDER == SDL_BIG_ENDIAN - rmask = 0xff000000; - gmask = 0x00ff0000; - bmask = 0x0000ff00; - amask = 0x000000ff; + rmask = 0xff000000; + gmask = 0x00ff0000; + bmask = 0x0000ff00; + amask = 0x000000ff; #else - rmask = 0x000000ff; - gmask = 0x0000ff00; - bmask = 0x00ff0000; - amask = 0xff000000; + rmask = 0x000000ff; + gmask = 0x0000ff00; + bmask = 0x00ff0000; + amask = 0xff000000; #endif - surface = SDL_CreateRGBSurface( 0 , width , height , 32 , rmask , gmask , bmask , amask ); - if( surface == NULL ) - { - error_printf("CreateRGBSurface failed: %s", SDL_GetError() ); - exit(EXIT_FAILURE); - } + surface = SDL_CreateRGBSurface(0, width, height, 32, rmask, gmask, bmask, amask); + if(surface == NULL) + { + error_printf("CreateRGBSurface failed: %s", SDL_GetError()); + exit(EXIT_FAILURE); + } return surface; } @@ -80,42 +80,49 @@ SDL_Surface* CreateSurface( int width , int height ) #define KEYSIM_FLAG ((SDL_COMPAT_KEY)0x8000) #define KEYSIM_MASK ((SDL_COMPAT_KEY)0x7FFF) -static SDL_COMPAT_KEY keyMap[] = { - '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', '\\', - SDLK_ESCAPE, 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', SDLK_BACKSPACE, - SDLK_LCTRL, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', SDLK_RETURN, - SDLK_LSHIFT, 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', SDLK_RSHIFT, - SDLK_LEFT, SDLK_DOWN, ' ', SDLK_UP, SDLK_RIGHT, SDLK_RALT, ' ', ' ', ' ', ' ', ' ', ' ' }; - -static SDL_COMPAT_KEY keyMapPravetz[] = { - '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', KEYSIM_FLAG|';', '-', ';', - SDLK_ESCAPE, 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', KEYSIM_FLAG|'2', '\\', SDLK_BACKSPACE, - SDLK_LCTRL, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', '[', ']', SDLK_RETURN, - SDLK_LSHIFT, 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', SDLK_RSHIFT, - SDLK_LEFT, SDLK_DOWN, ' ', SDLK_UP, SDLK_RIGHT, SDLK_RALT, KEYSIM_FLAG|'6', ' ', ' ', ' ', ' ', ' ' }; - -static SDL_COMPAT_KEY keyMapShiftedPravetz[] = { - '1', '\'', '3', '4', '5', '7', KEYSIM_FLAG|'\'', '9', '0', '-', '8', KEYSIM_FLAG|'=', '=', - SDLK_ESCAPE, 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '~', '\\', SDLK_BACKSPACE, - SDLK_LCTRL, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', '[', ']', SDLK_RETURN, - SDLK_LSHIFT, 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', SDLK_RSHIFT, - SDLK_LEFT, SDLK_DOWN, ' ', SDLK_UP, SDLK_RIGHT, SDLK_RALT, '`', ' ', ' ', ' ', ' ', ' ' }; - -enum { - MOD_CTRL = 0, - MOD_LSHIFT, - MOD_RSHIFT, - MOD_FUNCT, - MODKEY_MAX +static SDL_COMPAT_KEY keyMap[] = +{ + '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', '\\', + SDLK_ESCAPE, 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', SDLK_BACKSPACE, + SDLK_LCTRL, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', SDLK_RETURN, + SDLK_LSHIFT, 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', SDLK_RSHIFT, + SDLK_LEFT, SDLK_DOWN, ' ', SDLK_UP, SDLK_RIGHT, SDLK_RALT, ' ', ' ', ' ', ' ', ' ', ' ' +}; + +static SDL_COMPAT_KEY keyMapPravetz[] = +{ + '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', KEYSIM_FLAG|';', '-', ';', + SDLK_ESCAPE, 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', KEYSIM_FLAG|'2', '\\', SDLK_BACKSPACE, + SDLK_LCTRL, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', '[', ']', SDLK_RETURN, + SDLK_LSHIFT, 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', SDLK_RSHIFT, + SDLK_LEFT, SDLK_DOWN, ' ', SDLK_UP, SDLK_RIGHT, SDLK_RALT, KEYSIM_FLAG|'6', ' ', ' ', ' ', ' ', ' ' +}; + +static SDL_COMPAT_KEY keyMapShiftedPravetz[] = +{ + '1', '\'', '3', '4', '5', '7', KEYSIM_FLAG|'\'', '9', '0', '-', '8', KEYSIM_FLAG|'=', '=', + SDLK_ESCAPE, 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '~', '\\', SDLK_BACKSPACE, + SDLK_LCTRL, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', '[', ']', SDLK_RETURN, + SDLK_LSHIFT, 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', SDLK_RSHIFT, + SDLK_LEFT, SDLK_DOWN, ' ', SDLK_UP, SDLK_RIGHT, SDLK_RALT, '`', ' ', ' ', ' ', ' ', ' ' +}; + +enum +{ + MOD_CTRL = 0, + MOD_LSHIFT, + MOD_RSHIFT, + MOD_FUNCT, + MODKEY_MAX }; static SDL_COMPAT_KEY modKeys[MODKEY_MAX] = { SDLK_LCTRL, SDLK_LSHIFT, SDLK_RSHIFT, SDLK_LALT }; -static char *modKeyNames[MODKEY_MAX] = { "Ctrl", "Left shift", "Right shift", "Funct" }; +static char* modKeyNames[MODKEY_MAX] = { "Ctrl", "Left shift", "Right shift", "Funct" }; static const int modKeyMax = MODKEY_MAX; static SDL_bool modKeyPressed[MODKEY_MAX]; static SDL_bool modKeyFakePressed[MODKEY_MAX]; -int kbd_init( struct machine *oric ) +int kbd_init(struct machine *oric) { int i, j; @@ -124,7 +131,7 @@ int kbd_init( struct machine *oric ) oric->keyboard_mapping.nb_map = 0; - for( i=0; i<62; i++ ) + for(i=0; i<62; i++) { kbd_atmos[i].w = 43; kbd_atmos[i].h = 43; @@ -150,18 +157,20 @@ int kbd_init( struct machine *oric ) // mod keys - for (j = 0; j < modKeyMax; j++) { - if (kbd_atmos[i].keysim == modKeys[j]) { - kbd_atmos[i].is_mod_key = 1; - kbd_oric1[i].is_mod_key = 1; - kbd_pravetz[i].is_mod_key = 1; - } + for(j = 0; j < modKeyMax; j++) + { + if(kbd_atmos[i].keysim == modKeys[j]) + { + kbd_atmos[i].is_mod_key = 1; + kbd_oric1[i].is_mod_key = 1; + kbd_pravetz[i].is_mod_key = 1; } + } } - for( i=0; i<13; i++ ) + for(i=0; i<13; i++) { kbd_atmos[i].x = i*43+47; kbd_atmos[i].y = 10; @@ -172,7 +181,7 @@ int kbd_init( struct machine *oric ) kbd_pravetz[i].x = i*42+47; kbd_pravetz[i].y = 10; } - for( i=13; i<27; i++ ) + for(i=13; i<27; i++) { kbd_atmos[i].x = (i-13)*43+23; kbd_atmos[i].y = 53; @@ -183,7 +192,7 @@ int kbd_init( struct machine *oric ) kbd_pravetz[i].x = (i-13)*42+25; kbd_pravetz[i].y = 51; } - for( i=27; i<40; i++ ) + for(i=27; i<40; i++) { kbd_atmos[i].x = (i-27)*43+38; kbd_atmos[i].y = 96; @@ -201,7 +210,7 @@ int kbd_init( struct machine *oric ) kbd_atmos[40].y = 139; kbd_atmos[40].w = 65; - for( i=41; i<52; i++ ) + for(i=41; i<52; i++) { kbd_atmos[i].x = (i-41)*43+103; kbd_atmos[i].y = 139; @@ -223,7 +232,7 @@ int kbd_init( struct machine *oric ) kbd_atmos[57].y = 182; kbd_atmos[58].x = -1; - for( i=40; i<52; i++ ) + for(i=40; i<52; i++) { kbd_oric1[i].x = (i-40)*43+49; kbd_oric1[i].y = 144; @@ -242,7 +251,7 @@ int kbd_init( struct machine *oric ) kbd_oric1[56].y = 187; kbd_oric1[57].x = -1; - for( i=41; i<52; i++ ) + for(i=41; i<52; i++) { kbd_pravetz[i].x = (i-41)*43+103; kbd_pravetz[i].y = 137; @@ -283,307 +292,358 @@ static SDL_bool release_keys = SDL_FALSE; // This is the event handler for when you are in the menus -SDL_bool keyboard_event( SDL_Event *ev, struct machine *oric, SDL_bool *needrender ) +SDL_bool keyboard_event(SDL_Event *ev, struct machine *oric, SDL_bool *needrender) { - SDL_bool done = SDL_FALSE; - SDL_bool lshifted = modKeyPressed[MOD_LSHIFT]; - SDL_bool rshifted = modKeyPressed[MOD_RSHIFT]; + SDL_bool done = SDL_FALSE; + SDL_bool lshifted = modKeyPressed[MOD_LSHIFT]; + SDL_bool rshifted = modKeyPressed[MOD_RSHIFT]; - int i, x, y, current_key_num = -1; - static char tmp[64]; - struct kbdkey * kbd; + int i, x, y, current_key_num = -1; + static char tmp[64]; + struct kbdkey * kbd; - if (release_keys) + if(release_keys) + { + x = 0; + for(i=0; iay, modKeys[i], SDL_FALSE ); - snprintf(tmp, sizeof(tmp), "%s released.", modKeyNames[i]); - do_popup(oric, tmp); - x++; - } else if (modKeyFakePressed[i]) { - modKeyFakePressed[i] = SDL_FALSE; - ay_keypress( &oric->ay, modKeys[i], SDL_FALSE ); - } + modKeyPressed[i] = SDL_FALSE; + ay_keypress(&oric->ay, modKeys[i], SDL_FALSE); + snprintf(tmp, sizeof(tmp), "%s released.", modKeyNames[i]); + do_popup(oric, tmp); + x++; + } + else if(modKeyFakePressed[i]) + { + modKeyFakePressed[i] = SDL_FALSE; + ay_keypress(&oric->ay, modKeys[i], SDL_FALSE); } + } - if (x > 1) - do_popup(oric, "All keys released"); + if(x > 1) + do_popup(oric, "All keys released"); - release_keys = SDL_FALSE; - } + release_keys = SDL_FALSE; + } - x = -1; - y = -1; - switch( ev->type ) - { - case SDL_MOUSEBUTTONDOWN: - x = ev->button.x; - y = ev->button.y - 480; + x = -1; + y = -1; + switch(ev->type) + { + case SDL_MOUSEBUTTONDOWN: + x = ev->button.x; + y = ev->button.y - 480; - switch( oric->type ) - { - case MACH_PRAVETZ: - kbd = kbd_pravetz; - break; - case MACH_ORIC1: - case MACH_ORIC1_16K: - kbd = kbd_oric1; - break; - default: - kbd = kbd_atmos; - break; - } + switch(oric->type) + { + case MACH_PRAVETZ: + kbd = kbd_pravetz; + break; + case MACH_ORIC1: + case MACH_ORIC1_16K: + kbd = kbd_oric1; + break; + default: + kbd = kbd_atmos; + break; + } - // find the visual key under the mouse pointer - current_key = NULL; - for(i=0; i<62; i++) { - if ((x > kbd[i].x) && (x < kbd[i].x + kbd[i].w) && - (y > kbd[i].y) && (y < kbd[i].y + kbd[i].h)) { - current_key = &(kbd[i]); - current_key_num = i; - //if (ev->type == SDL_MOUSEBUTTONDOWN) - // printf("Key %d pressed : keysim %d (%c)\n", - // i, current_key->keysim, (char)(current_key->keysim)); - break; - } - } + // find the visual key under the mouse pointer + current_key = NULL; + for(i=0; i<62; i++) + { + if((x > kbd[i].x) && (x < kbd[i].x + kbd[i].w) && + (y > kbd[i].y) && (y < kbd[i].y + kbd[i].h)) + { + current_key = &(kbd[i]); + current_key_num = i; + //if (ev->type == SDL_MOUSEBUTTONDOWN) + // printf("Key %d pressed : keysim %d (%c)\n", + // i, current_key->keysim, (char)(current_key->keysim)); + break; + } + } - if (current_key != NULL) { - // check which button was pressed - if( ev->button.button == SDL_BUTTON_LEFT ) + if(current_key != NULL) + { + // check which button was pressed + if(ev->button.button == SDL_BUTTON_LEFT) + { + if(oric->define_mapping) + { + do_popup(oric, "Press the key you want to use."); + defining_key_map = SDL_TRUE; + } + else + { + // manage mod keys + if(current_key->is_mod_key && oric->sticky_mod_keys) + { + for(i=0; ikeysim == modKeys[i]) + break; + } + + if(i < modKeyMax) + { + if(modKeyPressed[i]) + { + modKeyPressed[i] = SDL_FALSE; + snprintf(tmp, sizeof(tmp), "%s released.", modKeyNames[i]); + } + else { - if(oric->define_mapping) { - do_popup( oric, "Press the key you want to use." ); - defining_key_map = SDL_TRUE; - } else { - // manage mod keys - if (current_key->is_mod_key && oric->sticky_mod_keys) { - for (i=0; ikeysim == modKeys[i]) - break; - } - - if (i < modKeyMax) { - if (modKeyPressed[i]) { - modKeyPressed[i] = SDL_FALSE; - snprintf(tmp, sizeof(tmp), "%s released.", modKeyNames[i]); - } else { - modKeyPressed[i] = SDL_TRUE; - snprintf(tmp, sizeof(tmp), "%s pressed.", modKeyNames[i]); - } - do_popup(oric, tmp); - ay_keypress( &oric->ay, current_key->keysim, modKeyPressed[i] ); - current_key = NULL; - return done; - } - } - - // send the key to the Oric - switch( oric->type ) - { - case MACH_PRAVETZ: - if (lshifted) { - if (current_key_num == 24) - queuekeys("\x60"); - if (KEYSIM_FLAG & current_key->keysimshifted) - ay_keypress( &oric->ay, modKeys[MOD_LSHIFT], SDL_FALSE ); - ay_keypress( &oric->ay, KEYSIM_MASK & current_key->keysimshifted, SDL_TRUE ); - } else if (rshifted) { - if (current_key_num == 24) - queuekeys("\x60"); - if (KEYSIM_FLAG & current_key->keysimshifted) - ay_keypress( &oric->ay, modKeys[MOD_RSHIFT], SDL_FALSE ); - ay_keypress( &oric->ay, KEYSIM_MASK & current_key->keysimshifted, SDL_TRUE ); - } else { - if (current_key_num == 59) { - queuekeys("\x14"); - } else if (KEYSIM_FLAG & current_key->keysim) { - ay_keypress( &oric->ay, modKeys[MOD_LSHIFT], SDL_TRUE ); - ay_keypress( &oric->ay, KEYSIM_MASK & current_key->keysim, SDL_TRUE ); - modKeyFakePressed[MOD_LSHIFT] = SDL_TRUE; - } else { - ay_keypress( &oric->ay, KEYSIM_MASK & current_key->keysim, SDL_TRUE ); - } - } - break; - case MACH_ORIC1: - case MACH_ORIC1_16K: - case MACH_ATMOS: - default: - ay_keypress( &oric->ay, current_key->keysim, SDL_TRUE ); - break; - } - - // start releasing mod keys if need be - release_keys = SDL_TRUE; - } + modKeyPressed[i] = SDL_TRUE; + snprintf(tmp, sizeof(tmp), "%s pressed.", modKeyNames[i]); } + do_popup(oric, tmp); + ay_keypress(&oric->ay, current_key->keysim, modKeyPressed[i]); + current_key = NULL; + return done; + } } - break; - - case SDL_MOUSEBUTTONUP: - if ((current_key == NULL) || (defining_key_map)) - break; // send the key to the Oric - switch( oric->type ) + switch(oric->type) { - case MACH_PRAVETZ: - if (lshifted || rshifted) { - ay_keypress( &oric->ay, KEYSIM_MASK & current_key->keysimshifted, SDL_FALSE ); - } else { - ay_keypress( &oric->ay, KEYSIM_MASK & current_key->keysim, SDL_FALSE ); - } - break; - case MACH_ORIC1: - case MACH_ORIC1_16K: - case MACH_ATMOS: - default: - ay_keypress( &oric->ay, current_key->keysim, SDL_FALSE ); - break; + case MACH_PRAVETZ: + if(lshifted) + { + if(current_key_num == 24) + queuekeys("\x60"); + if(KEYSIM_FLAG & current_key->keysimshifted) + ay_keypress(&oric->ay, modKeys[MOD_LSHIFT], SDL_FALSE); + ay_keypress(&oric->ay, KEYSIM_MASK & current_key->keysimshifted, SDL_TRUE); + } + else if(rshifted) + { + if(current_key_num == 24) + queuekeys("\x60"); + if(KEYSIM_FLAG & current_key->keysimshifted) + ay_keypress(&oric->ay, modKeys[MOD_RSHIFT], SDL_FALSE); + ay_keypress(&oric->ay, KEYSIM_MASK & current_key->keysimshifted, SDL_TRUE); + } + else + { + if(current_key_num == 59) + { + queuekeys("\x14"); + } + else if(KEYSIM_FLAG & current_key->keysim) + { + ay_keypress(&oric->ay, modKeys[MOD_LSHIFT], SDL_TRUE); + ay_keypress(&oric->ay, KEYSIM_MASK & current_key->keysim, SDL_TRUE); + modKeyFakePressed[MOD_LSHIFT] = SDL_TRUE; + } + else + { + ay_keypress(&oric->ay, KEYSIM_MASK & current_key->keysim, SDL_TRUE); + } + } + break; + case MACH_ORIC1: + case MACH_ORIC1_16K: + case MACH_ATMOS: + default: + ay_keypress(&oric->ay, current_key->keysim, SDL_TRUE); + break; } - current_key = NULL; - break; + // start releasing mod keys if need be + release_keys = SDL_TRUE; + } + } + } + break; - case SDL_KEYUP: - if (defining_key_map) { - SDL_KeyboardEvent *kbd_evt = (SDL_KeyboardEvent *) ev; - add_to_keyboard_mapping( &(oric->keyboard_mapping), kbd_evt->keysym.sym, current_key->keysim ); - do_popup( oric, "Key mapping done."); - defining_key_map = SDL_FALSE; - current_key = NULL; - } - break; + case SDL_MOUSEBUTTONUP: + if((current_key == NULL) || (defining_key_map)) + break; - } - return done; + // send the key to the Oric + switch(oric->type) + { + case MACH_PRAVETZ: + if(lshifted || rshifted) + { + ay_keypress(&oric->ay, KEYSIM_MASK & current_key->keysimshifted, SDL_FALSE); + } + else + { + ay_keypress(&oric->ay, KEYSIM_MASK & current_key->keysim, SDL_FALSE); + } + break; + case MACH_ORIC1: + case MACH_ORIC1_16K: + case MACH_ATMOS: + default: + ay_keypress(&oric->ay, current_key->keysim, SDL_FALSE); + break; + } + + current_key = NULL; + break; + + case SDL_KEYUP: + if(defining_key_map) + { + SDL_KeyboardEvent *kbd_evt = (SDL_KeyboardEvent *) ev; + add_to_keyboard_mapping(&(oric->keyboard_mapping), kbd_evt->keysym.sym, current_key->keysim); + do_popup(oric, "Key mapping done."); + defining_key_map = SDL_FALSE; + current_key = NULL; + } + break; + + } + return done; } -void release_sticky_keys() +void release_sticky_keys(void) { - release_keys = SDL_TRUE; + release_keys = SDL_TRUE; } -void add_to_keyboard_mapping( struct keyboard_mapping *map, SDL_COMPAT_KEY host_key, SDL_COMPAT_KEY oric_key ) +void add_to_keyboard_mapping(struct keyboard_mapping *map, SDL_COMPAT_KEY host_key, SDL_COMPAT_KEY oric_key) { - // search for a matching host key - int index = 0; - while (index < map->nb_map) { - if (map->host_keys[index] == host_key) { - // found one: update it - map->oric_keys[index] = oric_key; - return; - } else { - // move through the list - index++; - } + // search for a matching host key + int index = 0; + while(index < map->nb_map) + { + if(map->host_keys[index] == host_key) + { + // found one: update it + map->oric_keys[index] = oric_key; + return; + } + else + { + // move through the list + index++; } - // add a new mapping - map->host_keys[map->nb_map] = host_key; - map->oric_keys[map->nb_map] = oric_key; - map->nb_map++; + } + // add a new mapping + map->host_keys[map->nb_map] = host_key; + map->oric_keys[map->nb_map] = oric_key; + map->nb_map++; } -void reset_keyboard_mapping( struct keyboard_mapping *map ) +void reset_keyboard_mapping(struct keyboard_mapping *map) { - map->nb_map = 0; + map->nb_map = 0; } -SDL_bool save_keyboard_mapping( struct machine *oric, char *filename ) +SDL_bool save_keyboard_mapping(struct machine *oric, char* filename) { - SDL_bool ok = SDL_TRUE; - FILE *f = NULL; + SDL_bool ok = SDL_TRUE; + FILE *f = NULL; - f = fopen(filename, "wt"); - if (!f) - { - msgbox(oric, MSGBOX_OK, "Unable to create keyboard mapping file (1)"); - return SDL_FALSE; - } + f = fopen(filename, "wt"); + if(!f) + { + msgbox(oric, MSGBOX_OK, "Unable to create keyboard mapping file (1)"); + return SDL_FALSE; + } - if (fputs("# SDL_key_symbol_for_host : SDL_key_symbol_for_oric\n", f) < 0) - { - msgbox(oric, MSGBOX_OK, "Unable to write to keyboard mapping file (2)"); - ok = SDL_FALSE; - } - if (ok == SDL_TRUE && fputs("# see http://www.libsdl.org/release/SDL-1.2.15/docs/html/sdlkey.html \n", f) < 0) + if(fputs("# SDL_key_symbol_for_host : SDL_key_symbol_for_oric\n", f) < 0) + { + msgbox(oric, MSGBOX_OK, "Unable to write to keyboard mapping file (2)"); + ok = SDL_FALSE; + } + if(ok == SDL_TRUE && fputs("# see http://www.libsdl.org/release/SDL-1.2.15/docs/html/sdlkey.html \n", f) < 0) + { + msgbox(oric, MSGBOX_OK, "Unable to write to keyboard mapping file (2)"); + ok = SDL_FALSE; + } + + // if we have any definition to save + if(ok == SDL_TRUE && oric->keyboard_mapping.nb_map != 0) + { + int i; + // loop through them + for(i=0; i < oric->keyboard_mapping.nb_map && ok == SDL_TRUE; i++) { - msgbox(oric, MSGBOX_OK, "Unable to write to keyboard mapping file (2)"); + // print them in the file + if(fprintf(f, "%d : %d\n", oric->keyboard_mapping.host_keys[i], oric->keyboard_mapping.oric_keys[i]) < 0) + { + msgbox(oric, MSGBOX_OK, "Unable to write to keyboard mapping file (3)"); ok = SDL_FALSE; + } } + } - // if we have any definition to save - if (ok == SDL_TRUE && oric->keyboard_mapping.nb_map != 0) { - int i; - // loop through them - for(i=0; i < oric->keyboard_mapping.nb_map && ok == SDL_TRUE; i++) { - // print them in the file - if (fprintf(f, "%d : %d\n", oric->keyboard_mapping.host_keys[i], oric->keyboard_mapping.oric_keys[i]) < 0) - { - msgbox(oric, MSGBOX_OK, "Unable to write to keyboard mapping file (3)"); - ok = SDL_FALSE; - } - } - } - - if(fclose(f) == EOF) { - msgbox(oric, MSGBOX_OK, "Unable to close keyboard mapping file (4)"); - ok = SDL_FALSE; - } + if(fclose(f) == EOF) + { + msgbox(oric, MSGBOX_OK, "Unable to close keyboard mapping file (4)"); + ok = SDL_FALSE; + } - return ok; + return ok; } -SDL_bool load_keyboard_mapping( struct machine *oric, char *filename ) +SDL_bool load_keyboard_mapping(struct machine *oric, char* filename) { - SDL_bool ok = SDL_TRUE; - FILE *f = NULL; - char buf[4096]; - int host_key, oric_key; + SDL_bool ok = SDL_TRUE; + FILE *f = NULL; + char buf[4096]; + int host_key, oric_key; - f = fopen(filename, "rt"); - if (!f) - { - msgbox(oric, MSGBOX_OK, "Unable to read keyboard mapping file (1)"); - return SDL_FALSE; - } + f = fopen(filename, "rt"); + if(!f) + { + msgbox(oric, MSGBOX_OK, "Unable to read keyboard mapping file (1)"); + return SDL_FALSE; + } - // first reset the mapping - reset_keyboard_mapping(&(oric->keyboard_mapping)); - - // while we are not finished reading the file - while (!feof(f) && !ferror(f)) { - // if we can read something - if (fgets(buf, 4096, f)>0) { - // if it's not a comment - if (buf[0] != '#') { - // if we can read a definition - if (sscanf(buf, "%d : %d", &host_key, &oric_key)==2) { - // add it to the keyboard mapping - add_to_keyboard_mapping( &(oric->keyboard_mapping), host_key, oric_key); - } - } + // first reset the mapping + reset_keyboard_mapping(&(oric->keyboard_mapping)); + + // while we are not finished reading the file + while(!feof(f) && !ferror(f)) + { + // if we can read something + if(fgets(buf, 4096, f)>0) + { + // if it's not a comment + if(buf[0] != '#') + { + // if we can read a definition + if(sscanf(buf, "%d : %d", &host_key, &oric_key)==2) + { + // add it to the keyboard mapping + add_to_keyboard_mapping(&(oric->keyboard_mapping), host_key, oric_key); } + } } + } - if(ferror(f)) { - msgbox(oric, MSGBOX_OK, "Problem while reading from keyboard mapping file (2)"); - ok = SDL_FALSE; - } + if(ferror(f)) + { + msgbox(oric, MSGBOX_OK, "Problem while reading from keyboard mapping file (2)"); + ok = SDL_FALSE; + } - if (ok == SDL_TRUE && sprintf(buf, "Read %d key mappings", oric->keyboard_mapping.nb_map) > 0) - do_popup(oric, buf); + if(ok == SDL_TRUE && sprintf(buf, "Read %d key mappings", oric->keyboard_mapping.nb_map) > 0) + do_popup(oric, buf); + + if(fclose(f) == EOF) + { + msgbox(oric, MSGBOX_OK, "Unable to close keyboard mapping file (3)"); + ok = SDL_FALSE; + } + + return ok; +} - if(fclose(f) == EOF) { - msgbox(oric, MSGBOX_OK, "Unable to close keyboard mapping file (3)"); - ok = SDL_FALSE; - } - return ok; +#ifdef __ANDROID__ +extern struct osdmenuitem keopitems[]; +void togglekeyboard(struct machine *oric, struct osdmenuitem *mitem, int dummy); +void android_togglekeyboard(struct machine* oric) +{ + togglekeyboard(oric, &keopitems[0], 0); } +#endif diff --git a/keyboard.h b/keyboard.h index e80d8d6b..fbe04a3c 100644 --- a/keyboard.h +++ b/keyboard.h @@ -39,18 +39,22 @@ struct keyboard_mapping }; -int kbd_init( struct machine *oric ); +int kbd_init(struct machine *oric); -SDL_bool keyboard_event( SDL_Event *ev, struct machine *oric, SDL_bool *needrender ); +SDL_bool keyboard_event(SDL_Event *ev, struct machine *oric, SDL_bool *needrender); -void release_sticky_keys(); +void release_sticky_keys(void); -void add_to_keyboard_mapping( struct keyboard_mapping *map, SDL_COMPAT_KEY host_key, SDL_COMPAT_KEY oric_key ); +void add_to_keyboard_mapping(struct keyboard_mapping *map, SDL_COMPAT_KEY host_key, SDL_COMPAT_KEY oric_key); -void reset_keyboard_mapping( struct keyboard_mapping *map ); +void reset_keyboard_mapping(struct keyboard_mapping *map); -SDL_bool save_keyboard_mapping( struct machine *oric, char *filename ); +SDL_bool save_keyboard_mapping(struct machine *oric, char* filename); -SDL_bool load_keyboard_mapping( struct machine *oric, char *filename ); +SDL_bool load_keyboard_mapping(struct machine *oric, char* filename); + +#ifdef __ANDROID__ +void android_togglekeyboard(struct machine* oric); +#endif #endif diff --git a/machine.c b/machine.c index 7a66a7cb..00b7b0e5 100644 --- a/machine.c +++ b/machine.c @@ -46,6 +46,8 @@ #include "plugins/ch376/ch376.h" #include "plugins/ch376/oric_ch376_plugin.h" +#include "plugins/twilighte_board/oric_twilighte_board_plugin.h" + #include "machine.h" #include "avi.h" #include "filereq.h" @@ -60,11 +62,11 @@ extern char diskpath[], diskfile[], filetmp[]; extern char telediskpath[], telediskfile[]; extern char pravdiskpath[], pravdiskfile[]; extern SDL_bool refreshstatus, refreshavi; -extern int g_menu_scheme; // #InfoBadDesign - init g_menu_scheme should be done elsewhere - machine.c should not depend on gui - but this is the only place I know char atmosromfile[1024]; char oric1romfile[1024]; char mdiscromfile[1024]; +char bd500romfile[1024]; char jasmnromfile[1024]; char pravetzromfile[2][1024]; char telebankfiles[8][1024]; @@ -76,9 +78,9 @@ int vidcapcount = 0; char screencapname[128]; int screencapcount = 0; -unsigned char rom_microdisc[8912], rom_jasmin[2048], rom_pravetz[512]; -struct symboltable sym_microdisc, sym_jasmin, sym_pravetz; -SDL_bool microdiscrom_valid, jasminrom_valid, pravetzrom_valid; +unsigned char rom_microdisc[8912], rom_bd500[8912], rom_jasmin[2048], rom_pravetz[512]; +struct symboltable sym_microdisc, sym_bd500, sym_jasmin, sym_pravetz; +SDL_bool microdiscrom_valid, bd500rom_valid, jasminrom_valid, pravetzrom_valid; extern struct osdmenuitem mainitems[]; Uint8 oricpalette[] = { 0x00, 0x00, 0x00, @@ -88,58 +90,59 @@ Uint8 oricpalette[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xff, 0x00, 0xff, 0xff, - 0xff, 0xff, 0xff }; + 0xff, 0xff, 0xff + }; static Uint8 sedoric_detect[] = - { - 0xfb, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x53, 0x45, 0x44, 0x4f, 0x52, 0x49, 0x43, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - }; +{ + 0xfb, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x53, 0x45, 0x44, 0x4f, 0x52, 0x49, 0x43, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +}; static Uint8 stratsed_detect[] = - { - 0xfb, 0x00, 0x11, 0x2c, 0x00, 0xd4, 0xa9, 0x00, 0x00, 0x52, 0xa9, 0x00, 0x8d, 0x0f, 0x05, 0x8d, - 0x49, 0x05, 0xa9, 0x4c, 0xa0, 0x00, 0xa2, 0xd4, 0x8d, 0x4f, 0x05, 0x8c, 0x50, 0x05, 0x8e, 0x51, - 0x05, 0xa2, 0x03, 0xec, 0x0c, 0x02, 0xd0, 0x03, 0xa9, 0x02, 0x2c, 0xa9, 0x00, 0x9d, 0x09, 0x05, - }; +{ + 0xfb, 0x00, 0x11, 0x2c, 0x00, 0xd4, 0xa9, 0x00, 0x00, 0x52, 0xa9, 0x00, 0x8d, 0x0f, 0x05, 0x8d, + 0x49, 0x05, 0xa9, 0x4c, 0xa0, 0x00, 0xa2, 0xd4, 0x8d, 0x4f, 0x05, 0x8c, 0x50, 0x05, 0x8e, 0x51, + 0x05, 0xa2, 0x03, 0xec, 0x0c, 0x02, 0xd0, 0x03, 0xa9, 0x02, 0x2c, 0xa9, 0x00, 0x9d, 0x09, 0x05, +}; static Uint8 ftdos_detect[] = - { - 0xfb, 0x78, 0xa9, 0x7f, 0x8d, 0x0e, 0x03, 0xa9, 0x01, 0x8d, 0xfa, 0x03, 0xa9, 0x00, 0x8d, 0xfb, - 0x03, 0x85, 0x04, 0x8d, 0xf4, 0x03, 0xa2, 0x02, 0xac, 0x30, 0x02, 0xc0, 0x40, 0xd0, 0x04, 0xa9, - 0x04, 0xa2, 0x06, 0x85, 0x01, 0x8e, 0x53, 0x04, 0xa9, 0xac, 0x8d, 0xfe, 0xff, 0xa9, 0x04, 0x8d, - }; +{ + 0xfb, 0x78, 0xa9, 0x7f, 0x8d, 0x0e, 0x03, 0xa9, 0x01, 0x8d, 0xfa, 0x03, 0xa9, 0x00, 0x8d, 0xfb, + 0x03, 0x85, 0x04, 0x8d, 0xf4, 0x03, 0xa2, 0x02, 0xac, 0x30, 0x02, 0xc0, 0x40, 0xd0, 0x04, 0xa9, + 0x04, 0xa2, 0x06, 0x85, 0x01, 0x8e, 0x53, 0x04, 0xa9, 0xac, 0x8d, 0xfe, 0xff, 0xa9, 0x04, 0x8d, +}; static Uint8 ftdos_master_detect[] = - { - 0xfb, 0xea, 0x78, 0xa9, 0x7f, 0x8d, 0x0e, 0x03, 0xa9, 0x01, 0x8d, 0xfa, 0x03, 0xa9, 0x00, 0x8d, - 0xfb, 0x03, 0x85, 0x04, 0x85, 0x01, 0x8d, 0xf4, 0x03, 0xa9, 0xab, 0x8d, 0xfe, 0xff, 0xa9, 0x04, - 0x8d, 0xff, 0xff, 0x8d, 0x39, 0x04, 0x8d, 0x48, 0x04, 0x8d, 0x66, 0x04, 0xa9, 0x03, 0x85, 0x02, - }; +{ + 0xfb, 0xea, 0x78, 0xa9, 0x7f, 0x8d, 0x0e, 0x03, 0xa9, 0x01, 0x8d, 0xfa, 0x03, 0xa9, 0x00, 0x8d, + 0xfb, 0x03, 0x85, 0x04, 0x85, 0x01, 0x8d, 0xf4, 0x03, 0xa9, 0xab, 0x8d, 0xfe, 0xff, 0xa9, 0x04, + 0x8d, 0xff, 0xff, 0x8d, 0x39, 0x04, 0x8d, 0x48, 0x04, 0x8d, 0x66, 0x04, 0xa9, 0x03, 0x85, 0x02, +}; -int detect_image_type(char *filename) +int detect_image_type(char* filename) { FILE *f; size_t size; unsigned char tmp[6400]; f = fopen(filename, "rb"); - if (!f) + if(!f) return IMG_I_DUNNO; fseek(f, 0, SEEK_END); size = ftell(f); fseek(f, 0, SEEK_SET); - if (1 != fread(tmp, 8, 1, f)) + if(1 != fread(tmp, 8, 1, f)) { fclose(f); return IMG_I_DUNNO; } /* Look for tape header */ - if ((memcmp(tmp, "\x16\x16\x16\x16", 4) == 0) || + if((memcmp(tmp, "\x16\x16\x16\x16", 4) == 0) || (memcmp(tmp, "\x16\x16\x16\x24", 4) == 0) || (memcmp(tmp, "\x16\x16\x24", 3) == 0) || (memcmp(tmp, "RIFF", 4) == 0) || @@ -150,14 +153,14 @@ int detect_image_type(char *filename) } /* Look for snapshot header */ - if (memcmp(tmp, "OSN\x00", 4)==0) + if(memcmp(tmp, "OSN\x00", 4)==0) { fclose(f); return IMG_SNAPSHOT; } /* Look for a microdisc or jasmin disk image */ - if ((size > 20) && (memcmp(tmp, "MFM_DISK", 8)==0)) + if((size > 20) && (memcmp(tmp, "MFM_DISK", 8)==0)) { Uint8 *ptr, *eot; int sectorlen; @@ -171,13 +174,13 @@ int detect_image_type(char *filename) /* Find the first sector */ ptr = tmp; eot = &tmp[6400]; - while (1) + while(1) { // Search for ID mark - while( (ptr= eot) + if(ptr >= eot) { printf("%s: couldn't find track 0 sector 1 in %s\n", __func__, filename); return IMG_I_DUNNO; @@ -191,20 +194,20 @@ int detect_image_type(char *filename) ptr+=7; // Search for data ID - while( (ptr= eot) + while((ptr= eot) { printf("%s: couldn't find track 0 sector 1 in %s (2)\n", __func__, filename); return IMG_I_DUNNO; } // ptr now points to the sector data - if (gotsector) + if(gotsector) break; // Skip this sector ptr += sectorlen+3; - if (ptr >= eot) + if(ptr >= eot) { printf("%s: couldn't find track 0 sector 1 in %s (3)\n", __func__, filename); return IMG_I_DUNNO; @@ -213,18 +216,18 @@ int detect_image_type(char *filename) /* Got track 0, sector 1 */ /* See if we recognise it .. */ - if (sectorlen == 256) + if(sectorlen == 256) { - if (memcmp(ptr, sedoric_detect, sizeof(sedoric_detect))==0) + if(memcmp(ptr, sedoric_detect, sizeof(sedoric_detect))==0) return IMG_ATMOS_MICRODISC; - if (memcmp(ptr, stratsed_detect, sizeof(stratsed_detect))==0) + if(memcmp(ptr, stratsed_detect, sizeof(stratsed_detect))==0) return IMG_TELESTRAT_DISK; - if (memcmp(ptr, ftdos_detect, sizeof(ftdos_detect))==0) + if(memcmp(ptr, ftdos_detect, sizeof(ftdos_detect))==0) return IMG_ATMOS_JASMIN; - if (memcmp(ptr, ftdos_master_detect, sizeof(ftdos_master_detect))==0) + if(memcmp(ptr, ftdos_master_detect, sizeof(ftdos_master_detect))==0) return IMG_ATMOS_JASMIN; } @@ -235,93 +238,113 @@ int detect_image_type(char *filename) fclose(f); /* Maybe its a pravetz disk... */ - if (size == 143360) + if(size == 143360) return IMG_PRAVETZ_DISK; return IMG_I_DUNNO; } // Switch between emulation/monitor/menus etc. -void setemumode( struct machine *oric, struct osdmenuitem *mitem, int mode ) +void setemumode(struct machine *oric, struct osdmenuitem *mitem, int mode) { oric->emu_mode = mode; - switch( mode ) + switch(mode) { case EM_RUNNING: - SDL_COMPAT_EnableKeyRepeat( 0, 0 ); - SDL_COMPAT_EnableUNICODE( SDL_FALSE ); + SDL_COMPAT_EnableKeyRepeat(0, 0); + SDL_COMPAT_EnableUNICODE(SDL_FALSE); oric->ay.soundon = soundavailable && soundon && (!warpspeed); - if( oric->ay.soundon ) + if(oric->ay.soundon) { - ay_flushlog( &oric->ay ); - SDL_PauseAudio( 0 ); + ay_flushlog(&oric->ay); + SDL_PauseAudio(0); } - ula_set_dirty( oric ); + ula_set_dirty(oric); break; case EM_MENU: - if( vidcap ) avi_close( &vidcap ); - gotomenu( oric, NULL, 0 ); - SDL_COMPAT_EnableKeyRepeat( SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL ); - SDL_COMPAT_EnableUNICODE( SDL_TRUE ); + if(vidcap) avi_close(&vidcap); + gotomenu(oric, NULL, 0); + SDL_COMPAT_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL); + SDL_COMPAT_EnableUNICODE(SDL_TRUE); oric->ay.soundon = SDL_FALSE; - if( soundavailable ) - SDL_PauseAudio( 1 ); + if(soundavailable) + SDL_PauseAudio(1); break; - +#ifndef WWW_NO_MONITOR case EM_DEBUG: - if( vidcap ) avi_close( &vidcap ); - mon_enter( oric ); - SDL_COMPAT_EnableKeyRepeat( SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL ); - SDL_COMPAT_EnableUNICODE( SDL_TRUE ); + if(vidcap) avi_close(&vidcap); + mon_enter(oric); + SDL_COMPAT_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL); + SDL_COMPAT_EnableUNICODE(SDL_TRUE); oric->ay.soundon = SDL_FALSE; - if( soundavailable ) - SDL_PauseAudio( 1 ); + if(soundavailable) + SDL_PauseAudio(1); break; +#endif } } -void setromon( struct machine *oric ) +void setromon(struct machine *oric) { // Determine if the ROM is currently active oric->romon = SDL_TRUE; - if( oric->drivetype == DRV_JASMIN ) + if(oric->drivetype == DRV_JASMIN) { - if( oric->jasmin.olay == 0 ) + if(oric->jasmin.olay == 0) { oric->romon = !oric->romdis; - } else { + } + else + { oric->romon = SDL_FALSE; } } - else if( oric->drivetype == DRV_PRAVETZ ) + else if(oric->drivetype == DRV_PRAVETZ) { oric->romon = !oric->pravetz.olay; } - else if ( oric->type == MACH_TELESTRAT ) + else if(oric->type == MACH_TELESTRAT) + { + oric->romon = (oric->tele_banktype == TELEBANK_ROM); + } + else { - oric->romon = ( oric->tele_banktype == TELEBANK_ROM ); - } else { oric->romon = !oric->romdis; } } // Oric Atmos CPU write -void atmoswrite( struct m6502 *cpu, unsigned short addr, unsigned char data ) +void atmoswrite(struct m6502 *cpu, unsigned short addr, unsigned char data) { struct machine *oric = (struct machine *)cpu->userdata; - if( ( !oric->romdis ) && ( addr >= 0xc000 ) ) return; // Can't write to ROM! - if( ( addr & 0xff00 ) == 0x0300 ) + + + if(oric->twilighteboard_activated && addr >= 0xc000) + twilighteboard_oric_ROM_RAM_write(oric->twilighte,addr-0xc000,data); + else if((!oric->romdis) && (addr >= 0xc000)) return; // Can't write to ROM! + + if((addr & 0xff00) == 0x0300) { - if( oric->aciabackend && ( oric->aciaoffset <= addr && addr < oric->aciaoffset+4 ) ) - acia_write( &oric->tele_acia, addr, data ); + if(oric->aciabackend && (oric->aciaoffset <= addr && addr < oric->aciaoffset+4)) + acia_write(&oric->tele_acia, addr, data); - else if( oric->ch376_activated && ( 0x340 <= addr ) && ( addr < 0x342 ) ) + else if(oric->ch376_activated && (0x340 <= addr) && (addr < 0x342)) ch376_oric_write(oric->ch376, addr, data); + else if(oric->twilighteboard_activated && ((0x342 <= addr && addr < 0x344) || (0x320 <= addr && addr < 0x330))) + twilighteboard_oric_write(oric->twilighte,addr,0x00,data); + + else if(oric->twilighteboard_activated && oric->twilighte->microdisc==SDL_TRUE && (0x310 <= addr && addr < 0x319)) + { + if(addr==0x314) + twilighteboard_oric_write(oric->twilighte,addr,0x00,data); + microdisc_write(&oric->md, addr, data); + } + else - via_write( &oric->via, addr, data ); + via_write(&oric->via, addr, data); return; } @@ -329,20 +352,20 @@ void atmoswrite( struct m6502 *cpu, unsigned short addr, unsigned char data ) } // Oric-1 16k CPU write -void o16kwrite( struct m6502 *cpu, unsigned short addr, unsigned char data ) +void o16kwrite(struct m6502 *cpu, unsigned short addr, unsigned char data) { struct machine *oric = (struct machine *)cpu->userdata; - if( ( !oric->romdis ) && ( addr >= 0xc000 ) ) return; // Can't write to ROM! - if( ( addr & 0xff00 ) == 0x0300 ) + if((!oric->romdis) && (addr >= 0xc000)) return; // Can't write to ROM! + if((addr & 0xff00) == 0x0300) { - if( oric->aciabackend && ( oric->aciaoffset <= addr && addr < oric->aciaoffset+4 ) ) - acia_write( &oric->tele_acia, addr, data ); + if(oric->aciabackend && (oric->aciaoffset <= addr && addr < oric->aciaoffset+4)) + acia_write(&oric->tele_acia, addr, data); - else if( oric->ch376_activated && ( 0x340 <= addr ) && ( addr < 0x342 ) ) + else if(oric->ch376_activated && (0x340 <= addr) && (addr < 0x342)) ch376_oric_write(oric->ch376, addr, data); else - via_write( &oric->via, addr, data ); + via_write(&oric->via, addr, data); return; } @@ -351,54 +374,53 @@ void o16kwrite( struct m6502 *cpu, unsigned short addr, unsigned char data ) } // Oric Telestrat CPU write -void telestratwrite( struct m6502 *cpu, unsigned short addr, unsigned char data ) +void telestratwrite(struct m6502 *cpu, unsigned short addr, unsigned char data) { struct machine *oric = (struct machine *)cpu->userdata; - if( addr >= 0xc000 ) + if(addr >= 0xc000) { -// if( oric->romdis ) -// { -// if( ( oric->md.diskrom ) && ( addr >= 0xe000 ) ) return; // Can't write to ROM! -// } else { - switch( oric->tele_banktype ) - { - case TELEBANK_HALFNHALF: - if( addr >= 0xe000 ) break; - case TELEBANK_RAM: - oric->rom[addr-0xc000] = data; - break; - } - return; -// } + // if( oric->romdis ) + // { + // if( ( oric->md.diskrom ) && ( addr >= 0xe000 ) ) return; // Can't write to ROM! + // } else { + switch(oric->tele_banktype) + { + case TELEBANK_HALFNHALF: + if(addr >= 0xe000) break; + case TELEBANK_RAM: + oric->rom[addr-0xc000] = data; + break; + } + return; + // } } - if( ( addr & 0xff00 ) == 0x0300 ) + if((addr & 0xff00) == 0x0300) { - switch( addr & 0x0f0 ) + switch(addr & 0x0f0) { - case 0x20: - via_write( &oric->tele_via, addr, data ); + via_write(&oric->tele_via, addr, data); break; case 0x10: - if( addr >= 0x31c ) - acia_write( &oric->tele_acia, addr, data ); + if(addr >= 0x31c) + acia_write(&oric->tele_acia, addr, data); else - microdisc_write( &oric->md, addr, data ); + microdisc_write(&oric->md, addr, data); break; case 0x40: - if (oric->ch376_activated) + if(oric->ch376_activated) { - if (addr == 0x340 || addr == 0x341) + if(addr == 0x340 || addr == 0x341) ch376_oric_write(oric->ch376, addr, data); break; } default: - via_write( &oric->via, addr, data ); + via_write(&oric->via, addr, data); break; } return; @@ -408,33 +430,35 @@ void telestratwrite( struct m6502 *cpu, unsigned short addr, unsigned char data } // Oric Atmos + jasmin -void jasmin_atmoswrite( struct m6502 *cpu, unsigned short addr, unsigned char data ) +void jasmin_atmoswrite(struct m6502 *cpu, unsigned short addr, unsigned char data) { struct machine *oric = (struct machine *)cpu->userdata; - if( oric->jasmin.olay == 0 ) + if(oric->jasmin.olay == 0) { - if( oric->romdis ) + if(oric->romdis) { - if( addr >= 0xf800 ) return; // Can't write to jasmin rom - } else { - if( addr >= 0xc000 ) return; // Can't write to BASIC rom + if(addr >= 0xf800) return; // Can't write to jasmin rom + } + else + { + if(addr >= 0xc000) return; // Can't write to BASIC rom } } - if( ( addr & 0xff00 ) == 0x0300 ) + if((addr & 0xff00) == 0x0300) { - if( ( addr >= 0x3f4 ) && ( addr < 0x400 ) ) - jasmin_write( &oric->jasmin, addr, data ); + if((addr >= 0x3f4) && (addr < 0x400)) + jasmin_write(&oric->jasmin, addr, data); - else if( oric->aciabackend && ( oric->aciaoffset <= addr && addr < oric->aciaoffset+4 ) ) - acia_write( &oric->tele_acia, addr, data ); + else if(oric->aciabackend && (oric->aciaoffset <= addr && addr < oric->aciaoffset+4)) + acia_write(&oric->tele_acia, addr, data); - else if( oric->ch376_activated && ( 0x340 <= addr ) && ( addr < 0x342 ) ) + else if(oric->ch376_activated && (0x340 <= addr) && (addr < 0x342)) ch376_oric_write(oric->ch376, addr, data); else - via_write( &oric->via, addr, data ); + via_write(&oric->via, addr, data); return; } @@ -442,33 +466,35 @@ void jasmin_atmoswrite( struct m6502 *cpu, unsigned short addr, unsigned char da } // Oric-1 16k + jasmin -void jasmin_o16kwrite( struct m6502 *cpu, unsigned short addr, unsigned char data ) +void jasmin_o16kwrite(struct m6502 *cpu, unsigned short addr, unsigned char data) { struct machine *oric = (struct machine *)cpu->userdata; - if( oric->jasmin.olay == 0 ) + if(oric->jasmin.olay == 0) { - if( oric->romdis ) + if(oric->romdis) + { + if(addr >= 0xf800) return; // Can't write to jasmin rom + } + else { - if( addr >= 0xf800 ) return; // Can't write to jasmin rom - } else { - if( addr >= 0xc000 ) return; // Can't write to BASIC rom + if(addr >= 0xc000) return; // Can't write to BASIC rom } } - if( ( addr & 0xff00 ) == 0x0300 ) + if((addr & 0xff00) == 0x0300) { - if( ( addr >= 0x3f4 ) && ( addr < 0x400 ) ) - jasmin_write( &oric->jasmin, addr, data ); + if((addr >= 0x3f4) && (addr < 0x400)) + jasmin_write(&oric->jasmin, addr, data); - else if( oric->aciabackend && ( oric->aciaoffset <= addr && addr < oric->aciaoffset+4 ) ) - acia_write( &oric->tele_acia, addr, data ); + else if(oric->aciabackend && (oric->aciaoffset <= addr && addr < oric->aciaoffset+4)) + acia_write(&oric->tele_acia, addr, data); - else if( oric->ch376_activated && ( 0x340 <= addr ) && ( addr < 0x342 ) ) + else if(oric->ch376_activated && (0x340 <= addr) && (addr < 0x342)) ch376_oric_write(oric->ch376, addr, data); else - via_write( &oric->via, addr, data ); + via_write(&oric->via, addr, data); return; } @@ -477,29 +503,63 @@ void jasmin_o16kwrite( struct m6502 *cpu, unsigned short addr, unsigned char dat } // Oric Atmos + microdisc -void microdisc_atmoswrite( struct m6502 *cpu, unsigned short addr, unsigned char data ) +void microdisc_atmoswrite(struct m6502 *cpu, unsigned short addr, unsigned char data) +{ + struct machine *oric = (struct machine *)cpu->userdata; + if(oric->romdis) + { + if((oric->md.diskrom) && (addr >= 0xe000)) return; // Can't write to ROM! + } + else + { + if(addr >= 0xc000) return; + } + + if((addr & 0xff00) == 0x0300) + { + if((addr >= 0x310) && (addr < 0x31c)) + microdisc_write(&oric->md, addr, data); + + else if(oric->aciabackend && (oric->aciaoffset <= addr && addr < oric->aciaoffset+4)) + acia_write(&oric->tele_acia, addr, data); + + else if(oric->ch376_activated && (0x340 <= addr) && (addr < 0x342)) + ch376_oric_write(oric->ch376, addr, data); + + else + via_write(&oric->via, addr, data); + + return; + } + oric->mem[addr] = data; +} + +// Oric Atmos + bd500 +void bd500_atmoswrite(struct m6502 *cpu, unsigned short addr, unsigned char data) { struct machine *oric = (struct machine *)cpu->userdata; - if( oric->romdis ) + if(oric->romdis) + { + if((oric->bd.diskrom) && (addr >= 0xc000)) return; // Can't write to ROM! + } + else { - if( ( oric->md.diskrom ) && ( addr >= 0xe000 ) ) return; // Can't write to ROM! - } else { - if( addr >= 0xc000 ) return; + if(addr >= 0xc000) return; } - if( ( addr & 0xff00 ) == 0x0300 ) + if((addr & 0xff00) == 0x0300) { - if( ( addr >= 0x310 ) && ( addr < 0x31c ) ) - microdisc_write( &oric->md, addr, data ); + if((addr >= 0x310) && (addr < 0x324)) + bd500_write(&oric->bd, addr, data); - else if( oric->aciabackend && ( oric->aciaoffset <= addr && addr < oric->aciaoffset+4 ) ) - acia_write( &oric->tele_acia, addr, data ); + else if(oric->aciabackend && (oric->aciaoffset <= addr && addr < oric->aciaoffset+4)) + acia_write(&oric->tele_acia, addr, data); - else if( oric->ch376_activated && ( 0x340 <= addr ) && ( addr < 0x342 ) ) + else if(oric->ch376_activated && (0x340 <= addr) && (addr < 0x342)) ch376_oric_write(oric->ch376, addr, data); else - via_write( &oric->via, addr, data ); + via_write(&oric->via, addr, data); return; } @@ -507,29 +567,63 @@ void microdisc_atmoswrite( struct m6502 *cpu, unsigned short addr, unsigned char } // Oric-1 16k + microdisc -void microdisc_o16kwrite( struct m6502 *cpu, unsigned short addr, unsigned char data ) +void microdisc_o16kwrite(struct m6502 *cpu, unsigned short addr, unsigned char data) +{ + struct machine *oric = (struct machine *)cpu->userdata; + if(oric->romdis) + { + if((oric->md.diskrom) && (addr >= 0xe000)) return; // Can't write to ROM! + } + else + { + if(addr >= 0xc000) return; + } + + if((addr & 0xff00) == 0x0300) + { + if((addr >= 0x310) && (addr < 0x31c)) + microdisc_write(&oric->md, addr, data); + + else if(oric->aciabackend && (oric->aciaoffset <= addr && addr < oric->aciaoffset+4)) + acia_write(&oric->tele_acia, addr, data); + + else if(oric->ch376_activated && (0x340 <= addr) && (addr < 0x342)) + ch376_oric_write(oric->ch376, addr, data); + + else + via_write(&oric->via, addr, data); + + return; + } + oric->mem[addr&0x3fff] = data; +} + +// Oric-1 16k + bd500 +void bd500_o16kwrite(struct m6502 *cpu, unsigned short addr, unsigned char data) { struct machine *oric = (struct machine *)cpu->userdata; - if( oric->romdis ) + if(oric->romdis) { - if( ( oric->md.diskrom ) && ( addr >= 0xe000 ) ) return; // Can't write to ROM! - } else { - if( addr >= 0xc000 ) return; + if((oric->bd.diskrom) && (addr >= 0xc000)) return; // Can't write to ROM! + } + else + { + if(addr >= 0xc000) return; } - if( ( addr & 0xff00 ) == 0x0300 ) + if((addr & 0xff00) == 0x0300) { - if( ( addr >= 0x310 ) && ( addr < 0x31c ) ) - microdisc_write( &oric->md, addr, data ); + if((addr >= 0x310) && (addr < 0x324)) + bd500_write(&oric->bd, addr, data); - else if( oric->aciabackend && ( oric->aciaoffset <= addr && addr < oric->aciaoffset+4 ) ) - acia_write( &oric->tele_acia, addr, data ); + else if(oric->aciabackend && (oric->aciaoffset <= addr && addr < oric->aciaoffset+4)) + acia_write(&oric->tele_acia, addr, data); - else if( oric->ch376_activated && ( 0x340 <= addr ) && ( addr < 0x342 ) ) + else if(oric->ch376_activated && (0x340 <= addr) && (addr < 0x342)) ch376_oric_write(oric->ch376, addr, data); else - via_write( &oric->via, addr, data ); + via_write(&oric->via, addr, data); return; } @@ -537,26 +631,26 @@ void microdisc_o16kwrite( struct m6502 *cpu, unsigned short addr, unsigned char } // Pravetz -void pravetz_atmoswrite( struct m6502 *cpu, unsigned short addr, unsigned char data ) +void pravetz_atmoswrite(struct m6502 *cpu, unsigned short addr, unsigned char data) { struct machine *oric = (struct machine *)cpu->userdata; oric->mem[addr] = data; - if( 0x300 <= addr && addr <= 0x30f ) + if(0x300 <= addr && addr <= 0x30f) { - via_write( &oric->via, addr, data ); + via_write(&oric->via, addr, data); } - else if( 0x310 <= addr && addr <= 0x31f ) + else if(0x310 <= addr && addr <= 0x31f) { - if( oric->aciabackend && oric->pravetz.extension == 0x100 ) - acia_write( &oric->tele_acia, addr, data ); + if(oric->aciabackend && oric->pravetz.extension == 0x100) + acia_write(&oric->tele_acia, addr, data); else - pravetz_write( &oric->pravetz, addr, data ); + pravetz_write(&oric->pravetz, addr, data); } - else if( 0x320 <= addr && addr <= 0x3ff ) + else if(0x320 <= addr && addr <= 0x3ff) { - switch( addr ) + switch(addr) { case 0x380: oric->pravetz.olay = 0; @@ -593,32 +687,37 @@ void pravetz_atmoswrite( struct m6502 *cpu, unsigned short addr, unsigned char d } // VIA is returned as RAM since it isn't ROM -SDL_bool isram( struct machine *oric, unsigned short addr ) +SDL_bool isram(struct machine *oric, unsigned short addr) { - if( addr < 0xc000 ) return SDL_TRUE; + if(addr < 0xc000) return SDL_TRUE; - if( oric->type == MACH_TELESTRAT ) + if(oric->type == MACH_TELESTRAT) { return oric->tele_banktype == TELEBANK_RAM; } - if( !oric->romdis ) return SDL_FALSE; + if(!oric->romdis) return SDL_FALSE; - switch( oric->drivetype ) + switch(oric->drivetype) { case DRV_MICRODISC: - if( !oric->md.diskrom ) return SDL_TRUE; - if( addr >= 0xe000 ) return SDL_FALSE; + if(!oric->md.diskrom) return SDL_TRUE; + if(addr >= 0xe000) return SDL_FALSE; + break; + + case DRV_BD500: + if(!oric->bd.diskrom) return SDL_TRUE; + if(addr >= 0xc000) return SDL_FALSE; break; case DRV_JASMIN: - if( oric->jasmin.olay ) return SDL_TRUE; - if( addr >= 0xf800 ) return SDL_FALSE; + if(oric->jasmin.olay) return SDL_TRUE; + if(addr >= 0xf800) return SDL_FALSE; break; case DRV_PRAVETZ: - if( oric->pravetz.olay ) return SDL_TRUE; - if( addr >= 0xc000 ) return SDL_FALSE; + if(oric->pravetz.olay) return SDL_TRUE; + if(addr >= 0xc000) return SDL_FALSE; break; } @@ -626,250 +725,342 @@ SDL_bool isram( struct machine *oric, unsigned short addr ) } // Oric Atmos CPU read -unsigned char atmosread( struct m6502 *cpu, unsigned short addr ) +unsigned char atmosread(struct m6502 *cpu, unsigned short addr) { struct machine *oric = (struct machine *)cpu->userdata; - if( ( addr & 0xff00 ) == 0x0300 ) + if((addr & 0xff00) == 0x0300) { - if( oric->aciabackend && ( oric->aciaoffset <= addr && addr < oric->aciaoffset+4 ) ) - return acia_read( &oric->tele_acia, addr ); + if(oric->aciabackend && (oric->aciaoffset <= addr && addr < oric->aciaoffset+4)) + return acia_read(&oric->tele_acia, addr); - if( oric->ch376_activated && ( 0x340 <= addr ) && ( addr < 0x342 ) ) + if(oric->ch376_activated && (0x340 <= addr) && (addr < 0x342)) return ch376_oric_read(oric->ch376, addr); - return via_read( &oric->via, addr ); + if(oric->twilighteboard_activated) + { + if((0x342 <= addr && addr < 0x344) || (0x320 <= addr && addr < 0x330)) + return twilighteboard_oric_read(oric->twilighte,addr); + + if(oric->twilighte->microdisc==SDL_TRUE) + { + if(0x310 <= addr && addr < 0x319) + return microdisc_read(&oric->md, addr); + } + + } + + return via_read(&oric->via, addr); } - if( ( !oric->romdis ) && ( addr >= 0xc000 ) ) - return oric->rom[addr-0xc000]; + if((!oric->romdis) && (addr >= 0xc000)) + { + if(oric->twilighteboard_activated) + return twilighteboard_oric_ROM_RAM_read(oric->twilighte,addr-0xc000); + else + return oric->rom[addr-0xc000]; + } return oric->mem[addr]; } // Oric-1 16K CPU read -unsigned char o16kread( struct m6502 *cpu, unsigned short addr ) +unsigned char o16kread(struct m6502 *cpu, unsigned short addr) { struct machine *oric = (struct machine *)cpu->userdata; - if( ( addr & 0xff00 ) == 0x0300 ) + if((addr & 0xff00) == 0x0300) { - if( oric->aciabackend && ( oric->aciaoffset <= addr && addr < oric->aciaoffset+4 ) ) - return acia_read( &oric->tele_acia, addr ); + if(oric->aciabackend && (oric->aciaoffset <= addr && addr < oric->aciaoffset+4)) + return acia_read(&oric->tele_acia, addr); - if( oric->ch376_activated && ( 0x340 <= addr ) && ( addr < 0x342 ) ) + if(oric->ch376_activated && (0x340 <= addr) && (addr < 0x342)) return ch376_oric_read(oric->ch376, addr); - return via_read( &oric->via, addr ); + return via_read(&oric->via, addr); } - if( ( !oric->romdis ) && ( addr >= 0xc000 ) ) + if((!oric->romdis) && (addr >= 0xc000)) return oric->rom[addr-0xc000]; return oric->mem[addr&0x3fff]; } // Oric Telestrat CPU read -unsigned char telestratread( struct m6502 *cpu, unsigned short addr ) +unsigned char telestratread(struct m6502 *cpu, unsigned short addr) { struct machine *oric = (struct machine *)cpu->userdata; - if( ( addr & 0xff00 ) == 0x0300 ) + if((addr & 0xff00) == 0x0300) { - switch( addr & 0x0f0 ) + switch(addr & 0x0f0) { case 0x010: - if( addr >= 0x31c ) + if(addr >= 0x31c) { - return acia_read( &oric->tele_acia, addr ); + return acia_read(&oric->tele_acia, addr); } - return microdisc_read( &oric->md, addr ); + return microdisc_read(&oric->md, addr); case 0x020: - return via_read( &oric->tele_via, addr ); + return via_read(&oric->tele_via, addr); case 0x040: - if (oric->ch376_activated) + if(oric->ch376_activated) { - if (addr == 0x340 || addr == 0x341) + if(addr == 0x340 || addr == 0x341) return ch376_oric_read(oric->ch376, addr); } } - return via_read( &oric->via, addr ); + return via_read(&oric->via, addr); } - if( addr >= 0xc000 ) + if(addr >= 0xc000) { -// if( oric->romdis ) -// { -// if( ( oric->md.diskrom ) && ( addr >= 0xe000 ) ) -// return rom_microdisc[addr-0xe000]; -// } else { - return oric->rom[addr-0xc000]; -// } + // if( oric->romdis ) + // { + // if( ( oric->md.diskrom ) && ( addr >= 0xe000 ) ) + // return rom_microdisc[addr-0xe000]; + // } else { + return oric->rom[addr-0xc000]; + // } } return oric->mem[addr]; } // Oric Atmos + jasmin -unsigned char jasmin_atmosread( struct m6502 *cpu, unsigned short addr ) +unsigned char jasmin_atmosread(struct m6502 *cpu, unsigned short addr) { struct machine *oric = (struct machine *)cpu->userdata; - if( oric->jasmin.olay == 0 ) + if(oric->jasmin.olay == 0) { - if( oric->romdis ) + if(oric->romdis) + { + if(addr >= 0xf800) return rom_jasmin[addr-0xf800]; + } + else { - if( addr >= 0xf800 ) return rom_jasmin[addr-0xf800]; - } else { - if( addr >= 0xc000 ) return oric->rom[addr-0xc000]; + if(addr >= 0xc000) return oric->rom[addr-0xc000]; } } - if( ( addr & 0xff00 ) == 0x0300 ) + if((addr & 0xff00) == 0x0300) { - if( ( addr >= 0x3f4 ) && ( addr < 0x400 ) ) - return jasmin_read( &oric->jasmin, addr ); + if((addr >= 0x3f4) && (addr < 0x400)) + return jasmin_read(&oric->jasmin, addr); - if( oric->aciabackend && ( oric->aciaoffset <= addr && addr < oric->aciaoffset+4 ) ) - return acia_read( &oric->tele_acia, addr ); + if(oric->aciabackend && (oric->aciaoffset <= addr && addr < oric->aciaoffset+4)) + return acia_read(&oric->tele_acia, addr); - if( oric->ch376_activated && ( 0x340 <= addr ) && ( addr < 0x342 ) ) + if(oric->ch376_activated && (0x340 <= addr) && (addr < 0x342)) return ch376_oric_read(oric->ch376, addr); - return via_read( &oric->via, addr ); + return via_read(&oric->via, addr); } return oric->mem[addr]; } // Oric 16k + jasmin -unsigned char jasmin_o16kread( struct m6502 *cpu, unsigned short addr ) +unsigned char jasmin_o16kread(struct m6502 *cpu, unsigned short addr) { struct machine *oric = (struct machine *)cpu->userdata; - if( oric->jasmin.olay == 0 ) + if(oric->jasmin.olay == 0) { - if( oric->romdis ) + if(oric->romdis) + { + if(addr >= 0xf800) return rom_jasmin[addr-0xf800]; + } + else { - if( addr >= 0xf800 ) return rom_jasmin[addr-0xf800]; - } else { - if( addr >= 0xc000 ) return oric->rom[addr-0xc000]; + if(addr >= 0xc000) return oric->rom[addr-0xc000]; } } - if( ( addr & 0xff00 ) == 0x0300 ) + if((addr & 0xff00) == 0x0300) { - if( ( addr >= 0x3f4 ) && ( addr < 0x400 ) ) - return jasmin_read( &oric->jasmin, addr ); + if((addr >= 0x3f4) && (addr < 0x400)) + return jasmin_read(&oric->jasmin, addr); - if( oric->aciabackend && ( oric->aciaoffset <= addr && addr < oric->aciaoffset+4 ) ) - return acia_read( &oric->tele_acia, addr ); + if(oric->aciabackend && (oric->aciaoffset <= addr && addr < oric->aciaoffset+4)) + return acia_read(&oric->tele_acia, addr); - if( oric->ch376_activated && ( 0x340 <= addr ) && ( addr < 0x342 ) ) + if(oric->ch376_activated && (0x340 <= addr) && (addr < 0x342)) return ch376_oric_read(oric->ch376, addr); - return via_read( &oric->via, addr ); + return via_read(&oric->via, addr); } return oric->mem[addr&0x3fff]; } // Oric Atmos + microdisc -unsigned char microdisc_atmosread( struct m6502 *cpu, unsigned short addr ) +unsigned char microdisc_atmosread(struct m6502 *cpu, unsigned short addr) { struct machine *oric = (struct machine *)cpu->userdata; - if( oric->romdis ) + if(oric->romdis) { - if( ( oric->md.diskrom ) && ( addr >= 0xe000 ) ) + if((oric->md.diskrom) && (addr >= 0xe000)) return rom_microdisc[addr-0xe000]; - } else { - if( addr >= 0xc000 ) + } + else + { + if(addr >= 0xc000) + return oric->rom[addr-0xc000]; + } + + if((addr & 0xff00) == 0x0300) + { + if((addr >= 0x310) && (addr < 0x31c)) + return microdisc_read(&oric->md, addr); + + if(oric->aciabackend && (oric->aciaoffset <= addr && addr < oric->aciaoffset+4)) + return acia_read(&oric->tele_acia, addr); + + if(oric->ch376_activated && (0x340 <= addr) && (addr < 0x342)) + return ch376_oric_read(oric->ch376, addr); + + return via_read(&oric->via, addr); + } + + return oric->mem[addr]; +} + +// Oric Atmos + bd500 +unsigned char bd500_atmosread(struct m6502 *cpu, unsigned short addr) +{ + struct machine *oric = (struct machine *)cpu->userdata; + + if(oric->romdis) + { + if((oric->bd.diskrom) && (addr >= 0xe000)) + return rom_bd500[addr-0xe000]; + } + else + { + if(addr >= 0xc000) return oric->rom[addr-0xc000]; } - if( ( addr & 0xff00 ) == 0x0300 ) + if((addr & 0xff00) == 0x0300) { - if( ( addr >= 0x310 ) && ( addr < 0x31c ) ) - return microdisc_read( &oric->md, addr ); + if((addr >= 0x310) && (addr < 0x324)) + return bd500_read(&oric->bd, addr); - if( oric->aciabackend && ( oric->aciaoffset <= addr && addr < oric->aciaoffset+4 ) ) - return acia_read( &oric->tele_acia, addr ); + if(oric->aciabackend && (oric->aciaoffset <= addr && addr < oric->aciaoffset+4)) + return acia_read(&oric->tele_acia, addr); - if( oric->ch376_activated && ( 0x340 <= addr ) && ( addr < 0x342 ) ) + if(oric->ch376_activated && (0x340 <= addr) && (addr < 0x342)) return ch376_oric_read(oric->ch376, addr); - return via_read( &oric->via, addr ); + return via_read(&oric->via, addr); } return oric->mem[addr]; } // Oric-1 16k + microdisc -unsigned char microdisc_o16kread( struct m6502 *cpu, unsigned short addr ) +unsigned char microdisc_o16kread(struct m6502 *cpu, unsigned short addr) { struct machine *oric = (struct machine *)cpu->userdata; - if( oric->romdis ) + if(oric->romdis) { - if( ( oric->md.diskrom ) && ( addr >= 0xe000 ) ) + if((oric->md.diskrom) && (addr >= 0xe000)) return rom_microdisc[addr-0xe000]; - } else { - if( addr >= 0xc000 ) + } + else + { + if(addr >= 0xc000) return oric->rom[addr-0xc000]; } - if( ( addr & 0xff00 ) == 0x0300 ) + if((addr & 0xff00) == 0x0300) { - if( ( addr >= 0x310 ) && ( addr < 0x31c ) ) - return microdisc_read( &oric->md, addr ); + if((addr >= 0x310) && (addr < 0x31c)) + return microdisc_read(&oric->md, addr); - if( oric->aciabackend && ( oric->aciaoffset <= addr && addr < oric->aciaoffset+4 ) ) - return acia_read( &oric->tele_acia, addr ); + if(oric->aciabackend && (oric->aciaoffset <= addr && addr < oric->aciaoffset+4)) + return acia_read(&oric->tele_acia, addr); - if( oric->ch376_activated && ( 0x340 <= addr ) && ( addr < 0x342 ) ) + if(oric->ch376_activated && (0x340 <= addr) && (addr < 0x342)) return ch376_oric_read(oric->ch376, addr); - return via_read( &oric->via, addr ); + return via_read(&oric->via, addr); + } + + return oric->mem[addr&0x3fff]; +} + +// Oric-1 16k + bd500 +unsigned char bd500_o16kread(struct m6502 *cpu, unsigned short addr) +{ + struct machine *oric = (struct machine *)cpu->userdata; + + if(oric->romdis) + { + if((oric->bd.diskrom) && (addr >= 0xe000)) + return rom_bd500[addr-0xe000]; + } + else + { + if(addr >= 0xc000) + return oric->rom[addr-0xc000]; + } + + if((addr & 0xff00) == 0x0300) + { + if((addr >= 0x310) && (addr < 0x324)) + return bd500_read(&oric->bd, addr); + + if(oric->aciabackend && (oric->aciaoffset <= addr && addr < oric->aciaoffset+4)) + return acia_read(&oric->tele_acia, addr); + + if(oric->ch376_activated && (0x340 <= addr) && (addr < 0x342)) + return ch376_oric_read(oric->ch376, addr); + + return via_read(&oric->via, addr); } return oric->mem[addr&0x3fff]; } // Pravetz -unsigned char pravetz_atmosread( struct m6502 *cpu, unsigned short addr ) +unsigned char pravetz_atmosread(struct m6502 *cpu, unsigned short addr) { struct machine *oric = (struct machine *)cpu->userdata; - if( 0x300 == ( addr & 0xfff0 ) ) + if(0x300 == (addr & 0xfff0)) { - return via_read( &oric->via, addr ); + return via_read(&oric->via, addr); } - if( 0x310 == ( addr & 0xfff0 ) ) + if(0x310 == (addr & 0xfff0)) { - if( oric->aciabackend && oric->pravetz.extension == 0x100 ) - return acia_read( &oric->tele_acia, addr ); + if(oric->aciabackend && oric->pravetz.extension == 0x100) + return acia_read(&oric->tele_acia, addr); else - return pravetz_read( &oric->pravetz, addr ); + return pravetz_read(&oric->pravetz, addr); } - if( 0x320 <= addr && addr <= 0x3ff ) + if(0x320 <= addr && addr <= 0x3ff) { - if( pravetzrom_valid ) + if(pravetzrom_valid) { return rom_pravetz[addr - 0x300 + oric->pravetz.extension]; } } - if( 0xc000 <= addr /* 0xFFFF */) + if(0xc000 <= addr /* 0xFFFF */) { - if( !oric->pravetz.olay ) + if(!oric->pravetz.olay) { return oric->rom[addr-0xc000]; } @@ -879,47 +1070,46 @@ unsigned char pravetz_atmosread( struct m6502 *cpu, unsigned short addr ) } /* Wrapper for the above when lightpen is enabled */ -unsigned char lightpen_read( struct m6502 *cpu, unsigned short addr ) +unsigned char lightpen_read(struct m6502 *cpu, unsigned short addr) { struct machine *oric = (struct machine *)cpu->userdata; - if( addr == 0x3e0 ) return oric->lightpenx; - if( addr == 0x3e1 ) return oric->lightpeny; + if(addr == 0x3e0) return oric->lightpenx; + if(addr == 0x3e1) return oric->lightpeny; - return oric->read_not_lightpen( cpu, addr ); + return oric->read_not_lightpen(cpu, addr); } - -static SDL_bool load_rom( struct machine *oric, char *fname, int size, unsigned char *where, struct symboltable *stab, int symflags ) +static SDL_bool load_rom(struct machine *oric, char* fname, int size, unsigned char* where, struct symboltable *stab, int symflags) { SDL_RWops *f; - char *tmpname; + char* tmpname; // MinGW doesn't have asprintf :-( - tmpname = malloc( strlen( fname ) + 10 ); - if( !tmpname ) return SDL_FALSE; + tmpname = malloc(strlen(fname) + 10); + if(!tmpname) return SDL_FALSE; - sprintf( tmpname, "%s.rom", fname ); - f = SDL_RWFromFile( tmpname, "rb" ); - if( !f ) + sprintf(tmpname, "%s.rom", fname); + f = SDL_RWFromFile(tmpname, "rb"); + if(!f) { - error_printf( "Unable to open '%s'\n", tmpname ); - free( tmpname ); + error_printf("Unable to open '%s'\n", tmpname); + free(tmpname); return SDL_FALSE; } - if( size < 0 ) + if(size < 0) { int filesize; - SDL_RWseek( f, 0, SEEK_END ); - filesize = SDL_RWtell( f ); - SDL_RWseek( f, 0, SEEK_SET ); + SDL_RWseek(f, 0, SEEK_END); + filesize = SDL_RWtell(f); + SDL_RWseek(f, 0, SEEK_SET); - if( filesize > -size ) + if(filesize > -size) { - error_printf( "ROM '%s' exceeds %d bytes.\n", fname, -size ); - SDL_RWclose( f ); - free( tmpname ); + error_printf("ROM '%s' exceeds %d bytes.\n", fname, -size); + SDL_RWclose(f); + free(tmpname); return SDL_FALSE; } @@ -927,38 +1117,40 @@ static SDL_bool load_rom( struct machine *oric, char *fname, int size, unsigned size = filesize; } - if( SDL_RWread( f, where, size, 1 ) != 1 ) + if(SDL_RWread(f, where, size, 1) != 1) { - error_printf( "Unable to read '%s'\n", tmpname ); - SDL_RWclose( f ); - free( tmpname ); + error_printf("Unable to read '%s'\n", tmpname); + SDL_RWclose(f); + free(tmpname); return SDL_FALSE; } - SDL_RWclose( f ); - - sprintf( tmpname, "%s.sym", fname ); - mon_new_symbols( stab, oric, tmpname, symflags, SDL_FALSE, SDL_FALSE ); - free( tmpname ); + SDL_RWclose(f); +#ifndef WWW_NO_MONITOR + sprintf(tmpname, "%s.sym", fname); + mon_new_symbols(stab, oric, tmpname, symflags, SDL_FALSE, SDL_FALSE); + free(tmpname); +#endif return SDL_TRUE; } -void preinit_machine( struct machine *oric ) +void preinit_machine(struct machine *oric) { int i; - - mon_init_symtab( &sym_microdisc ); - mon_init_symtab( &sym_jasmin ); - mon_init_symtab( &oric->romsyms ); - mon_init_symtab( &oric->tele_banksyms[0] ); - mon_init_symtab( &oric->tele_banksyms[1] ); - mon_init_symtab( &oric->tele_banksyms[2] ); - mon_init_symtab( &oric->tele_banksyms[3] ); - mon_init_symtab( &oric->tele_banksyms[4] ); - mon_init_symtab( &oric->tele_banksyms[5] ); - mon_init_symtab( &oric->tele_banksyms[6] ); - mon_init_symtab( &oric->tele_banksyms[7] ); +#ifndef WWW_NO_MONITOR + mon_init_symtab(&sym_microdisc); + mon_init_symtab(&sym_jasmin); + mon_init_symtab(&oric->romsyms); + mon_init_symtab(&oric->tele_banksyms[0]); + mon_init_symtab(&oric->tele_banksyms[1]); + mon_init_symtab(&oric->tele_banksyms[2]); + mon_init_symtab(&oric->tele_banksyms[3]); + mon_init_symtab(&oric->tele_banksyms[4]); + mon_init_symtab(&oric->tele_banksyms[5]); + mon_init_symtab(&oric->tele_banksyms[6]); + mon_init_symtab(&oric->tele_banksyms[7]); +#endif oric->mem = NULL; oric->rom = NULL; @@ -991,6 +1183,8 @@ void preinit_machine( struct machine *oric ) oric->tapecap = NULL; oric->tapenoise = SDL_FALSE; oric->rawtape = SDL_FALSE; + oric->rom16 = SDL_TRUE; + oric->dos70 = SDL_FALSE; oric->joy_iface = JOYIFACE_NONE; oric->joymode_a = JOYMODE_KB1; @@ -1009,16 +1203,17 @@ void preinit_machine( struct machine *oric ) oric->kbjoy1[4] = SDLK_KP_ENTER; oric->kbjoy1[5] = SDLK_KP_PLUS; oric->kbjoy1[6] = SDLK_KP_MINUS; - oric->kbjoy2[0] = 'w'; - oric->kbjoy2[1] = 's'; - oric->kbjoy2[2] = 'a'; - oric->kbjoy2[3] = 'd'; - oric->kbjoy2[4] = SDLK_SPACE; - oric->kbjoy2[5] = 'n'; - oric->kbjoy2[5] = SDLK_LALT; + + oric->kbjoy2[0] = 0; + oric->kbjoy2[1] = 0; + oric->kbjoy2[2] = 0; + oric->kbjoy2[3] = 0; + oric->kbjoy2[4] = 0; + oric->kbjoy2[5] = 0; + oric->kbjoy2[6] = 0; oric->drivetype = DRV_NONE; - for( i=0; iwddisk.disk[i] = NULL; oric->diskname[i][0] = 0; @@ -1033,6 +1228,8 @@ void preinit_machine( struct machine *oric ) oric->printenable = SDL_TRUE; oric->printfilter = SDL_TRUE; + oric->dcadjust = SDL_TRUE; + oric->soundloopon = SDL_FALSE; oric->aciabackend = ACIA_TYPE_NONE; oric->aciaoffset = 0x31c; @@ -1044,51 +1241,67 @@ void preinit_machine( struct machine *oric ) oric->define_mapping = SDL_FALSE; oric->sticky_mod_keys = SDL_FALSE; + oric->disable_menuscheme = SDL_FALSE; + oric->pravdiskautoboot = SDL_TRUE; } -void load_diskroms( struct machine *oric ) +void load_diskroms(struct machine *oric) { - microdiscrom_valid = load_rom( oric, mdiscromfile, 8192, rom_microdisc, &sym_microdisc, SYMF_ROMDIS1|SYMF_MICRODISC ); - jasminrom_valid = load_rom( oric, jasmnromfile, 2048, rom_jasmin, &sym_jasmin, SYMF_ROMDIS1|SYMF_JASMIN ); - pravetzrom_valid = load_rom( oric, pravetzromfile[1], 512, rom_pravetz, &sym_pravetz, SYMF_PRAVZ8D ); + microdiscrom_valid = load_rom(oric, mdiscromfile, 8192, rom_microdisc, &sym_microdisc, SYMF_ROMDIS1|SYMF_MICRODISC); + bd500rom_valid = load_rom(oric, bd500romfile, 8192, rom_bd500, &sym_bd500, SYMF_ROMDIS1|SYMF_BD500); + jasminrom_valid = load_rom(oric, jasmnromfile, 2048, rom_jasmin, &sym_jasmin, SYMF_ROMDIS1|SYMF_JASMIN); + pravetzrom_valid = load_rom(oric, pravetzromfile[1], 512, rom_pravetz, &sym_pravetz, SYMF_PRAVZ8D); } // This is currently used to workaround a change in the behaviour of SDL // on OS4, but in future it would be a handy place to fix keyboard layout // issues, such as the problems with a non-uk keymap on linux. // Also helps German keymap on MorphOS. -int mapkey( struct machine *oric, int key ) +int mapkey(struct machine *oric, int key) { - switch( key ) + switch(key) { #if defined(__amigaos4__) || defined(__MORPHOS__) || defined(__AROS__) case '\xF6': - case ':': return ';'; - case '<': return ','; - case '>': return '.'; + case ':': + return ';'; + case '<': + return ','; + case '>': + return '.'; case '\xDF': - case '?': return '/'; + case '?': + return '/'; case '@': case '#': - case '~': return '\''; - case '_': return '-'; - case '+': return '='; + case '~': + return '\''; + case '_': + return '-'; + case '+': + return '='; case '\xE4': - case '{': return '['; + case '{': + return '['; case '\xFC': - case '}': return ']'; - case '^': return '\\'; + case '}': + return ']'; + case '^': + return '\\'; #elif defined(WIN32) - case '<': return '\\'; + case '<': + return '\\'; #endif } - if (oric->keyboard_mapping.nb_map != 0) { + if(oric->keyboard_mapping.nb_map != 0) + { int i; - for(i=0; i < oric->keyboard_mapping.nb_map; i++) { - if (key == oric->keyboard_mapping.host_keys[i]) - return oric->keyboard_mapping.oric_keys[i]; + for(i=0; i < oric->keyboard_mapping.nb_map; i++) + { + if(key == oric->keyboard_mapping.host_keys[i]) + return oric->keyboard_mapping.oric_keys[i]; } } @@ -1096,11 +1309,11 @@ int mapkey( struct machine *oric, int key ) } static SDL_bool lightpendown = SDL_FALSE; -void move_lightpen( struct machine *oric, int x, int y ) +void move_lightpen(struct machine *oric, int x, int y) { - if (!lightpendown) return; + if(!lightpendown) return; - if ((oric->rendermode == RENDERMODE_SW) || (!oric->hstretch)) + if((oric->rendermode == RENDERMODE_SW) || (!oric->hstretch)) { x = (x-80)/2; if(oric->rendermode == RENDERMODE_GL && oric->aratio && oric->vid_freq) @@ -1118,9 +1331,9 @@ void move_lightpen( struct machine *oric, int x, int y ) y = (y-14)/2; } - if ((x>=0) && (x<240) && (y>=0) && (y<224)) + if((x>=0) && (x<240) && (y>=0) && (y<224)) { - if (oric->scr[y*240+x] != 0) + if(oric->scr[y*240+x] != 0) { oric->lightpenx = (x+219)&0xff; oric->lightpeny = (y+54)&0xff; @@ -1129,50 +1342,62 @@ void move_lightpen( struct machine *oric, int x, int y ) } static SDL_bool shifted = SDL_FALSE; -SDL_bool emu_event( SDL_Event *ev, struct machine *oric, SDL_bool *needrender ) +SDL_bool emu_event(SDL_Event *ev, struct machine *oric, SDL_bool *needrender) { Sint32 i; - if( joy_filter_event( ev, oric ) ) + if(joy_filter_event(ev, oric)) return SDL_FALSE; -// char stmp[32]; - switch( ev->type ) + // char stmp[32]; + switch(ev->type) { case SDL_MOUSEBUTTONDOWN: - switch (ev->button.button) + switch(ev->button.button) { case SDL_BUTTON_LEFT: lightpendown = SDL_TRUE; - move_lightpen( oric, ev->button.x, ev->button.y ); + move_lightpen(oric, ev->button.x, ev->button.y); break; case SDL_BUTTON_RIGHT: - setemumode( oric, NULL, EM_MENU ); + setemumode(oric, NULL, EM_MENU); *needrender = SDL_TRUE; break; } break; - case SDL_MOUSEBUTTONUP: - if( ev->button.button == SDL_BUTTON_LEFT ) + if(ev->button.button == SDL_BUTTON_LEFT) lightpendown = SDL_FALSE; break; case SDL_MOUSEMOTION: - move_lightpen( oric, ev->motion.x, ev->motion.y ); + move_lightpen(oric, ev->motion.x, ev->motion.y); break; +#ifdef WWW + case SDL_MULTIGESTURE: + { + SDL_MultiGestureEvent *m = (SDL_MultiGestureEvent*)ev; + if(m->numFingers == 2) + { + setemumode(oric, NULL, EM_MENU); + *needrender = SDL_TRUE; + } + break; + } +#endif + case SDL_KEYUP: - switch( ev->key.keysym.sym ) + switch(ev->key.keysym.sym) { case SDLK_F1: - setemumode( oric, NULL, EM_MENU ); + setemumode(oric, NULL, EM_MENU); *needrender = SDL_TRUE; break; case SDLK_F2: - setemumode( oric, NULL, EM_DEBUG ); + setemumode(oric, NULL, EM_DEBUG); *needrender = SDL_TRUE; break; @@ -1181,33 +1406,59 @@ SDL_bool emu_event( SDL_Event *ev, struct machine *oric, SDL_bool *needrender ) break; case SDLK_F4: - if( ( shifted ) && ( oric->drivetype == DRV_JASMIN ) ) - oric->cpu.write( &oric->cpu, 0x3fb, 1 ); // ROMDIS - if( oric->drivetype == DRV_MICRODISC ) + if((shifted) && (oric->drivetype == DRV_JASMIN)) + { + // ROMDIS + oric->cpu.write(&oric->cpu, 0x3fb, 1); + } + if(oric->drivetype == DRV_MICRODISC) + { + oric->romdis = SDL_TRUE; + microdisc_init(&oric->md, &oric->wddisk, oric); + } + else if(oric->drivetype == DRV_BD500) { oric->romdis = SDL_TRUE; - microdisc_init( &oric->md, &oric->wddisk, oric ); + bd500_init(&oric->bd, &oric->wddisk, oric); } - else if( oric->drivetype == DRV_PRAVETZ ) + else if(oric->drivetype == DRV_PRAVETZ) { oric->pravetz.olay = 0; oric->pravetz.romdis = 1; oric->pravetz.extension = 0; oric->romdis = !oric->pravetz.romdis; } - setromon( oric ); - m6502_reset( &oric->cpu ); - via_init( &oric->via, oric, VIA_MAIN ); - via_init( &oric->tele_via, oric, VIA_TELESTRAT ); - acia_init( &oric->tele_acia, oric ); + setromon(oric); + m6502_reset(&oric->cpu); + via_init(&oric->via, oric, VIA_MAIN); + via_init(&oric->tele_via, oric, VIA_TELESTRAT); + acia_init(&oric->tele_acia, oric); + + if(oric->twilighteboard_activated) + { + oric->ch376_activated=SDL_TRUE; + oric->twilighte=twilighte_oric_init(); + if(oric->twilighte->microdisc==SDL_TRUE) + { + oric->drivetype = DRV_MICRODISC; + oric->disksyms = NULL; + microdisc_init(&oric->md, &oric->wddisk, oric); + } + } + + if(oric->twilighte==NULL) + { + oric->twilighteboard_activated=SDL_FALSE; + } + else + oric->ch376_activated=SDL_TRUE; - if (oric->ch376_activated) + if(oric->ch376_activated) { oric->ch376 = ch376_oric_init(); - if (oric->ch376 != NULL) + if(oric->ch376 != NULL) ch376_oric_config(oric->ch376); } - break; case SDLK_F5: @@ -1218,38 +1469,31 @@ SDL_bool emu_event( SDL_Event *ev, struct machine *oric, SDL_bool *needrender ) break; case SDLK_F6: - if( vidcap ) - { - warpspeed = SDL_FALSE; - } - else - { - warpspeed = warpspeed ? SDL_FALSE : SDL_TRUE; - } + warpspeed = (vidcap || warpspeed)? SDL_FALSE : SDL_TRUE; - if( soundavailable && soundon ) + if(soundavailable && soundon) { - ay_flushlog( &oric->ay ); + ay_flushlog(&oric->ay); oric->ay.soundon = !warpspeed; - SDL_PauseAudio( warpspeed ); + SDL_PauseAudio(warpspeed); } break; case SDLK_F7: - if( oric->drivetype == DRV_NONE ) break; + if(oric->drivetype == DRV_NONE) break; - for( i=0; i<4; i++ ) + for(i=0; i<4; i++) { - if( ( oric->wddisk.disk[i] ) && ( oric->wddisk.disk[i]->modified ) ) + if((oric->wddisk.disk[i]) && (oric->wddisk.disk[i]->modified)) { - if( shifted ) + if(shifted) { char frname[64]; - char *dpath, *dfile; + char* dpath, *dfile; - if( oric->type != MACH_TELESTRAT ) + if(oric->type != MACH_TELESTRAT) { - switch (oric->drivetype) + switch(oric->drivetype) { case DRV_PRAVETZ: dpath = pravdiskpath; @@ -1261,105 +1505,114 @@ SDL_bool emu_event( SDL_Event *ev, struct machine *oric, SDL_bool *needrender ) dfile = diskfile; break; } - } else { + } + else + { dpath = telediskpath; dfile = telediskfile; } - sprintf( frname, "Save disk %d", i ); - if( filerequester( oric, frname, dpath, dfile, FR_DISKSAVE ) ) + sprintf(frname, "Save disk %d", i); + if(filerequester(oric, frname, dpath, dfile, FR_DISKSAVE)) { - joinpath( dpath, dfile ); - diskimage_save( oric, filetmp, i ); + joinpath(dpath, dfile); + diskimage_save(oric, filetmp, i); } - } else { - diskimage_save( oric, oric->wddisk.disk[i]->filename, i ); + } + else + { + diskimage_save(oric, oric->wddisk.disk[i]->filename, i); } } } break; case SDLK_F8: - togglefullscreen( oric, NULL, 0 ); + togglefullscreen(oric, NULL, 0); break; case SDLK_F9: - toggletapecap( oric, find_item_by_function(mainitems, toggletapecap), 0 ); + toggletapecap(oric, find_item_by_function(mainitems, toggletapecap), 0); break; case SDLK_F10: - if( vidcap ) - { - ay_lockaudio( &oric->ay ); - avi_close( &vidcap ); - ay_unlockaudio( &oric->ay ); - do_popup( oric, "AVI capture stopped" ); - refreshavi = SDL_TRUE; - break; - } - - sprintf( vidcapname, "Capturing to video%02d.avi", vidcapcount ); - warpspeed = SDL_FALSE; - ay_lockaudio( &oric->ay ); - vidcap = avi_open( &vidcapname[13], oricpalette, soundavailable&&soundon, oric->vid_freq ); - ay_unlockaudio( &oric->ay ); - if( vidcap ) - { - vidcapcount++; - do_popup( oric, vidcapname ); - } - refreshavi = SDL_TRUE; - break; +#ifndef __ANDROID__ + if(vidcap) + { + ay_lockaudio(&oric->ay); + avi_close(&vidcap); + ay_unlockaudio(&oric->ay); + do_popup(oric, "AVI capture stopped"); + refreshavi = SDL_TRUE; + break; + } + + sprintf(vidcapname, "Capturing to video%02d.avi", vidcapcount); + warpspeed = SDL_FALSE; + ay_lockaudio(&oric->ay); + vidcap = avi_open(&vidcapname[13], oricpalette, soundavailable&&soundon, oric->vid_freq); + ay_unlockaudio(&oric->ay); + if(vidcap) + { + vidcapcount++; + do_popup(oric, vidcapname); + } + refreshavi = SDL_TRUE; +#else + android_togglekeyboard(oric); +#endif + break; #ifdef __CBCOPY__ case SDLK_F11: - clipboard_copy( oric ); + clipboard_copy(oric); break; #endif #ifdef __CBPASTE__ case SDLK_F12: - clipboard_paste( oric ); + clipboard_paste(oric); break; #endif #ifdef __amigaos4__ case SDLK_HELP: - IDOS->SystemTags( "Multiview Oricutron.guide", - SYS_Input, IDOS->Open( "NIL:", MODE_NEWFILE ), - SYS_Output, IDOS->Open( "NIL:", MODE_NEWFILE ), - SYS_Asynch, TRUE, - TAG_DONE ); - break; + IDOS->SystemTags("Multiview Oricutron.guide", + SYS_Input, IDOS->Open("NIL:", MODE_NEWFILE), + SYS_Output, IDOS->Open("NIL:", MODE_NEWFILE), + SYS_Asynch, TRUE, + TAG_DONE); + break; #endif #ifdef __MORPHOS__ case SDLK_HELP: - { - struct NewAmigaGuide nag = - { (BPTR) NULL, - "Oricutron.guide", - NULL, - NULL, - NULL, - NULL, - NULL, - 0, - NULL, - "MAIN", - 0, - NULL, - NULL - }; - - OpenAmigaGuide(&nag, TAG_DONE); - } - break; + { + struct NewAmigaGuide nag = + { + (BPTR) NULL, + "Oricutron.guide", + NULL, + NULL, + NULL, + NULL, + NULL, + 0, + NULL, + "MAIN", + 0, + NULL, + NULL + }; + + OpenAmigaGuide(&nag, TAG_DONE); + } + break; #endif case SDLK_PRINT: - sprintf( screencapname, "Capturing to screenshot%02d.bmp", screencapcount ); + sprintf(screencapname, "Capturing to screenshot%02d.bmp", screencapcount); screencapcount++; - do_popup( oric, screencapname ); - SDL_COMPAT_TakeScreenshot( &screencapname[13] ); + do_popup(oric, screencapname); + SDL_COMPAT_TakeScreenshot(&screencapname[13]); break; case SDLK_LSHIFT: @@ -1367,20 +1620,20 @@ SDL_bool emu_event( SDL_Event *ev, struct machine *oric, SDL_bool *needrender ) shifted = SDL_FALSE; default: - ay_keypress( &oric->ay, mapkey( oric, ev->key.keysym.sym ), SDL_FALSE ); + ay_keypress(&oric->ay, mapkey(oric, ev->key.keysym.sym), SDL_FALSE); break; } break; case SDL_KEYDOWN: - switch( ev->key.keysym.sym ) + switch(ev->key.keysym.sym) { case SDLK_LSHIFT: case SDLK_RSHIFT: shifted = SDL_TRUE; default: - ay_keypress( &oric->ay, mapkey( oric, ev->key.keysym.sym ), SDL_TRUE ); + ay_keypress(&oric->ay, mapkey(oric, ev->key.keysym.sym), SDL_TRUE); break; } break; @@ -1389,16 +1642,16 @@ SDL_bool emu_event( SDL_Event *ev, struct machine *oric, SDL_bool *needrender ) return SDL_FALSE; } -void blank_ram( Sint32 how, Uint8 *mem, Uint32 size ) +void blank_ram(Sint32 how, Uint8 *mem, Uint32 size) { Uint32 i, j; - switch( how ) + switch(how) { case 0: - for( i=0; ipch_fd_cload_getname_pc = -1; oric->pch_fd_csave_getname_pc = -1; @@ -1442,14 +1695,15 @@ void clear_patches( struct machine *oric ) oric->keymap = KMAP_QWERTY; } -static char *keymapnames[] = { "qwerty", +static char* keymapnames[] = { "qwerty", "azerty", "qwertz", - NULL }; + NULL + }; static Uint8 hex2bin(char c) { - return ( ('0' <= c && c <= '9')? (c - '0') : (10 + (toupper(c) - 'A')) ); + return (('0' <= c && c <= '9')? (c - '0') : (10 + (toupper(c) - 'A'))); } static Uint8 hex2byte(char* s) @@ -1469,55 +1723,55 @@ static SDL_bool ishexchar(char c) return SDL_FALSE; } -void load_patches( struct machine *oric, char *fname ) +void load_patches(struct machine *oric, char* fname) { FILE *f; Sint32 i; - char *tmpname; + char* tmpname; // MinGW doesn't have asprintf :-( - tmpname = malloc( strlen( fname ) + 10 ); - if( !tmpname ) return; - - sprintf( tmpname, "%s.pch", fname ); - - f = fopen( tmpname, "r" ); - free( tmpname ); - if( !f ) return; - - while( !feof( f ) ) - { - if( !fgets( filetmp, 2048, f ) ) break; - - for( i=0; isws( filetmp[i] ); i++ ) ; - - if( read_config_int( &filetmp[i], "fd_cload_getname_pc", &oric->pch_fd_cload_getname_pc, 0, 65535 ) ) continue; - if( read_config_int( &filetmp[i], "fd_csave_getname_pc", &oric->pch_fd_csave_getname_pc, 0, 65535 ) ) continue; - if( read_config_int( &filetmp[i], "fd_store_getname_pc", &oric->pch_fd_store_getname_pc, 0, 65535 ) ) continue; - if( read_config_int( &filetmp[i], "fd_recall_getname_pc", &oric->pch_fd_recall_getname_pc, 0, 65535 ) ) continue; - if( read_config_int( &filetmp[i], "fd_getname_addr", &oric->pch_fd_getname_addr, 0, 65535 ) ) continue; - if( read_config_int( &filetmp[i], "tt_getsync_pc", &oric->pch_tt_getsync_pc, 0, 65535 ) ) continue; - if( read_config_int( &filetmp[i], "tt_getsync_end_pc", &oric->pch_tt_getsync_end_pc, 0, 65535 ) ) continue; - if( read_config_int( &filetmp[i], "tt_getsync_loop_pc", &oric->pch_tt_getsync_loop_pc, 0, 65535 ) ) continue; - if( read_config_int( &filetmp[i], "tt_readbyte_pc", &oric->pch_tt_readbyte_pc, 0, 65535 ) ) continue; - if( read_config_int( &filetmp[i], "tt_readbyte_end_pc", &oric->pch_tt_readbyte_end_pc, 0, 65535 ) ) continue; - if( read_config_int( &filetmp[i], "tt_readbyte_storebyte_addr", &oric->pch_tt_readbyte_storebyte_addr, 0, 65535 ) ) continue; - if( read_config_int( &filetmp[i], "tt_readbyte_storezero_addr", &oric->pch_tt_readbyte_storezero_addr, 0, 65535 ) ) continue; - if( read_config_bool( &filetmp[i], "tt_readbyte_setcarry", &oric->pch_tt_readbyte_setcarry ) ) continue; - if( read_config_int( &filetmp[i], "tt_putbyte_pc", &oric->pch_tt_putbyte_pc, 0, 65535 ) ) continue; - if( read_config_int( &filetmp[i], "tt_putbyte_end_pc", &oric->pch_tt_putbyte_end_pc, 0, 65535 ) ) continue; - if( read_config_int( &filetmp[i], "tt_csave_end_pc", &oric->pch_tt_csave_end_pc, 0, 65535 ) ) continue; - if( read_config_int( &filetmp[i], "tt_store_end_pc", &oric->pch_tt_store_end_pc, 0, 65535 ) ) continue; - if( read_config_int( &filetmp[i], "tt_writeleader_pc", &oric->pch_tt_writeleader_pc, 0, 65535 ) ) continue; - if( read_config_int( &filetmp[i], "tt_writeleader_end_pc", &oric->pch_tt_writeleader_end_pc, 0, 65535 ) ) continue; - if( read_config_option( &filetmp[i], "keymap", &oric->keymap, keymapnames ) ) continue; + tmpname = malloc(strlen(fname) + 10); + if(!tmpname) return; + + sprintf(tmpname, "%s.pch", fname); + + f = fopen(tmpname, "r"); + free(tmpname); + if(!f) return; + + while(!feof(f)) + { + if(!fgets(filetmp, 2048, f)) break; + + for(i=0; isws(filetmp[i]); i++) ; + + if(read_config_int(&filetmp[i], "fd_cload_getname_pc", &oric->pch_fd_cload_getname_pc, 0, 65535)) continue; + if(read_config_int(&filetmp[i], "fd_csave_getname_pc", &oric->pch_fd_csave_getname_pc, 0, 65535)) continue; + if(read_config_int(&filetmp[i], "fd_store_getname_pc", &oric->pch_fd_store_getname_pc, 0, 65535)) continue; + if(read_config_int(&filetmp[i], "fd_recall_getname_pc", &oric->pch_fd_recall_getname_pc, 0, 65535)) continue; + if(read_config_int(&filetmp[i], "fd_getname_addr", &oric->pch_fd_getname_addr, 0, 65535)) continue; + if(read_config_int(&filetmp[i], "tt_getsync_pc", &oric->pch_tt_getsync_pc, 0, 65535)) continue; + if(read_config_int(&filetmp[i], "tt_getsync_end_pc", &oric->pch_tt_getsync_end_pc, 0, 65535)) continue; + if(read_config_int(&filetmp[i], "tt_getsync_loop_pc", &oric->pch_tt_getsync_loop_pc, 0, 65535)) continue; + if(read_config_int(&filetmp[i], "tt_readbyte_pc", &oric->pch_tt_readbyte_pc, 0, 65535)) continue; + if(read_config_int(&filetmp[i], "tt_readbyte_end_pc", &oric->pch_tt_readbyte_end_pc, 0, 65535)) continue; + if(read_config_int(&filetmp[i], "tt_readbyte_storebyte_addr", &oric->pch_tt_readbyte_storebyte_addr, 0, 65535)) continue; + if(read_config_int(&filetmp[i], "tt_readbyte_storezero_addr", &oric->pch_tt_readbyte_storezero_addr, 0, 65535)) continue; + if(read_config_bool(&filetmp[i], "tt_readbyte_setcarry", &oric->pch_tt_readbyte_setcarry)) continue; + if(read_config_int(&filetmp[i], "tt_putbyte_pc", &oric->pch_tt_putbyte_pc, 0, 65535)) continue; + if(read_config_int(&filetmp[i], "tt_putbyte_end_pc", &oric->pch_tt_putbyte_end_pc, 0, 65535)) continue; + if(read_config_int(&filetmp[i], "tt_csave_end_pc", &oric->pch_tt_csave_end_pc, 0, 65535)) continue; + if(read_config_int(&filetmp[i], "tt_store_end_pc", &oric->pch_tt_store_end_pc, 0, 65535)) continue; + if(read_config_int(&filetmp[i], "tt_writeleader_pc", &oric->pch_tt_writeleader_pc, 0, 65535)) continue; + if(read_config_int(&filetmp[i], "tt_writeleader_end_pc", &oric->pch_tt_writeleader_end_pc, 0, 65535)) continue; + if(read_config_option(&filetmp[i], "keymap", &oric->keymap, keymapnames)) continue; /* - * parse real patch line formated as: + * parse real patch line formatted as: * $xxxx:00112233445566778899AABBCCDDEEFF */ - // atleast address and 1 byte required + // at least address and 1 byte required if(8 <= strlen(&filetmp[i]) && ';' != filetmp[i]) { char* ptmp = &filetmp[i]; @@ -1543,56 +1797,65 @@ void load_patches( struct machine *oric, char *fname ) } - fclose( f ); + fclose(f); // Got all the addresses needed for each patch? - if( ( ( oric->pch_fd_cload_getname_pc != -1 ) || - ( oric->pch_fd_csave_getname_pc != -1 ) || - ( oric->pch_fd_store_getname_pc != -1 ) || - ( oric->pch_fd_recall_getname_pc != -1 ) ) && - ( oric->pch_fd_getname_addr != -1 ) ) + if(((oric->pch_fd_cload_getname_pc != -1) || + (oric->pch_fd_csave_getname_pc != -1) || + (oric->pch_fd_store_getname_pc != -1) || + (oric->pch_fd_recall_getname_pc != -1)) && + (oric->pch_fd_getname_addr != -1)) oric->pch_fd_available = SDL_TRUE; - if( ( oric->pch_tt_getsync_pc != -1 ) && - ( oric->pch_tt_getsync_end_pc != -1 ) && - ( oric->pch_tt_getsync_loop_pc != -1 ) && - ( oric->pch_tt_readbyte_pc != -1 ) && - ( oric->pch_tt_readbyte_end_pc != -1 ) ) + if((oric->pch_tt_getsync_pc != -1) && + (oric->pch_tt_getsync_end_pc != -1) && + (oric->pch_tt_getsync_loop_pc != -1) && + (oric->pch_tt_readbyte_pc != -1) && + (oric->pch_tt_readbyte_end_pc != -1)) oric->pch_tt_available = SDL_TRUE; - if( ( oric->pch_tt_putbyte_pc != -1 ) && - ( oric->pch_tt_putbyte_end_pc != -1 ) ) + if((oric->pch_tt_putbyte_pc != -1) && + (oric->pch_tt_putbyte_end_pc != -1)) oric->pch_tt_save_available = SDL_TRUE; } -static void setup_for_microdisc( struct machine *oric, void *readptr, void *writeptr ) +static void setup_for_microdisc(struct machine *oric, void* readptr, void* writeptr) { oric->cpu.read = readptr; oric->cpu.write = writeptr; oric->romdis = SDL_TRUE; - microdisc_init( &oric->md, &oric->wddisk, oric ); + microdisc_init(&oric->md, &oric->wddisk, oric); oric->disksyms = &sym_microdisc; } -static void setup_for_jasmin( struct machine *oric, void *readptr, void *writeptr ) +static void setup_for_bd500(struct machine *oric, void* readptr, void* writeptr) +{ + oric->cpu.read = readptr; + oric->cpu.write = writeptr; + oric->romdis = SDL_TRUE; + bd500_init(&oric->bd, &oric->wddisk, oric); + oric->disksyms = &sym_bd500; +} + +static void setup_for_jasmin(struct machine *oric, void* readptr, void* writeptr) { oric->cpu.read = readptr; oric->cpu.write = writeptr; oric->romdis = SDL_FALSE; - jasmin_init( &oric->jasmin, &oric->wddisk, oric ); + jasmin_init(&oric->jasmin, &oric->wddisk, oric); oric->disksyms = &sym_jasmin; } -static void setup_for_pravetzdisk( struct machine *oric, void *readptr, void *writeptr ) +static void setup_for_pravetzdisk(struct machine *oric, void* readptr, void* writeptr) { oric->cpu.read = readptr; oric->cpu.write = writeptr; oric->romdis = SDL_FALSE; - pravetz_init( &oric->pravetz, oric ); + pravetz_init(&oric->pravetz, oric); oric->disksyms = &sym_pravetz; } -static void setup_for_no_disk( struct machine *oric, void *readptr, void *writeptr ) +static void setup_for_no_disk(struct machine *oric, void* readptr, void* writeptr) { oric->drivetype = DRV_NONE; oric->cpu.read = readptr; @@ -1601,14 +1864,14 @@ static void setup_for_no_disk( struct machine *oric, void *readptr, void *writep oric->disksyms = NULL; } -SDL_bool init_machine( struct machine *oric, int type, SDL_bool nukebreakpoints ) +SDL_bool init_machine(struct machine *oric, int type, SDL_bool nukebreakpoints) { int i; oric->tapeturbo_forceoff = SDL_FALSE; oric->type = type; - m6502_init( &oric->cpu, (void*)oric, nukebreakpoints ); + m6502_init(&oric->cpu, (void*)oric, nukebreakpoints); oric->tapeturbo_syncstack = -1; @@ -1627,138 +1890,150 @@ SDL_bool init_machine( struct machine *oric, int type, SDL_bool nukebreakpoints oric->tele_banksyms[6].numsyms = 0; oric->tele_banksyms[7].numsyms = 0; - clear_patches( oric ); - - g_menu_scheme = type; + clear_patches(oric); - switch( type ) + switch(type) { case MACH_ORIC1_16K: - for( i=0; i<4; i++ ) + for(i=0; i<4; i++) oric->vidbases[i] &= 0x7fff; oric->memsize = 16384 + 16384; - oric->mem = malloc( oric->memsize ); - if( !oric->mem ) + oric->mem = malloc(oric->memsize); + if(!oric->mem) { - error_printf( "Out of memory\n" ); + error_printf("Out of memory\n"); return SDL_FALSE; } - blank_ram( oric->rampattern, oric->mem, 16384+16384 ); + blank_ram(oric->rampattern, oric->mem, 16384+16384); oric->rom = &oric->mem[16384]; - switch( oric->drivetype ) + switch(oric->drivetype) { case DRV_MICRODISC: - setup_for_microdisc( oric, microdisc_o16kread, microdisc_o16kwrite); + setup_for_microdisc(oric, microdisc_o16kread, microdisc_o16kwrite); + break; + + case DRV_BD500: + setup_for_bd500(oric, bd500_o16kread, bd500_o16kwrite); break; case DRV_JASMIN: - setup_for_jasmin( oric, jasmin_o16kread, jasmin_o16kwrite); + setup_for_jasmin(oric, jasmin_o16kread, jasmin_o16kwrite); break; case DRV_PRAVETZ: default: - setup_for_no_disk( oric, o16kread, o16kwrite ); + setup_for_no_disk(oric, o16kread, o16kwrite); break; } - if( !load_rom( oric, oric1romfile, -16384, &oric->rom[0], &oric->romsyms, SYMF_ROMDIS0 ) ) return SDL_FALSE; - load_patches( oric, oric1romfile ); + if(!load_rom(oric, oric1romfile, -16384, &oric->rom[0], &oric->romsyms, SYMF_ROMDIS0)) return SDL_FALSE; + load_patches(oric, oric1romfile); break; case MACH_ORIC1: oric->memsize = 65536 + 16384; - oric->mem = malloc( oric->memsize ); - if( !oric->mem ) + oric->mem = malloc(oric->memsize); + if(!oric->mem) { - error_printf( "Out of memory\n" ); + error_printf("Out of memory\n"); return SDL_FALSE; } - blank_ram( oric->rampattern, oric->mem, 65536+16384 ); + blank_ram(oric->rampattern, oric->mem, 65536+16384); oric->rom = &oric->mem[65536]; - switch( oric->drivetype ) + switch(oric->drivetype) { case DRV_MICRODISC: - setup_for_microdisc( oric, microdisc_atmosread, microdisc_atmoswrite); + setup_for_microdisc(oric, microdisc_atmosread, microdisc_atmoswrite); + break; + + case DRV_BD500: + setup_for_bd500(oric, bd500_atmosread, bd500_atmoswrite); break; case DRV_JASMIN: - setup_for_jasmin( oric, jasmin_atmosread, jasmin_atmoswrite); + setup_for_jasmin(oric, jasmin_atmosread, jasmin_atmoswrite); break; case DRV_PRAVETZ: default: - setup_for_no_disk( oric, atmosread, atmoswrite ); + setup_for_no_disk(oric, atmosread, atmoswrite); break; } - if( !load_rom( oric, oric1romfile, -16384, &oric->rom[0], &oric->romsyms, SYMF_ROMDIS0 ) ) return SDL_FALSE; - load_patches( oric, oric1romfile ); + if(!load_rom(oric, oric1romfile, -16384, &oric->rom[0], &oric->romsyms, SYMF_ROMDIS0)) return SDL_FALSE; + load_patches(oric, oric1romfile); break; case MACH_ATMOS: oric->memsize = 65536 + 16384; - oric->mem = malloc( oric->memsize ); - if( !oric->mem ) + oric->mem = malloc(oric->memsize); + if(!oric->mem) { - error_printf( "Out of memory\n" ); + error_printf("Out of memory\n"); return SDL_FALSE; } - blank_ram( oric->rampattern, oric->mem, 65536+16384 ); + blank_ram(oric->rampattern, oric->mem, 65536+16384); oric->rom = &oric->mem[65536]; - switch( oric->drivetype ) + switch(oric->drivetype) { case DRV_MICRODISC: - setup_for_microdisc( oric, microdisc_atmosread, microdisc_atmoswrite); + setup_for_microdisc(oric, microdisc_atmosread, microdisc_atmoswrite); + break; + + case DRV_BD500: + setup_for_bd500(oric, bd500_atmosread, bd500_atmoswrite); break; case DRV_JASMIN: - setup_for_jasmin( oric, jasmin_atmosread, jasmin_atmoswrite); + setup_for_jasmin(oric, jasmin_atmosread, jasmin_atmoswrite); break; case DRV_PRAVETZ: default: - setup_for_no_disk( oric, atmosread, atmoswrite ); + setup_for_no_disk(oric, atmosread, atmoswrite); break; } - if( !load_rom( oric, atmosromfile, -16384, &oric->rom[0], &oric->romsyms, SYMF_ROMDIS0 ) ) return SDL_FALSE; - load_patches( oric, atmosromfile ); + if(!load_rom(oric, atmosromfile, -16384, &oric->rom[0], &oric->romsyms, SYMF_ROMDIS0)) return SDL_FALSE; + load_patches(oric, atmosromfile); break; case MACH_TELESTRAT: oric->drivetype = DRV_MICRODISC; oric->memsize = 65536 + 16384*7; - oric->mem = malloc( oric->memsize ); - if( !oric->mem ) + oric->mem = malloc(oric->memsize); + if(!oric->mem) { - error_printf( "Out of memory\n" ); + error_printf("Out of memory\n"); return SDL_FALSE; } - blank_ram( oric->rampattern, oric->mem, 65536+16384*7 ); + blank_ram(oric->rampattern, oric->mem, 65536+16384*7); - setup_for_microdisc( oric, telestratread, telestratwrite ); + setup_for_microdisc(oric, telestratread, telestratwrite); oric->disksyms = NULL; - for( i=0; i<8; i++ ) + for(i=0; i<8; i++) { // assign oric->rom to allow binary patches oric->rom = oric->tele_bank[i].ptr = &oric->mem[0x0c000+(i*0x4000)]; - if( telebankfiles[i][0] ) + if(telebankfiles[i][0]) { oric->tele_bank[i].type = TELEBANK_ROM; - if( !load_rom( oric, telebankfiles[i], -16384, oric->tele_bank[i].ptr, &oric->tele_banksyms[i], SYMF_TELEBANK0<tele_bank[i].ptr, &oric->tele_banksyms[i], SYMF_TELEBANK0<tele_bank[i].type = TELEBANK_RAM; } } @@ -1770,38 +2045,42 @@ SDL_bool init_machine( struct machine *oric, int type, SDL_bool nukebreakpoints case MACH_PRAVETZ: oric->memsize = 65536 + 16384; - oric->mem = malloc( oric->memsize ); - if( !oric->mem ) + oric->mem = malloc(oric->memsize); + if(!oric->mem) { - error_printf( "Out of memory\n" ); + error_printf("Out of memory\n"); return SDL_FALSE; } - blank_ram( oric->rampattern, oric->mem, 65536+16384 ); + blank_ram(oric->rampattern, oric->mem, 65536+16384); oric->rom = &oric->mem[65536]; - switch( oric->drivetype ) + switch(oric->drivetype) { case DRV_MICRODISC: - setup_for_microdisc( oric, microdisc_atmosread, microdisc_atmoswrite); + setup_for_microdisc(oric, microdisc_atmosread, microdisc_atmoswrite); + break; + + case DRV_BD500: + setup_for_bd500(oric, bd500_atmosread, bd500_atmoswrite); break; case DRV_JASMIN: - setup_for_jasmin( oric, jasmin_atmosread, jasmin_atmoswrite); + setup_for_jasmin(oric, jasmin_atmosread, jasmin_atmoswrite); break; case DRV_PRAVETZ: - setup_for_pravetzdisk( oric, pravetz_atmosread, pravetz_atmoswrite ); + setup_for_pravetzdisk(oric, pravetz_atmosread, pravetz_atmoswrite); break; default: - setup_for_no_disk( oric, atmosread, atmoswrite ); + setup_for_no_disk(oric, atmosread, atmoswrite); break; } - if( !load_rom( oric, pravetzromfile[0], -16384, &oric->rom[0], &oric->romsyms, SYMF_ROMDIS0 ) ) return SDL_FALSE; - load_patches( oric, pravetzromfile[0] ); + if(!load_rom(oric, pravetzromfile[0], -16384, &oric->rom[0], &oric->romsyms, SYMF_ROMDIS0)) return SDL_FALSE; + load_patches(oric, pravetzromfile[0]); break; default: @@ -1814,86 +2093,138 @@ SDL_bool init_machine( struct machine *oric, int type, SDL_bool nukebreakpoints oric->vid_maxrast = 312; oric->vid_end = oric->vid_start + 224; oric->vid_raster = 0; - ula_powerup_default( oric ); + ula_powerup_default(oric); oric->read_not_lightpen = oric->cpu.read; - if (oric->lightpen) + if(oric->lightpen) oric->cpu.read = lightpen_read; - setromon( oric ); + setromon(oric); oric->tapename[0] = 0; - tape_rewind( oric ); - m6502_reset( &oric->cpu ); - via_init( &oric->via, oric, VIA_MAIN ); - via_init( &oric->tele_via, oric, VIA_TELESTRAT ); - acia_init( &oric->tele_acia, oric ); + tape_rewind(oric); + if(oric->twilighteboard_activated) + { + oric->twilighte=twilighte_oric_init(); + oric->ch376_activated=SDL_TRUE; + + if(oric->twilighte->microdisc==SDL_TRUE) + { + oric->drivetype = DRV_MICRODISC; + oric->disksyms = NULL; + microdisc_init(&oric->md, &oric->wddisk, oric); + } + + } + + if(oric->twilighte==NULL) oric->twilighteboard_activated=SDL_FALSE; - if (oric->ch376_activated) + m6502_reset(&oric->cpu); + via_init(&oric->via, oric, VIA_MAIN); + via_init(&oric->tele_via, oric, VIA_TELESTRAT); + acia_init(&oric->tele_acia, oric); + + if(oric->ch376_activated) { oric->ch376 = ch376_oric_init(); ch376_oric_config(oric->ch376); } - ay_init( &oric->ay, oric ); - joy_setup( oric ); + + + ay_init(&oric->ay, oric); + joy_setup(oric); oric->cpu.rastercycles = oric->cyclesperraster; oric->frames = 0; oric->vid_double = SDL_TRUE; - setemumode( oric, NULL, EM_RUNNING ); + setemumode(oric, NULL, EM_RUNNING); - if( oric->autorewind ) tape_rewind( oric ); + if(oric->autorewind) tape_rewind(oric); - setmenutoggles( oric ); + setmenutoggles(oric); refreshstatus = SDL_TRUE; return SDL_TRUE; } -void shut_machine( struct machine *oric ) +void shut_machine(struct machine *oric) { - if( oric->drivetype == DRV_MICRODISC ) { microdisc_free( &oric->md ); oric->drivetype = DRV_NONE; } - if( oric->drivetype == DRV_JASMIN ) { jasmin_free( &oric->jasmin ); oric->drivetype = DRV_NONE; } - if( oric->drivetype == DRV_PRAVETZ ) { pravetz_free( &oric->pravetz ); oric->drivetype = DRV_NONE; } - if( oric->mem ) { free( oric->mem ); oric->mem = NULL; oric->rom = NULL; } - if( oric->prf ) { fclose( oric->prf ); oric->prf = NULL; } - if( oric->tsavf ) tape_stop_savepatch( oric ); - if( oric->tapecap ) toggletapecap( oric, find_item_by_function(mainitems, toggletapecap), 0 ); - if (oric->tapebuf) { free(oric->tapebuf); oric->tapebuf = NULL; } - mon_freesyms( &sym_microdisc ); - mon_freesyms( &sym_jasmin ); - mon_freesyms( &sym_pravetz ); - mon_freesyms( &oric->romsyms ); - mon_freesyms( &oric->tele_banksyms[0] ); - mon_freesyms( &oric->tele_banksyms[1] ); - mon_freesyms( &oric->tele_banksyms[2] ); - mon_freesyms( &oric->tele_banksyms[3] ); - mon_freesyms( &oric->tele_banksyms[4] ); - mon_freesyms( &oric->tele_banksyms[5] ); - mon_freesyms( &oric->tele_banksyms[6] ); - mon_freesyms( &oric->tele_banksyms[7] ); + if(oric->drivetype == DRV_MICRODISC) + { + microdisc_free(&oric->md); + oric->drivetype = DRV_NONE; + } + if(oric->drivetype == DRV_BD500) + { + bd500_free(&oric->bd); + oric->drivetype = DRV_NONE; + } + if(oric->drivetype == DRV_JASMIN) + { + jasmin_free(&oric->jasmin); + oric->drivetype = DRV_NONE; + } + if(oric->drivetype == DRV_PRAVETZ) + { + pravetz_free(&oric->pravetz); + oric->drivetype = DRV_NONE; + } + if(oric->mem) + { + free(oric->mem); + oric->mem = NULL; + oric->rom = NULL; + } + if(oric->prf) + { + fclose(oric->prf); + oric->prf = NULL; + } + if(oric->tsavf) tape_stop_savepatch(oric); + if(oric->tapecap) toggletapecap(oric, find_item_by_function(mainitems, toggletapecap), 0); + if(oric->tapebuf) + { + free(oric->tapebuf); + oric->tapebuf = NULL; + } +#ifndef WWW_NO_MONITOR + mon_freesyms(&sym_microdisc); + mon_freesyms(&sym_bd500); + mon_freesyms(&sym_jasmin); + mon_freesyms(&sym_pravetz); + mon_freesyms(&oric->romsyms); + mon_freesyms(&oric->tele_banksyms[0]); + mon_freesyms(&oric->tele_banksyms[1]); + mon_freesyms(&oric->tele_banksyms[2]); + mon_freesyms(&oric->tele_banksyms[3]); + mon_freesyms(&oric->tele_banksyms[4]); + mon_freesyms(&oric->tele_banksyms[5]); + mon_freesyms(&oric->tele_banksyms[6]); + mon_freesyms(&oric->tele_banksyms[7]); +#endif } -void setdrivetype( struct machine *oric, struct osdmenuitem *mitem, int type ) +void setdrivetype(struct machine *oric, struct osdmenuitem *mitem, int type) { - if( oric->drivetype == type ) + if(oric->drivetype == type) return; - if( ( type == DRV_PRAVETZ ) && - ( oric->type != MACH_PRAVETZ ) ) + if((type == DRV_PRAVETZ) && + (oric->type != MACH_PRAVETZ)) { - swapmach( oric, mitem, (DRV_PRAVETZ<<16)|MACH_PRAVETZ ); + swapmach(oric, mitem, (DRV_PRAVETZ<<16)|MACH_PRAVETZ); return; } - shut_machine( oric ); + shut_machine(oric); - switch( type ) + switch(type) { case DRV_MICRODISC: + case DRV_BD500: case DRV_JASMIN: case DRV_PRAVETZ: - oric->drivetype = type; + oric->drivetype = type; break; default: @@ -1901,25 +2232,30 @@ void setdrivetype( struct machine *oric, struct osdmenuitem *mitem, int type ) break; } - mon_state_reset( oric ); - if( !init_machine( oric, oric->type, SDL_FALSE ) ) +#ifndef WWW_NO_MONITOR + mon_state_reset(oric); +#endif + if(!init_machine(oric, oric->type, SDL_FALSE)) { - shut( oric ); - exit( EXIT_FAILURE ); + shut(oric); +#ifdef __ANDROID__ + error_printf("'init_machine' failed"); +#endif + exit(EXIT_FAILURE); } - setmenutoggles( oric ); + setmenutoggles(oric); } -void swapmach( struct machine *oric, struct osdmenuitem *mitem, int which ) +void swapmach(struct machine *oric, struct osdmenuitem *mitem, int which) { int curr_drivetype; curr_drivetype = oric->drivetype; - shut_machine( oric ); + shut_machine(oric); - if( ((which>>16)&0xffff) != 0xffff ) + if(((which>>16)&0xffff) != 0xffff) curr_drivetype = (which>>16)&0xffff; which &= 0xffff; @@ -1928,13 +2264,18 @@ void swapmach( struct machine *oric, struct osdmenuitem *mitem, int which ) /* The contents of the disk panel depend on the disk type. */ /* Wipe it to prevent garbage. */ - clear_textzone( oric, TZ_DISK ); + clear_textzone(oric, TZ_DISK); - mon_state_reset( oric ); - if( !init_machine( oric, which, which!=oric->type ) ) +#ifndef WWW_NO_MONITOR + mon_state_reset(oric); +#endif + if(!init_machine(oric, which, which!=oric->type)) { - shut( oric ); - exit( EXIT_FAILURE ); + shut(oric); +#ifdef __ANDROID__ + error_printf("'init_machine' failed"); +#endif + exit(EXIT_FAILURE); } } diff --git a/machine.h b/machine.h index a71555f9..8feeebfb 100644 --- a/machine.h +++ b/machine.h @@ -27,7 +27,8 @@ enum DRV_NONE = 0, DRV_JASMIN, DRV_MICRODISC, - DRV_PRAVETZ + DRV_BD500, + DRV_PRAVETZ, }; enum @@ -70,6 +71,7 @@ enum IMG_ATMOS_MICRODISC, IMG_ATMOS_JASMIN, IMG_TELESTRAT_DISK, + IMG_BD500_DISK, IMG_PRAVETZ_DISK, IMG_GUESS_MICRODISC, IMG_SNAPSHOT, @@ -79,7 +81,7 @@ enum struct telebankinfo { unsigned char type; - unsigned char *ptr; + unsigned char* ptr; }; struct machine @@ -89,8 +91,8 @@ struct machine struct via via; struct ay8912 ay; unsigned int memsize; - unsigned char *mem; - unsigned char *rom; + unsigned char* mem; + unsigned char* rom; int emu_mode; struct symboltable romsyms; @@ -102,7 +104,9 @@ struct machine struct via tele_via; struct acia tele_acia; struct ch376 *ch376; + struct twilighte *twilighte; SDL_bool ch376_activated; + SDL_bool twilighteboard_activated; int tele_currbank; unsigned char tele_banktype; @@ -124,7 +128,7 @@ struct machine int vid_chline; int frames; SDL_bool vid_dirty[224]; - void (*vid_block_func)( struct machine *, SDL_bool, int, int ); + void (*vid_block_func)(struct machine *, SDL_bool, int, int); int overclockmult, overclockshift; @@ -132,12 +136,12 @@ struct machine int vsync; SDL_bool vid_double; - SDL_bool romdis, romon; + SDL_bool romdis, romon, rom16, dos70; SDL_bool vsynchack; unsigned short vid_addr; - unsigned char *vid_ch_data; - unsigned char *vid_ch_base; + unsigned char* vid_ch_data; + unsigned char* vid_ch_base; Uint8 *scrpt; Uint8 *scr; @@ -147,6 +151,7 @@ struct machine int drivetype; struct wd17xx wddisk; struct microdisc md; + struct bd500 bd; struct jasmin jasmin; struct pravetz pravetz; char diskname[MAX_DRIVES][32]; @@ -158,7 +163,7 @@ struct machine unsigned char tapebit, tapeout, tapeparity; int tapelen, tapeoffs, tapecount, tapetime, tapedupbytes, tapehdrend, tapedelay; - unsigned char *tapebuf; + unsigned char* tapebuf; SDL_bool tapemotor, tapenoise, tapeturbo, autorewind, autoinsert; SDL_bool tapeturbo_forceoff; SDL_bool symbolsautoload, symbolscase; @@ -211,14 +216,14 @@ struct machine void (*render_textzone_alloc)(struct machine *, int); void (*render_textzone_free)(struct machine *, int); void (*render_textzone)(struct machine *, int); - void (*render_clear_area)( int, int, int, int ); + void (*render_clear_area)(int, int, int, int); void (*render_gimg)(int, Sint32, Sint32); void (*render_gimgpart)(int, Sint32, Sint32, Sint32, Sint32, Sint32, Sint32); void (*render_alloc_textzone)(struct machine *, struct textzone *); void (*render_free_textzone)(struct machine *, struct textzone *); void (*render_video)(struct machine *, SDL_bool); - SDL_bool (*render_togglefullscreen)(struct machine *oric); - SDL_bool (*init_render)(struct machine *); + SDL_bool(*render_togglefullscreen)(struct machine *oric); + SDL_bool(*init_render)(struct machine *); void (*shut_render)(struct machine *); char popupstr[40]; @@ -228,7 +233,7 @@ struct machine char statusstr[40]; SDL_bool newstatusstr; - int statusbar_mode; + Sint32 statusbar_mode; int rampattern; @@ -239,6 +244,8 @@ struct machine SDL_bool printenable; SDL_bool printfilter; + SDL_bool dcadjust; + SDL_bool soundloopon; SDL_bool lightpen; Uint8 lightpenx, lightpeny; @@ -254,6 +261,8 @@ struct machine SDL_bool define_mapping; SDL_bool sticky_mod_keys; + SDL_bool disable_menuscheme; + int aciaoffset; int aciabackend; int aciabackendcfg; @@ -262,21 +271,21 @@ struct machine char aciabackendname[ACIA_BACKEND_NAME_LEN]; }; -void setromon( struct machine *oric ); -void setemumode( struct machine *oric, struct osdmenuitem *mitem, int mode ); -void video_show( struct machine *oric ); -SDL_bool emu_event( SDL_Event *ev, struct machine *oric, SDL_bool *needrender ); +void setromon(struct machine *oric); +void setemumode(struct machine *oric, struct osdmenuitem *mitem, int mode); +void video_show(struct machine *oric); +SDL_bool emu_event(SDL_Event *ev, struct machine *oric, SDL_bool *needrender); -void preinit_machine( struct machine *oric ); -void load_diskroms( struct machine *oric ); -SDL_bool init_machine( struct machine *oric, int type, SDL_bool nukebreakpoints ); -void shut_machine( struct machine *oric ); -void setdrivetype( struct machine *oric, struct osdmenuitem *mitem, int type ); -void swapmach( struct machine *oric, struct osdmenuitem *mitem, int which ); -SDL_bool isram( struct machine *oric, unsigned short addr ); +void preinit_machine(struct machine *oric); +void load_diskroms(struct machine *oric); +SDL_bool init_machine(struct machine *oric, int type, SDL_bool nukebreakpoints); +void shut_machine(struct machine *oric); +void setdrivetype(struct machine *oric, struct osdmenuitem *mitem, int type); +void swapmach(struct machine *oric, struct osdmenuitem *mitem, int which); +SDL_bool isram(struct machine *oric, unsigned short addr); -void clear_patches( struct machine *oric ); +void clear_patches(struct machine *oric); -unsigned char lightpen_read( struct m6502 *cpu, unsigned short addr ); +unsigned char lightpen_read(struct m6502 *cpu, unsigned short addr); -int detect_image_type(char *filename); +int detect_image_type(char* filename); diff --git a/main.c b/main.c index 1f27ee50..a47cd0ce 100644 --- a/main.c +++ b/main.c @@ -18,6 +18,11 @@ ** */ +#ifdef WWW +#include +#include +#endif + #ifdef __APPLE__ #include "CoreFoundation/CoreFoundation.h" #endif @@ -81,11 +86,12 @@ extern char tapepath[], diskpath[], telediskpath[], pravdiskpath[]; extern char atmosromfile[]; extern char oric1romfile[]; extern char mdiscromfile[]; +extern char bd500romfile[]; extern char jasmnromfile[]; extern char pravetzromfile[2][1024]; extern char telebankfiles[8][1024]; -static char keymap_path[4096+32]; +static char keymap_path[4096]; static int load_keymap = SDL_FALSE; struct context @@ -130,28 +136,34 @@ struct start_opts char* start_syms_files[32]; Sint32 start_syms_count; char start_snapshot[1024]; - char *start_breakpoint; + char* start_breakpoint; + Sint32 start_disks_count; + char start_disks[4][1024]; }; -static char *machtypes[] = { "oric1", +static char* machtypes[] = { "oric1", "oric1-16k", "atmos", "telestrat", "pravetz|pravetz8d", - NULL }; + NULL + }; -static char *disktypes[] = { "none", +static char* disktypes[] = { "none", "jasmin", "microdisc", + "bd500", "pravetz", - NULL }; + NULL + }; -static char *joyifacetypes[] = { "none", +static char* joyifacetypes[] = { "none", "altai|pase", "ijk", - NULL }; + NULL + }; -static char *joymodes[] = { "none", +static char* joymodes[] = { "none", "kbjoy1", "kbjoy2", "sdljoy0", @@ -165,56 +177,154 @@ static char *joymodes[] = { "none", "sdljoy8", "sdljoy9", "mouse", - NULL }; + NULL + }; -static char *rendermodes[] = { "{{INVALID}}", +static char* rendermodes[] = { "{{INVALID}}", "soft", "opengl", - NULL }; + NULL + }; + +static char* swdepths[] = { "8", "16", "32", NULL }; + +static char* sbarmodes[] = { "full", "nofps", "none", NULL }; + +static char* fileprefix = 0; + +// Initialize path prefix for locating program resources +static void init_fileprefix(char* argv[]) +{ + (void) argv; +#if defined(__amigaos4__) + + fileprefix = "PROGDIR:"; + +#elif defined(__ANDROID__) + + fileprefix = "/data/data/com.emul.oricutron/files/"; + +#elif defined(__linux__) || defined(__APPLE__) + + // Find program directory + fileprefix = realpath(argv[0], 0); // convert to absolute path + int len = strlen(fileprefix); + while(len && fileprefix[len-1] != PATHSEP) // strip the program filename + len--; + fileprefix[len] = 0; + +#if defined(__APPLE__) + // When bundled, program is in /Oricutron.app/Contents/MacOS/ + // but data files are further up in the parent of Oricutron.app. + const char* suffix = ".app/Contents/MacOS/"; + int suffix_len = strlen(suffix); + if(len > suffix_len && !strcasecmp(fileprefix + len - suffix_len, suffix)) + { + // Located in bundle - go to parent of .app dir + len -= suffix_len; // strip the suffix we matched + while(len && fileprefix[len-1] != PATHSEP) // strip the .app dir + len--; + fileprefix[len] = 0; + } + // else not bundled, stay in program directory +#endif + +#else + fileprefix = ""; +#endif +} + +// Get prefix string to locate program resources +const char* get_fileprefix() +{ + return fileprefix; +} + +// Check if filename looks to be absolute path +SDL_bool is_abs_path(const char* filename) +{ + char c = *(filename++); + + // Detect unix-style absolute path + if(c == '/' || c == '\\' || c == '~') + return SDL_TRUE; + + // Detect Amiga style absolute path or DOS drive letter + while(c) + { + if(c == ':') + return SDL_TRUE; + c = *(filename++); + } + + return SDL_FALSE; +} + +// Prepend file prefix to relative path, buffer of size maxlen +void add_fileprefix(char* filename, int maxlen) +{ + const char* prefix = get_fileprefix(); + Sint32 prefix_len = strlen(prefix); + if(prefix_len == 0) + return; // no file prefix on this platform -static char *swdepths[] = { "8", "16", "32", NULL }; + Sint32 filename_len = strlen(filename); + if(prefix_len + filename_len + 1 > maxlen) + return; // won't fit in buffer -static SDL_bool istokend( char c ) + if(is_abs_path(filename)) + return; // don't apply prefix to absolute path + + // Move filename including terminating zero + for(int i=filename_len+1; i>=0; i--) + filename[prefix_len+i] = filename[i]; + + // Put the prefix before + for(int i=0; i= (maxlen-1) ) break; - if( !buf[i] ) break; + if(d >= (maxlen-1)) break; + if(!buf[i]) break; - if( ( buf[i] == '\\' ) && ( buf[i+1] == '\'' ) ) + if((buf[i] == '\\') && (buf[i+1] == '\'')) { dest[d++] = '\''; i+=2; continue; } - if( ( buf[i] == '\\' ) && ( buf[i+1] == '\\' ) ) + if((buf[i] == '\\') && (buf[i+1] == '\\')) { dest[d++] = '\\'; i+=2; @@ -228,149 +338,159 @@ SDL_bool read_config_string( char *buf, char *token, char *dest, Sint32 maxlen ) return SDL_TRUE; } -SDL_bool read_config_bool( char *buf, char *token, SDL_bool *dest ) +SDL_bool read_config_path(char* buf, char* token, char* dest, Sint32 maxlen) +{ + if(!read_config_string(buf, token, dest, maxlen)) + return SDL_FALSE; + add_fileprefix(dest, maxlen); + return SDL_TRUE; +} + +SDL_bool read_config_bool(char* buf, char* token, SDL_bool *dest) { Sint32 i, toklen; // Get the token length - toklen = (int)strlen( token ); + toklen = (int)strlen(token); // Is this the token? - if( strncasecmp( buf, token, toklen ) != 0 ) return SDL_FALSE; + if(strncasecmp(buf, token, toklen) != 0) return SDL_FALSE; i = toklen; // Check for whitespace, equals, whitespace, single quote - while( isws( buf[i] ) ) i++; - if( buf[i] != '=' ) return SDL_TRUE; + while(isws(buf[i])) i++; + if(buf[i] != '=') return SDL_TRUE; i++; - while( isws( buf[i] ) ) i++; + while(isws(buf[i])) i++; (*dest) = SDL_FALSE; - if( strncasecmp( &buf[i], "true", 4 ) == 0 ) (*dest) = SDL_TRUE; - if( strncasecmp( &buf[i], "yes", 3 ) == 0 ) (*dest) = SDL_TRUE; + if(strncasecmp(&buf[i], "true", 4) == 0)(*dest) = SDL_TRUE; + if(strncasecmp(&buf[i], "yes", 3) == 0)(*dest) = SDL_TRUE; return SDL_TRUE; } -SDL_bool read_config_option( char *buf, char *token, Sint32 *dest, char **options ) +SDL_bool read_config_option(char* buf, char* token, Sint32 *dest, char** options) { Sint32 i, j, len; - char *thisopt; + char* thisopt; // Get the token length - len = (int)strlen( token ); + len = (int)strlen(token); // Is this the token? - if( strncasecmp( buf, token, len ) != 0 ) return SDL_FALSE; + if(strncasecmp(buf, token, len) != 0) return SDL_FALSE; i = len; // Check for whitespace, equals, whitespace, single quote - while( isws( buf[i] ) ) i++; - if( buf[i] != '=' ) return SDL_TRUE; + while(isws(buf[i])) i++; + if(buf[i] != '=') return SDL_TRUE; i++; - while( isws( buf[i] ) ) i++; + while(isws(buf[i])) i++; // Huh!? - if( strncmp( &buf[i], "{{INVALID}}", 11 ) == 0 ) + if(strncmp(&buf[i], "{{INVALID}}", 11) == 0) return SDL_FALSE; - for( j=0; options[j]; j++ ) + for(j=0; options[j]; j++) { thisopt = options[j]; - while( thisopt[0] ) + while(thisopt[0]) { len = 0; - while( (thisopt[len]!=0) && (thisopt[len]!='|') ) len++; + while((thisopt[len]!=0) && (thisopt[len]!='|')) len++; - if( strncasecmp( &buf[i], thisopt, len ) == 0 ) + if(strncasecmp(&buf[i], thisopt, len) == 0) { - if( istokend( buf[i+len] ) ) + if(istokend(buf[i+len])) { *dest = j; return SDL_TRUE; } } thisopt += len; - if( thisopt[0] == '|' ) thisopt++; + if(thisopt[0] == '|') thisopt++; } } return SDL_TRUE; } -SDL_bool read_config_int( char *buf, char *token, int *dest, int min, int max ) +SDL_bool read_config_int(char* buf, char* token, int* dest, int min, int max) { Sint32 i, toklen; int val, hv; // Get the token length - toklen = (int)strlen( token ); + toklen = (int)strlen(token); // Is this the token? - if( strncasecmp( buf, token, toklen ) != 0 ) return SDL_FALSE; + if(strncasecmp(buf, token, toklen) != 0) return SDL_FALSE; i = toklen; // Check for whitespace, equals, whitespace - while( isws( buf[i] ) ) i++; - if( buf[i] != '=' ) return SDL_TRUE; + while(isws(buf[i])) i++; + if(buf[i] != '=') return SDL_TRUE; i++; - while( isws( buf[i] ) ) i++; + while(isws(buf[i])) i++; val = 0; - if( buf[i] == '$' ) + if(buf[i] == '$') { i++; - while( (hv=hexit(buf[i])) != -1 ) + while((hv=hexit(buf[i])) != -1) { val = (val<<4) + hv; i++; } - } else { - val = atoi( &buf[i] ); + } + else + { + val = atoi(&buf[i]); } - if( val < min ) val = min; - if( val > max ) val = max; + if(val < min) val = min; + if(val > max) val = max; (*dest) = val; return SDL_TRUE; } -SDL_bool read_config_joykey( char *buf, char *token, SDL_COMPAT_KEY *dest ) +SDL_bool read_config_joykey(char* buf, char* token, SDL_COMPAT_KEY *dest) { Sint32 i, toklen, d; SDL_COMPAT_KEY thekey; char keyname[32]; // Get the token length - toklen = (int)strlen( token ); + toklen = (int)strlen(token); // Is this the token? - if( strncasecmp( buf, token, toklen ) != 0 ) return SDL_FALSE; + if(strncasecmp(buf, token, toklen) != 0) return SDL_FALSE; i = toklen; // Check for whitespace, equals, whitespace, single quote - while( isws( buf[i] ) ) i++; - if( buf[i] != '=' ) return SDL_TRUE; + while(isws(buf[i])) i++; + if(buf[i] != '=') return SDL_TRUE; i++; - while( isws( buf[i] ) ) i++; - if( buf[i] != '\'' ) return SDL_TRUE; + while(isws(buf[i])) i++; + if(buf[i] != '\'') return SDL_TRUE; i++; // Copy and un-escape the string d=0; - while( buf[i] != '\'' ) + while(buf[i] != '\'') { - if( d >= 31 ) break; - if( !buf[i] ) break; + if(d >= 31) break; + if(!buf[i]) break; - if( ( buf[i] == '\\' ) && ( buf[i+1] == '\'' ) ) + if((buf[i] == '\\') && (buf[i+1] == '\'')) { keyname[d++] = '\''; i+=2; continue; } - if( ( buf[i] == '\\' ) && ( buf[i+1] == '\\' ) ) + if((buf[i] == '\\') && (buf[i+1] == '\\')) { keyname[d++] = '\\'; i+=2; @@ -382,9 +502,9 @@ SDL_bool read_config_joykey( char *buf, char *token, SDL_COMPAT_KEY *dest ) keyname[d] = 0; - thekey = joy_keyname_to_sym( keyname ); + thekey = joy_keyname_to_sym(keyname); - if( thekey ) + if(thekey) { *dest = thekey; return SDL_TRUE; @@ -393,74 +513,88 @@ SDL_bool read_config_joykey( char *buf, char *token, SDL_COMPAT_KEY *dest ) return SDL_FALSE; } -static void load_config( struct start_opts *sto, struct machine *oric ) +static void load_config(struct start_opts *sto, struct machine *oric) { FILE *f; Sint32 i, j; char tbtmp[32]; - char keymap_file[4096]; + char config_path[4096]; - f = fopen( FILEPREFIX"oricutron.cfg", "r" ); - if( !f ) return; + strcpy(config_path, "oricutron.cfg"); + add_fileprefix(config_path, 4096); + f = fopen(config_path, "r"); + if(!f) return; - while( !feof( f ) ) + while(!feof(f)) { - if( !fgets( sto->lctmp, 2048, f ) ) break; - - for( i=0; isws( sto->lctmp[i] ); i++ ) ; - - if( read_config_option( &sto->lctmp[i], "machine", &sto->start_machine, machtypes ) ) continue; - if( read_config_option( &sto->lctmp[i], "disktype", &sto->start_disktype, disktypes ) ) continue; - if( read_config_bool( &sto->lctmp[i], "debug", &sto->start_debug ) ) continue; - if( read_config_bool( &sto->lctmp[i], "fullscreen", &fullscreen ) ) continue; - if( read_config_bool( &sto->lctmp[i], "hwsurface", &hwsurface ) ) continue; - if( read_config_bool( &sto->lctmp[i], "scanlines", &oric->scanlines ) ) continue; - if( read_config_bool( &sto->lctmp[i], "aratio", &oric->aratio ) ) continue; - if( read_config_bool( &sto->lctmp[i], "hstretch", &oric->hstretch ) ) continue; - if( read_config_bool( &sto->lctmp[i], "palghosting", &oric->palghost ) ) continue; - if( read_config_string( &sto->lctmp[i], "diskimage", sto->start_disk, 1024 ) ) continue; - if( read_config_string( &sto->lctmp[i], "tapeimage", sto->start_tape, 1024 ) ) continue; - if( read_config_string( &sto->lctmp[i], "symbols", sto->start_syms, 1024 ) ) continue; - if( read_config_string( &sto->lctmp[i], "tapepath", tapepath, 1024 ) ) continue; - if( read_config_string( &sto->lctmp[i], "diskpath", diskpath, 1024 ) ) continue; - if( read_config_string( &sto->lctmp[i], "telediskpath", telediskpath, 1024 ) ) continue; - if( read_config_string( &sto->lctmp[i], "pravdiskpath", pravdiskpath, 1024 ) ) continue; - if( read_config_string( &sto->lctmp[i], "atmosrom", atmosromfile, 1024 ) ) continue; - if( read_config_string( &sto->lctmp[i], "oric1rom", oric1romfile, 1024 ) ) continue; - if( read_config_string( &sto->lctmp[i], "mdiscrom", mdiscromfile, 1024 ) ) continue; - if( read_config_string( &sto->lctmp[i], "jasminrom", jasmnromfile, 1024 ) ) continue; - if( read_config_string( &sto->lctmp[i], "pravetzrom", pravetzromfile[0], 1024 ) ) continue; - if( read_config_string( &sto->lctmp[i], "pravetz8drom", pravetzromfile[1], 1024 ) ) continue; - if( read_config_int( &sto->lctmp[i], "rampattern", &oric->rampattern, 0, 1 ) ) continue; - if( read_config_option( &sto->lctmp[i], "swdepth", &oric->sw_depth, swdepths ) ) + if(!fgets(sto->lctmp, 2048, f)) break; + + for(i=0; isws(sto->lctmp[i]); i++) ; + + if(read_config_option(&sto->lctmp[i], "machine", &sto->start_machine, machtypes)) continue; + if(read_config_option(&sto->lctmp[i], "disktype", &sto->start_disktype, disktypes)) continue; + if(read_config_bool(&sto->lctmp[i], "debug", &sto->start_debug)) continue; + if(read_config_bool(&sto->lctmp[i], "fullscreen", &fullscreen)) continue; + if(read_config_option(&sto->lctmp[i], "statusbarmode", &oric->statusbar_mode, sbarmodes)) continue; + if(read_config_bool(&sto->lctmp[i], "hwsurface", &hwsurface)) continue; + if(read_config_bool(&sto->lctmp[i], "scanlines", &oric->scanlines)) continue; + if(read_config_bool(&sto->lctmp[i], "aratio", &oric->aratio)) continue; + if(read_config_bool(&sto->lctmp[i], "hstretch", &oric->hstretch)) continue; + if(read_config_bool(&sto->lctmp[i], "palghosting", &oric->palghost)) continue; + if(read_config_bool(&sto->lctmp[i], "rom16", &oric->rom16)) continue; + if(read_config_bool(&sto->lctmp[i], "dos70", &oric->dos70)) continue; + if(read_config_path(&sto->lctmp[i], "diskimage", sto->start_disk, 1024)) continue; + if(read_config_path(&sto->lctmp[i], "tapeimage", sto->start_tape, 1024)) continue; + if(read_config_path(&sto->lctmp[i], "symbols", sto->start_syms, 1024)) continue; + if(read_config_path(&sto->lctmp[i], "tapepath", tapepath, 1024)) continue; + if(read_config_path(&sto->lctmp[i], "diskpath", diskpath, 1024)) continue; + if(read_config_path(&sto->lctmp[i], "telediskpath", telediskpath, 1024)) continue; + if(read_config_path(&sto->lctmp[i], "pravdiskpath", pravdiskpath, 1024)) continue; + if(read_config_path(&sto->lctmp[i], "atmosrom", atmosromfile, 1024)) continue; + if(read_config_path(&sto->lctmp[i], "oric1rom", oric1romfile, 1024)) continue; + if(read_config_path(&sto->lctmp[i], "mdiscrom", mdiscromfile, 1024)) continue; + if(read_config_path(&sto->lctmp[i], "bd500rom", bd500romfile, 1024)) continue; + if(read_config_path(&sto->lctmp[i], "jasminrom", jasmnromfile, 1024)) continue; + if(read_config_path(&sto->lctmp[i], "pravetzrom", pravetzromfile[0], 1024)) continue; + if(read_config_path(&sto->lctmp[i], "pravetz8drom", pravetzromfile[1], 1024)) continue; + if(read_config_int(&sto->lctmp[i], "rampattern", &oric->rampattern, 0, 1)) continue; + if(read_config_option(&sto->lctmp[i], "swdepth", &oric->sw_depth, swdepths)) { /* Convert index to depth */ - switch (oric->sw_depth) + switch(oric->sw_depth) { - case 0: oric->sw_depth = 8; break; - case 2: oric->sw_depth = 32; break; - default: oric->sw_depth = 16; break; + case 0: + oric->sw_depth = 8; + break; + case 2: + oric->sw_depth = 32; + break; + default: + oric->sw_depth = 16; + break; } continue; } - if( read_config_option( &sto->lctmp[i], "rendermode", &sto->start_rendermode, rendermodes ) ) + if(read_config_option(&sto->lctmp[i], "rendermode", &sto->start_rendermode, rendermodes)) { #ifndef __OPENGL_AVAILABLE__ - if( sto->start_rendermode == RENDERMODE_GL ) + if(sto->start_rendermode == RENDERMODE_GL) sto->start_rendermode = RENDERMODE_SW; #endif continue; } - for( j=0; j<8; j++ ) + for(j=0; j<8; j++) { - sprintf( tbtmp, "telebank%c", j+'0' ); - if( read_config_string( &sto->lctmp[i], tbtmp, telebankfiles[j], 1024 ) ) break; + sprintf(tbtmp, "telebank%c", j+'0'); + if(read_config_path(&sto->lctmp[i], tbtmp, telebankfiles[j], 1024)) break; } - if( read_config_bool( &sto->lctmp[i], "lightpen", &oric->lightpen ) ) continue; - if( read_config_bool( &sto->lctmp[i], "printenable", &oric->printenable ) ) continue; - if( read_config_bool( &sto->lctmp[i], "printfilter", &oric->printfilter ) ) continue; - if( read_config_int( &sto->lctmp[i], "serial_address", &oric->aciaoffset, 0x310, 0x3fc ) ) continue; - if( read_config_string( &sto->lctmp[i], "serial", oric->aciabackendname, ACIA_BACKEND_NAME_LEN ) ) + if(read_config_bool(&sto->lctmp[i], "lightpen", &oric->lightpen)) continue; + if(read_config_bool(&sto->lctmp[i], "printenable", &oric->printenable)) continue; + if(read_config_bool(&sto->lctmp[i], "printfilter", &oric->printfilter)) continue; + if(read_config_bool(&sto->lctmp[i], "dcadjust", &oric->dcadjust)) continue; + if(read_config_bool(&sto->lctmp[i], "soundloopon", &oric->soundloopon)) continue; + if(read_config_int(&sto->lctmp[i], "serial_address", &oric->aciaoffset, 0x310, 0x3fc)) continue; + if(read_config_string(&sto->lctmp[i], "serial", oric->aciabackendname, ACIA_BACKEND_NAME_LEN)) { if(!strcasecmp("none", oric->aciabackendname)) oric->aciabackendcfg = oric->aciabackend = ACIA_TYPE_NONE; @@ -473,16 +607,20 @@ static void load_config( struct start_opts *sto, struct machine *oric ) oric->aciabackendcfg = oric->aciabackend = ACIA_TYPE_MODEM; oric->aciabackendcfgport = 0; oric->aciabackendcfgdomain = 4; - if(p) { + if(p) + { char* p2 = strchr(p+1, ':'); - if (p2) { + if(p2) + { // check if we want IPv6 - if (strcasecmp(p2+1, "ipv6")==0) - oric->aciabackendcfgdomain = 6; + if(strcasecmp(p2+1, "ipv6")==0) + oric->aciabackendcfgdomain = 6; *p2 = '\0'; // temporarily place a \0 to isolate the port part of the string oric->aciabackendcfgport = atoi(p+1); // get the port part of the string *p2 = ':'; // put back the semicolon - } else { + } + else + { oric->aciabackendcfgport = atoi(p+1); } } @@ -498,135 +636,143 @@ static void load_config( struct start_opts *sto, struct machine *oric ) } continue; } - if( read_config_option( &sto->lctmp[i], "joyinterface", &oric->joy_iface, joyifacetypes ) ) continue; - if( read_config_option( &sto->lctmp[i], "joystick_a", &oric->joymode_a, joymodes ) ) continue; - if( read_config_option( &sto->lctmp[i], "joystick_b", &oric->joymode_b, joymodes ) ) continue; - if( read_config_option( &sto->lctmp[i], "telejoy_a", &oric->telejoymode_a, joymodes ) ) continue; - if( read_config_option( &sto->lctmp[i], "telejoy_b", &oric->telejoymode_b, joymodes ) ) continue; - if( read_config_joykey( &sto->lctmp[i], "kbjoy1_up", &oric->kbjoy1[0] ) ) continue; - if( read_config_joykey( &sto->lctmp[i], "kbjoy1_down", &oric->kbjoy1[1] ) ) continue; - if( read_config_joykey( &sto->lctmp[i], "kbjoy1_left", &oric->kbjoy1[2] ) ) continue; - if( read_config_joykey( &sto->lctmp[i], "kbjoy1_right", &oric->kbjoy1[3] ) ) continue; - if( read_config_joykey( &sto->lctmp[i], "kbjoy1_fire1", &oric->kbjoy1[4] ) ) continue; - if( read_config_joykey( &sto->lctmp[i], "kbjoy1_fire2", &oric->kbjoy1[5] ) ) continue; - if( read_config_joykey( &sto->lctmp[i], "kbjoy1_fire3", &oric->kbjoy1[6] ) ) continue; - if( read_config_joykey( &sto->lctmp[i], "kbjoy2_up", &oric->kbjoy2[0] ) ) continue; - if( read_config_joykey( &sto->lctmp[i], "kbjoy2_down", &oric->kbjoy2[1] ) ) continue; - if( read_config_joykey( &sto->lctmp[i], "kbjoy2_left", &oric->kbjoy2[2] ) ) continue; - if( read_config_joykey( &sto->lctmp[i], "kbjoy2_right", &oric->kbjoy2[3] ) ) continue; - if( read_config_joykey( &sto->lctmp[i], "kbjoy2_fire1", &oric->kbjoy2[4] ) ) continue; - if( read_config_joykey( &sto->lctmp[i], "kbjoy2_fire2", &oric->kbjoy2[5] ) ) continue; - if( read_config_joykey( &sto->lctmp[i], "kbjoy2_fire3", &oric->kbjoy2[6] ) ) continue; - if( read_config_bool( &sto->lctmp[i], "diskautosave", &oric->diskautosave ) ) continue; - if( read_config_bool( &sto->lctmp[i], "ch376", &oric->ch376_activated) ) continue; - if( read_config_bool( &sto->lctmp[i], "pravdiskautoboot", &oric->pravdiskautoboot ) ) continue; - if( read_config_bool( &sto->lctmp[i], "show_keyboard", &oric->show_keyboard ) ) continue; - if( read_config_bool( &sto->lctmp[i], "sticky_mod_keys", &oric->sticky_mod_keys ) )continue; - if( read_config_string( &sto->lctmp[i], "autoload_keyboard_mapping", keymap_file, 4096 ) ) + if(read_config_option(&sto->lctmp[i], "joyinterface", &oric->joy_iface, joyifacetypes)) continue; + if(read_config_option(&sto->lctmp[i], "joystick_a", &oric->joymode_a, joymodes)) continue; + if(read_config_option(&sto->lctmp[i], "joystick_b", &oric->joymode_b, joymodes)) continue; + if(read_config_option(&sto->lctmp[i], "telejoy_a", &oric->telejoymode_a, joymodes)) continue; + if(read_config_option(&sto->lctmp[i], "telejoy_b", &oric->telejoymode_b, joymodes)) continue; + if(read_config_joykey(&sto->lctmp[i], "kbjoy1_up", &oric->kbjoy1[0])) continue; + if(read_config_joykey(&sto->lctmp[i], "kbjoy1_down", &oric->kbjoy1[1])) continue; + if(read_config_joykey(&sto->lctmp[i], "kbjoy1_left", &oric->kbjoy1[2])) continue; + if(read_config_joykey(&sto->lctmp[i], "kbjoy1_right", &oric->kbjoy1[3])) continue; + if(read_config_joykey(&sto->lctmp[i], "kbjoy1_fire1", &oric->kbjoy1[4])) continue; + if(read_config_joykey(&sto->lctmp[i], "kbjoy1_fire2", &oric->kbjoy1[5])) continue; + if(read_config_joykey(&sto->lctmp[i], "kbjoy1_fire3", &oric->kbjoy1[6])) continue; + if(read_config_joykey(&sto->lctmp[i], "kbjoy2_up", &oric->kbjoy2[0])) continue; + if(read_config_joykey(&sto->lctmp[i], "kbjoy2_down", &oric->kbjoy2[1])) continue; + if(read_config_joykey(&sto->lctmp[i], "kbjoy2_left", &oric->kbjoy2[2])) continue; + if(read_config_joykey(&sto->lctmp[i], "kbjoy2_right", &oric->kbjoy2[3])) continue; + if(read_config_joykey(&sto->lctmp[i], "kbjoy2_fire1", &oric->kbjoy2[4])) continue; + if(read_config_joykey(&sto->lctmp[i], "kbjoy2_fire2", &oric->kbjoy2[5])) continue; + if(read_config_joykey(&sto->lctmp[i], "kbjoy2_fire3", &oric->kbjoy2[6])) continue; + if(read_config_bool(&sto->lctmp[i], "diskautosave", &oric->diskautosave)) continue; + if(read_config_bool(&sto->lctmp[i], "ch376", &oric->ch376_activated)) continue; + if(read_config_bool(&sto->lctmp[i], "twilighte_board", &oric->twilighteboard_activated)) continue; + if(read_config_bool(&sto->lctmp[i], "pravdiskautoboot", &oric->pravdiskautoboot)) continue; + if(read_config_bool(&sto->lctmp[i], "disable_menuscheme", &oric->disable_menuscheme)) continue; + if(read_config_bool(&sto->lctmp[i], "show_keyboard", &oric->show_keyboard)) continue; + if(read_config_bool(&sto->lctmp[i], "sticky_mod_keys", &oric->sticky_mod_keys))continue; + if(read_config_path(&sto->lctmp[i], "autoload_keyboard_mapping", keymap_path, 4096)) { - strcpy(keymap_path, FILEPREFIX""); - strcat(keymap_path, keymap_file); - load_keymap = SDL_TRUE; - continue; + load_keymap = SDL_TRUE; + continue; } } - - fclose( f ); + fclose(f); } -static void usage( int ret ) +static void usage(int ret) { - printf( VERSION_COPYRIGHTS "\n\n" - "Usage:\toricutron [-a|--arg [option]] [disk file] [tape file] [snapshot file]\n" - " -m / --machine = Specify machine type. Valid types are:\n" - "\n" - " \"atmos\" or \"a\" for Oric Atmos\n" - " \"oric1\" or \"1\" for Oric-1\n" - " \"o16k\" for Oric-1 16k\n" - " \"telestrat\" or \"t\" for Telestrat\n" - " \"pravetz\", \"pravetz8d\" or \"p\" for Pravetz 8D\n" - "\n" - " -d / --disk = Specify a disk image to use in drive 0\n" - " -t / --tape = Specify a tape image to use\n" - " -k / --drive = Specify a disk drive controller. Valid types are:\n" - "\n" - " \"microdisc\" or \"m\" for Microdisc\n" - " \"jasmin\" or \"j\" for Jasmin\n" - " \"pravetz\" or \"p\" for Pravetz\n" - " \"none\" or \"n\"\n" - "\n" - " -s / --symbols = Load symbols from a file\n" - " -f / --fullscreen = Run oricutron fullscreen\n" - " -w / --window = Run oricutron in a window\n" + printf(VERSION_COPYRIGHTS "\n\n" + "Usage:\toricutron [-a|--arg [option]] [disk file] [tape file] [snapshot file]\n" + " -m / --machine = Specify machine type. Valid types are:\n" + "\n" + " \"atmos\" or \"a\" for Oric Atmos\n" + " \"oric1\" or \"1\" for Oric-1\n" + " \"o16k\" for Oric-1 16k\n" + " \"telestrat\" or \"t\" for Telestrat\n" + " \"pravetz\", \"pravetz8d\" or \"p\" for Pravetz 8D\n" + "\n" + " -d / --disk = Specify a disk image to use in drive 0\n" + " -t / --tape = Specify a tape image to use\n" + " -k / --drive = Specify a disk drive controller. Valid types are:\n" + "\n" + " \"microdisc\" or \"m\" for Microdisc\n" + " \"jasmin\" or \"j\" for Jasmin\n" + " \"bd500\" or \"b\" for Byte Drive 500\n" + " \"pravetz\" or \"p\" for Pravetz\n" + " \"none\" or \"n\"\n" + "\n" + " -s / --symbols = Load symbols from a file\n" + " -f / --fullscreen = Run oricutron fullscreen\n" + " --statusbar = Set initial status bar mode: 'full', 'nofps' or 'none'\n" + " -w / --window = Run oricutron in a window\n" #ifdef __OPENGL_AVAILABLE__ - " -R / --rendermode = Render mode. Valid modes are:\n" - "\n" - " \"soft\" for software rendering\n" - " \"opengl\" for OpenGL\n" - "\n" + " -R / --rendermode = Render mode. Valid modes are:\n" + "\n" + " \"soft\" for software rendering\n" + " \"opengl\" for OpenGL\n" + "\n" #endif - " -b / --debug = Start oricutron in the debugger\n" - " -r / --breakpoint = Set a breakpoint\n" - "\n" - " --turbotape on|off = Enable or disable turbotape\n" - " --lightpen on|off = Enable or disable lightpen\n" - " --vsynchack on|off = Enable or disable VSync hack\n" - " --scanlines on|off = Enable or disable scanline simulation\n" - "\n" - " --serial_address N = Set serial card base address to N\n" - " where N is decimal or hexadecimal within the range of $31c..$3fc\n" - " (i.e. 796, 0x31c, $31C represent the same value)\n" - "\n" - " --serial = Set serial card back-end emulation:\n" - "\n" - " \"none\" - no serial\n" - " \"loopback\" - for testing - all TX data is returned to RX\n" + " -b / --debug = Start oricutron in the debugger\n" + " -r / --breakpoint = Set a breakpoint\n" + "\n" + " --turbotape on|off = Enable or disable turbotape\n" + " --lightpen on|off = Enable or disable lightpen\n" + " --vsynchack on|off = Enable or disable VSync hack\n" + " --scanlines on|off = Enable or disable scanline simulation\n" + "\n" + " --serial_address N = Set serial card base address to N\n" + " where N is decimal or hexadecimal within the range of $31c..$3fc\n" + " (i.e. 796, 0x31c, $31C represent the same value)\n" + "\n" + " --serial = Set serial card back-end emulation:\n" + "\n" + " \"none\" - no serial\n" + " \"loopback\" - for testing - all TX data is returned to RX\n" #ifdef BACKEND_MODEM - " \"modem[:port]\" - emulates com port with attached modem,\n" - " only minimal AT command set is supported and\n" - " data is redirected to TCP. Default port is 23 (telnet)\n" + " \"modem[:port]\" - emulates com port with attached modem,\n" + " only minimal AT command set is supported and\n" + " data is redirected to TCP. Default port is 23 (telnet)\n" #endif #ifdef BACKEND_COM - " \"com:115200,8,N,1,\" - use real or virtual on host as emulated ACIA.\n" - " Baudrate, data bits, parity and stop bits can be set as needed\n" - " ex.: Windows: \"com:115200,8,N,1,COM1\"\n" - " Linux: \"com:19200,8,N,1,/dev/ttyS0\"\n" - " \"com:115200,8,N,1,/dev/ttyUSB0\"\n" + " \"com:115200,8,N,1,\" - use real or virtual on host as emulated ACIA.\n" + " Baudrate, data bits, parity and stop bits can be set as needed\n" + " ex.: Windows: \"com:115200,8,N,1,COM1\"\n" + " Linux: \"com:19200,8,N,1,/dev/ttyS0\"\n" + " \"com:115200,8,N,1,/dev/ttyUSB0\"\n" +#endif + "\n"); + +#ifdef __ANDROID__ + error_printf("Bad command line."); #endif - "\n"); + exit(ret); } // Print a formatted string into a textzone -void error_printf( char *fmt, ... ) +#ifndef __ANDROID__ +void error_printf(char* fmt, ...) { static char str[256]; // Stupid MinGW32 not having vasprintf... va_list ap; - va_start( ap, fmt ); - if( vsnprintf( str, 256, fmt, ap ) != -1 ) + va_start(ap, fmt); + if(vsnprintf(str, 256, fmt, ap) != -1) { str[255] = 0; #ifdef WIN32 - MessageBoxA( NULL, str, "Oricutron", MB_OK ); + MessageBoxA(NULL, str, "Oricutron", MB_OK); #else - fprintf( stderr, "%s\n", str ); + fprintf(stderr, "%s\n", str); #endif } - va_end( ap ); + va_end(ap); } +#endif -static SDL_bool on_or_off( char *arg, char *option, SDL_bool *storage ) +static SDL_bool on_or_off(char* arg, char* option, SDL_bool *storage) { - if( option ) + if(option) { - if( strcasecmp( option, "on" ) == 0 ) + if(strcasecmp(option, "on") == 0) { *storage = SDL_TRUE; return SDL_TRUE; } - if( strcasecmp( option, "off" ) == 0 ) + if(strcasecmp(option, "off") == 0) { *storage = SDL_FALSE; return SDL_TRUE; @@ -637,14 +783,14 @@ static SDL_bool on_or_off( char *arg, char *option, SDL_bool *storage ) return SDL_FALSE; } -SDL_bool init( struct machine *oric, int argc, char *argv[] ) +SDL_bool init(struct machine *oric, int argc, char* argv[]) { Sint32 i; struct start_opts *sto; - char opt_type, *opt_arg, *tmp; + char opt_type, *opt_arg = NULL, *tmp; - sto = malloc( sizeof( struct start_opts ) ); - if( !sto ) return SDL_FALSE; + sto = malloc(sizeof(struct start_opts)); + if(!sto) return SDL_FALSE; // Defaults sto->start_machine = MACH_ATMOS; @@ -653,6 +799,11 @@ SDL_bool init( struct machine *oric, int argc, char *argv[] ) sto->start_disktype_set = SDL_FALSE; sto->start_debug = SDL_FALSE; sto->start_rendermode = RENDERMODE_SW; + sto->start_disks_count = 0; + sto->start_disks[0][0] = 0; + sto->start_disks[1][0] = 0; + sto->start_disks[2][0] = 0; + sto->start_disks[3][0] = 0; sto->start_disk[0] = 0; sto->start_tape[0] = 0; sto->start_syms[0] = 0; @@ -666,96 +817,143 @@ SDL_bool init( struct machine *oric, int argc, char *argv[] ) #else hwsurface = SDL_FALSE; #endif + preinit_ula(oric); + preinit_machine(oric); + preinit_render_sw(oric); + preinit_render_sw8(oric); - preinit_ula( oric ); - preinit_machine( oric ); - preinit_render_sw( oric ); - preinit_render_sw8( oric ); #ifdef __OPENGL_AVAILABLE__ - preinit_render_gl( oric ); + preinit_render_gl(oric); #endif - preinit_gui( oric ); + preinit_gui(oric); kbd_init(oric); // Go SDL! - if( SDL_Init( SDL_INIT_VIDEO | SDL_INIT_AUDIO ) < 0 ) + if(SDL_COMPAT_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0) { - error_printf( "SDL init failed" ); - free( sto ); + free(sto); return SDL_FALSE; } need_sdl_quit = SDL_TRUE; -#ifndef __APPLE__ - SDL_COMPAT_WM_SetIcon( SDL_LoadBMP( IMAGEPREFIX"winicon.bmp" ), NULL ); -#endif + render_sw_detectvideo(oric); - render_sw_detectvideo( oric ); + load_config(sto, oric); - load_config( sto, oric ); - - for( i=1; itapeturbo ) ) exit( EXIT_FAILURE ); + if(!on_or_off(argv[i-1], opt_arg, &oric->tapeturbo)) exit(EXIT_FAILURE); continue; } - if( strcasecmp( tmp, "lightpen" ) == 0 ) + if(strcasecmp(tmp, "lightpen") == 0) { - if( !on_or_off( argv[i-1], opt_arg, &oric->lightpen ) ) exit( EXIT_FAILURE ); + if(!on_or_off(argv[i-1], opt_arg, &oric->lightpen)) exit(EXIT_FAILURE); continue; } - if( strcasecmp( tmp, "serial_address" ) == 0 ) + if(strcasecmp(tmp, "serial_address") == 0) { - if( !opt_arg ) - exit( EXIT_FAILURE ); - if( '$' == opt_arg[0] && 1 == sscanf(opt_arg, "$%x", &oric->aciaoffset) ) + if(!opt_arg) + exit(EXIT_FAILURE); + if('$' == opt_arg[0] && 1 == sscanf(opt_arg, "$%x", &oric->aciaoffset)) continue; - if( '0' == opt_arg[0] && 1 == sscanf(opt_arg, "0x%x", &oric->aciaoffset) ) + if('0' == opt_arg[0] && 1 == sscanf(opt_arg, "0x%x", &oric->aciaoffset)) continue; - if( '0' == opt_arg[0] && 1 == sscanf(opt_arg, "0X%x", &oric->aciaoffset) ) + if('0' == opt_arg[0] && 1 == sscanf(opt_arg, "0X%x", &oric->aciaoffset)) continue; - if( 1 == sscanf(opt_arg, "%d", &oric->aciaoffset) ) + if(1 == sscanf(opt_arg, "%d", &oric->aciaoffset)) continue; - exit( EXIT_FAILURE ); + exit(EXIT_FAILURE); } - if( strcasecmp( tmp, "serial" ) == 0 ) + if(strcasecmp(tmp, "serial") == 0) { oric->aciabackendcfg = oric->aciabackend = ACIA_TYPE_NONE; if(!strcasecmp("none", opt_arg)) @@ -769,17 +967,21 @@ SDL_bool init( struct machine *oric, int argc, char *argv[] ) oric->aciabackendcfg = oric->aciabackend = ACIA_TYPE_MODEM; oric->aciabackendcfgport = 0; oric->aciabackendcfgdomain = 4; - if(p) { + if(p) + { char* p2 = strchr(p+1, ':'); - if (p2) { - // check if we want IPv6 - if (strcasecmp(p2+1, "ipv6")==0) - oric->aciabackendcfgdomain = 6; - *p2 = '\0'; // temporarily place a \0 to isolate the port part of the string - oric->aciabackendcfgport = atoi(p+1); // get the port part of the string - *p2 = ':'; // put back the semicolon - } else { - oric->aciabackendcfgport = atoi(p+1); + if(p2) + { + // check if we want IPv6 + if(strcasecmp(p2+1, "ipv6")==0) + oric->aciabackendcfgdomain = 6; + *p2 = '\0'; // temporarily place a \0 to isolate the port part of the string + oric->aciabackendcfgport = atoi(p+1); // get the port part of the string + *p2 = ':'; // put back the semicolon + } + else + { + oric->aciabackendcfgport = atoi(p+1); } } if(oric->aciabackendcfgport <= 0) @@ -789,34 +991,61 @@ SDL_bool init( struct machine *oric, int argc, char *argv[] ) else { #ifdef BACKEND_COM - strncpy(oric->aciabackendname, opt_arg, ACIA_BACKEND_NAME_LEN); + strncpy(oric->aciabackendname, opt_arg, ACIA_BACKEND_NAME_LEN-1); + oric->aciabackendname[ACIA_BACKEND_NAME_LEN-1] = 0; oric->aciabackendcfg = oric->aciabackend = ACIA_TYPE_COM; #endif } continue; } - if( strcasecmp( tmp, "vsynchack" ) == 0 ) + if(strcasecmp(tmp, "vsynchack") == 0) { - if( !on_or_off( argv[i-1], opt_arg, &oric->vsynchack ) ) exit( EXIT_FAILURE ); + if(!on_or_off(argv[i-1], opt_arg, &oric->vsynchack)) exit(EXIT_FAILURE); continue; } - if( strcasecmp( tmp, "scanlines" ) == 0 ) + if(strcasecmp(tmp, "scanlines") == 0) { - if( !on_or_off( argv[i-1], opt_arg, &oric->scanlines ) ) exit( EXIT_FAILURE ); + if(!on_or_off(argv[i-1], opt_arg, &oric->scanlines)) exit(EXIT_FAILURE); continue; } + + if(strcasecmp(tmp, "statusbar") == 0) + { + if(opt_arg) + { + if(strcasecmp(opt_arg, "none") == 0) + { + oric->statusbar_mode = STATUSBARMODE_NONE; + continue; + } + if(strcasecmp(opt_arg, "full") == 0) + { + oric->statusbar_mode = STATUSBARMODE_FULL; + continue; + } + if(strcasecmp(opt_arg, "nofps") == 0) + { + oric->statusbar_mode = STATUSBARMODE_NOFPS; + continue; + } + } + + error_printf("Invalid statusbar mode"); + free(sto); + exit(EXIT_FAILURE); + } break; default: opt_type = argv[i][1]; opt_arg = NULL; - if (argv[i][2]) + if(argv[i][2]) opt_arg = &argv[i][2]; - else if ( i<(argc-1)) + else if(i<(argc-1)) { - switch (opt_type) + switch(opt_type) { case 'm': case 'd': @@ -827,48 +1056,48 @@ SDL_bool init( struct machine *oric, int argc, char *argv[] ) #ifdef __OPENGL_AVAILABLE__ case 'R': #endif - opt_arg = argv[i+1]; + opt_arg = argv[i+1]; i++; } } break; } - switch( opt_type ) + switch(opt_type) { case 'm': // Machine type - if( opt_arg ) + if(opt_arg) { - if(( strcasecmp( opt_arg, "atmos" ) == 0 ) || - ( strcasecmp( opt_arg, "a" ) == 0 )) + if((strcasecmp(opt_arg, "atmos") == 0) || + (strcasecmp(opt_arg, "a") == 0)) { sto->start_machine = MACH_ATMOS; sto->start_machine_set = SDL_TRUE; break; } - if(( strcasecmp( opt_arg, "oric1" ) == 0 ) || - ( strcasecmp( opt_arg, "1" ) == 0 )) + if((strcasecmp(opt_arg, "oric1") == 0) || + (strcasecmp(opt_arg, "1") == 0)) { sto->start_machine = MACH_ORIC1; sto->start_machine_set = SDL_TRUE; break; } - if( strcasecmp( opt_arg, "o16k" ) == 0 ) + if(strcasecmp(opt_arg, "o16k") == 0) { sto->start_machine = MACH_ORIC1_16K; sto->start_machine_set = SDL_TRUE; break; } - if(( strcasecmp( opt_arg, "telestrat" ) == 0 ) || - ( strcasecmp( opt_arg, "t" ) == 0 )) + if((strcasecmp(opt_arg, "telestrat") == 0) || + (strcasecmp(opt_arg, "t") == 0)) { sto->start_machine = MACH_TELESTRAT; sto->start_machine_set = SDL_TRUE; break; } - if(( strcasecmp( opt_arg, "pravetz" ) == 0 ) || - ( strcasecmp( opt_arg, "pravetz8d" ) == 0 ) || - ( strcasecmp( opt_arg, "p" ) == 0 )) + if((strcasecmp(opt_arg, "pravetz") == 0) || + (strcasecmp(opt_arg, "pravetz8d") == 0) || + (strcasecmp(opt_arg, "p") == 0)) { sto->start_machine = MACH_PRAVETZ; sto->start_machine_set = SDL_TRUE; @@ -876,78 +1105,86 @@ SDL_bool init( struct machine *oric, int argc, char *argv[] ) } } - error_printf( "Invalid machine type" ); - free( sto ); - exit( EXIT_FAILURE ); + error_printf("Invalid machine type"); + free(sto); + exit(EXIT_FAILURE); break; case 't': // Tape image - { - SDL_bool drop_through = SDL_FALSE; - if( opt_arg ) { - switch (detect_image_type(opt_arg)) + SDL_bool drop_through = SDL_FALSE; + if(opt_arg) { - case IMG_ATMOS_MICRODISC: - case IMG_ATMOS_JASMIN: - case IMG_TELESTRAT_DISK: - case IMG_PRAVETZ_DISK: - case IMG_GUESS_MICRODISC: - printf("'%s' seems to be a disk image.\n", opt_arg); - drop_through = SDL_TRUE; - break; - - case IMG_SNAPSHOT: - printf("'%s' seems to be a snapshot file.\n", opt_arg); - strncpy( sto->start_snapshot, opt_arg, 1024); - sto->start_snapshot[1023] = 0; - break; - - case IMG_TAPE: - default: - strncpy( sto->start_tape, opt_arg, 1024 ); - sto->start_tape[1023] = 0; - break; + switch(detect_image_type(opt_arg)) + { + case IMG_ATMOS_MICRODISC: + case IMG_ATMOS_JASMIN: + case IMG_TELESTRAT_DISK: + case IMG_BD500_DISK: + case IMG_PRAVETZ_DISK: + case IMG_GUESS_MICRODISC: + printf("'%s' seems to be a disk image.\n", opt_arg); + drop_through = SDL_TRUE; + break; + + case IMG_SNAPSHOT: + printf("'%s' seems to be a snapshot file.\n", opt_arg); + strncpy(sto->start_snapshot, opt_arg, 1024); + sto->start_snapshot[1023] = 0; + break; + + case IMG_TAPE: + default: + strncpy(sto->start_tape, opt_arg, 1024); + sto->start_tape[1023] = 0; + break; + } + } + else + { + error_printf("No tape image specified"); + free(sto); + exit(EXIT_FAILURE); } - } else { - error_printf( "No tape image specified" ); - free( sto ); - exit( EXIT_FAILURE ); - } - if (!drop_through) - break; - } + if(!drop_through) + break; + } case 'd': // Disk image - if( opt_arg ) + if(opt_arg) { - strncpy( sto->start_disk, opt_arg, 1024 ); + strncpy(sto->start_disk, opt_arg, 1024); sto->start_disk[1023] = 0; - switch (detect_image_type(sto->start_disk)) + switch(detect_image_type(sto->start_disk)) { case IMG_ATMOS_MICRODISC: - if (!sto->start_machine_set) sto->start_machine = MACH_ATMOS; - if (!sto->start_disktype_set) sto->start_disktype = DRV_MICRODISC; + if(!sto->start_machine_set) sto->start_machine = MACH_ATMOS; + if(!sto->start_disktype_set) sto->start_disktype = DRV_MICRODISC; break; case IMG_ATMOS_JASMIN: - if (!sto->start_machine_set) sto->start_machine = MACH_ATMOS; - if (!sto->start_disktype_set) sto->start_disktype = DRV_JASMIN; + if(!sto->start_machine_set) sto->start_machine = MACH_ATMOS; + if(!sto->start_disktype_set) sto->start_disktype = DRV_JASMIN; break; case IMG_TELESTRAT_DISK: - if (!sto->start_machine_set) sto->start_machine = MACH_TELESTRAT; - if (!sto->start_disktype_set) sto->start_disktype = DRV_MICRODISC; + if(!sto->start_machine_set) sto->start_machine = MACH_TELESTRAT; + if(!sto->start_disktype_set) sto->start_disktype = DRV_MICRODISC; + break; + + case IMG_BD500_DISK: + if(!sto->start_machine_set) sto->start_machine = MACH_ATMOS; + if(!sto->start_disktype_set) sto->start_disktype = DRV_BD500; break; case IMG_PRAVETZ_DISK: - if (!sto->start_machine_set) sto->start_machine = MACH_PRAVETZ; - if (!sto->start_disktype_set) sto->start_disktype = DRV_PRAVETZ; + if(!sto->start_machine_set) sto->start_machine = MACH_PRAVETZ; + if(!sto->start_disktype_set) sto->start_disktype = DRV_PRAVETZ; break; case IMG_GUESS_MICRODISC: - if (!sto->start_disktype_set) sto->start_disktype = DRV_MICRODISC; + if(!sto->start_disktype_set) sto->start_disktype = DRV_MICRODISC; break; case IMG_TAPE: @@ -958,43 +1195,61 @@ SDL_bool init( struct machine *oric, int argc, char *argv[] ) case IMG_SNAPSHOT: printf("'%s' seems to be a snapshot file.\n", opt_arg); - strncpy( sto->start_snapshot, opt_arg, 1024); + strncpy(sto->start_snapshot, opt_arg, 1024); sto->start_snapshot[1023] = 0; + sto->start_disk[0] = 0; break; } - } else { - error_printf( "No disk image specified" ); - free( sto ); - exit( EXIT_FAILURE ); + if(sto->start_disk[0]) + { + if(sto->start_disks_count < 4) + { + strcpy(sto->start_disks[sto->start_disks_count], sto->start_disk); + sto->start_disks_count++; + } + } + } + else + { + error_printf("No disk image specified"); + free(sto); + exit(EXIT_FAILURE); } break; case 'k': // Drive controller type - if( opt_arg ) + if(opt_arg) { - if(( strcasecmp( opt_arg, "microdisc" ) == 0 ) || - ( strcasecmp( opt_arg, "m" ) == 0 )) + if((strcasecmp(opt_arg, "microdisc") == 0) || + (strcasecmp(opt_arg, "m") == 0)) { sto->start_disktype = DRV_MICRODISC; sto->start_disktype_set = SDL_TRUE; break; } - if(( strcasecmp( opt_arg, "jasmin" ) == 0 ) || - ( strcasecmp( opt_arg, "j" ) == 0 )) + if((strcasecmp(opt_arg, "bd500") == 0) || + (strcasecmp(opt_arg, "b") == 0)) + { + sto->start_disktype = DRV_BD500; + sto->start_disktype_set = SDL_TRUE; + break; + } + if((strcasecmp(opt_arg, "jasmin") == 0) || + (strcasecmp(opt_arg, "j") == 0)) { sto->start_disktype = DRV_JASMIN; sto->start_disktype_set = SDL_TRUE; break; } - if(( strcasecmp( opt_arg, "pravetz" ) == 0 ) || - ( strcasecmp( opt_arg, "p" ) == 0 )) + if((strcasecmp(opt_arg, "pravetz") == 0) || + (strcasecmp(opt_arg, "p") == 0)) { sto->start_disktype = DRV_PRAVETZ; sto->start_disktype_set = SDL_TRUE; break; } - if(( strcasecmp( opt_arg, "none" ) == 0 ) || - ( strcasecmp( opt_arg, "n" ) == 0 )) + if((strcasecmp(opt_arg, "none") == 0) || + (strcasecmp(opt_arg, "n") == 0)) { sto->start_disktype = DRV_NONE; sto->start_disktype_set = SDL_FALSE; @@ -1002,29 +1257,32 @@ SDL_bool init( struct machine *oric, int argc, char *argv[] ) } } - error_printf( "Invalid drive type" ); - free( sto ); - exit( EXIT_FAILURE ); + error_printf("Invalid drive type"); + free(sto); + exit(EXIT_FAILURE); break; case 's': // Pre-load symbols file - if( opt_arg ) + if(opt_arg) { - if( sto->start_syms_count < 32 ) + if(sto->start_syms_count < 32) { - char* new_syms = strdup( opt_arg ); - if( NULL != new_syms ) + char* new_syms = strdup(opt_arg); + if(NULL != new_syms) sto->start_syms_files[sto->start_syms_count++] = new_syms; } - } else { - error_printf( "No symbols file specified" ); - free( sto ); - exit( EXIT_FAILURE ); + } + else + { + error_printf("No symbols file specified"); + free(sto); + exit(EXIT_FAILURE); } break; case 'f': fullscreen = SDL_TRUE; + oric->statusbar_mode = STATUSBARMODE_NONE; break; case 'w': @@ -1036,78 +1294,93 @@ SDL_bool init( struct machine *oric, int argc, char *argv[] ) break; case 'r': // Breakpoint - if( opt_arg ) + if(opt_arg) { sto->start_breakpoint = opt_arg; } else { - error_printf( "Breakpoint address or symbol expected" ); - free( sto ); - exit( EXIT_FAILURE ); + error_printf("Breakpoint address or symbol expected"); + free(sto); + exit(EXIT_FAILURE); } break; #ifdef __OPENGL_AVAILABLE__ case 'R': // Render mode - if( opt_arg ) + if(opt_arg) { - if( strcasecmp( opt_arg, "soft" ) == 0 ) { sto->start_rendermode = RENDERMODE_SW; break; } - if( strcasecmp( opt_arg, "opengl" ) == 0 ) { sto->start_rendermode = RENDERMODE_GL; break; } + if(strcasecmp(opt_arg, "soft") == 0) + { + sto->start_rendermode = RENDERMODE_SW; + break; + } + if(strcasecmp(opt_arg, "opengl") == 0) + { + sto->start_rendermode = RENDERMODE_GL; + break; + } } - error_printf( "Invalid render mode" ); - free( sto ); - exit( EXIT_FAILURE ); + error_printf("Invalid render mode"); + free(sto); + exit(EXIT_FAILURE); break; #endif case 'h': - free( sto ); - usage( EXIT_SUCCESS ); + free(sto); + usage(EXIT_SUCCESS); break; } } else { - switch (detect_image_type(argv[i])) + switch(detect_image_type(argv[i])) { case IMG_SNAPSHOT: - strncpy( sto->start_snapshot, argv[i], 1024); + strncpy(sto->start_snapshot, argv[i], 1024); sto->start_snapshot[1023] = 0; break; case IMG_ATMOS_MICRODISC: - if (!sto->start_machine_set) sto->start_machine = MACH_ATMOS; - if (!sto->start_disktype_set) sto->start_disktype = DRV_MICRODISC; - strncpy( sto->start_disk, argv[i], 1024 ); + if(!sto->start_machine_set) sto->start_machine = MACH_ATMOS; + if(!sto->start_disktype_set) sto->start_disktype = DRV_MICRODISC; + strncpy(sto->start_disk, argv[i], 1024); sto->start_disk[1023] = 0; break; case IMG_ATMOS_JASMIN: - if (!sto->start_machine_set) sto->start_machine = MACH_ATMOS; - if (!sto->start_disktype_set) sto->start_disktype = DRV_JASMIN; - strncpy( sto->start_disk, argv[i], 1024 ); + if(!sto->start_machine_set) sto->start_machine = MACH_ATMOS; + if(!sto->start_disktype_set) sto->start_disktype = DRV_JASMIN; + strncpy(sto->start_disk, argv[i], 1024); sto->start_disk[1023] = 0; break; case IMG_TELESTRAT_DISK: - if (!sto->start_machine_set) sto->start_machine = MACH_TELESTRAT; - if (!sto->start_disktype_set) sto->start_disktype = DRV_MICRODISC; - strncpy( sto->start_disk, argv[i], 1024 ); + if(!sto->start_machine_set) sto->start_machine = MACH_TELESTRAT; + if(!sto->start_disktype_set) sto->start_disktype = DRV_MICRODISC; + strncpy(sto->start_disk, argv[i], 1024); + sto->start_disk[1023] = 0; + break; + + case IMG_BD500_DISK: + if(!sto->start_machine_set) sto->start_machine = MACH_ATMOS; + if(!sto->start_disktype_set) sto->start_disktype = DRV_BD500; + strncpy(sto->start_disk, argv[i], 1024); sto->start_disk[1023] = 0; break; case IMG_PRAVETZ_DISK: - if (!sto->start_machine_set) sto->start_machine = MACH_PRAVETZ; - if (!sto->start_disktype_set) sto->start_disktype = DRV_PRAVETZ; - strncpy( sto->start_disk, argv[i], 1024 ); + if(!sto->start_machine_set) sto->start_machine = MACH_PRAVETZ; + if(!sto->start_disktype_set) sto->start_disktype = DRV_PRAVETZ; + strncpy(sto->start_disk, argv[i], 1024); sto->start_disk[1023] = 0; break; case IMG_GUESS_MICRODISC: - if (!sto->start_disktype_set) sto->start_disktype = DRV_MICRODISC; - strncpy( sto->start_disk, argv[i], 1024 ); + if(!sto->start_disktype_set) sto->start_disktype = DRV_MICRODISC; + strncpy(sto->start_disk, argv[i], 1024); sto->start_disk[1023] = 0; break; @@ -1117,36 +1390,131 @@ SDL_bool init( struct machine *oric, int argc, char *argv[] ) break; default: - free( sto ); - usage( EXIT_FAILURE ); + free(sto); + usage(EXIT_FAILURE); + } + if(sto->start_disk[0]) + { + if(sto->start_disks_count < 4) + { + strcpy(sto->start_disks[sto->start_disks_count], sto->start_disk); + sto->start_disks_count++; + } } } } - load_diskroms( oric ); + load_diskroms(oric); - if( ( sto->start_disk[0] ) && ( sto->start_disktype == DRV_NONE ) ) + if((sto->start_disk[0]) && (sto->start_disktype == DRV_NONE)) sto->start_disktype = DRV_MICRODISC; - for( i=0; i<8; i++ ) lastframetimes[i] = 0; + for(i=0; i<8; i++) lastframetimes[i] = 0; frametimeave = 0; - setoverclock( oric, NULL, 0 ); - if( !init_gui( oric, sto->start_rendermode ) ) { free( sto ); return SDL_FALSE; } - if( !init_filerequester( oric ) ) { free( sto ); return SDL_FALSE; } - if( !init_msgbox( oric ) ) { free( sto ); return SDL_FALSE; } + setoverclock(oric, NULL, 0); + if(!init_gui(oric, sto->start_rendermode)) + { + free(sto); + return SDL_FALSE; + } + if(!init_filerequester(oric)) + { + free(sto); + return SDL_FALSE; + } + if(!init_msgbox(oric)) + { + free(sto); + return SDL_FALSE; + } oric->drivetype = sto->start_disktype; - if( !init_ula( oric ) ) { free( sto ); return SDL_FALSE; } - if( !init_joy( oric ) ) { free( sto ); return SDL_FALSE; } - if( !init_machine( oric, sto->start_machine, SDL_TRUE ) ) { free( sto ); return SDL_FALSE; } + if(!init_ula(oric)) + { + free(sto); + return SDL_FALSE; + } + if(!init_joy(oric)) + { + free(sto); + return SDL_FALSE; + } + if(!init_machine(oric, sto->start_machine, SDL_TRUE)) + { + free(sto); + return SDL_FALSE; + } - if( sto->start_disk[0] ) + if(sto->start_disk[0]) { - diskimage_load( oric, sto->start_disk, 0 ); - switch (oric->drivetype) +#ifdef WWW + // NOT SURE WHY I HAD TO DO THIS ??? + if(sto->start_disk[0]) + { + if(sto->start_disks_count < 4) + { + strcpy(sto->start_disks[sto->start_disks_count], sto->start_disk); + sto->start_disks_count++; + } + } +#endif + switch(detect_image_type(sto->start_disk)) + { + case IMG_ATMOS_MICRODISC: + if(!sto->start_machine_set) sto->start_machine = MACH_ATMOS; + if(!sto->start_disktype_set) sto->start_disktype = DRV_MICRODISC; + break; + + case IMG_ATMOS_JASMIN: + if(!sto->start_machine_set) sto->start_machine = MACH_ATMOS; + if(!sto->start_disktype_set) sto->start_disktype = DRV_JASMIN; + break; + + case IMG_TELESTRAT_DISK: + if(!sto->start_machine_set) sto->start_machine = MACH_TELESTRAT; + if(!sto->start_disktype_set) sto->start_disktype = DRV_MICRODISC; + break; + + case IMG_BD500_DISK: + if(!sto->start_machine_set) sto->start_machine = MACH_ATMOS; + if(!sto->start_disktype_set) sto->start_disktype = DRV_BD500; + break; + + case IMG_PRAVETZ_DISK: + if(!sto->start_machine_set) sto->start_machine = MACH_PRAVETZ; + if(!sto->start_disktype_set) sto->start_disktype = DRV_PRAVETZ; + break; + + case IMG_GUESS_MICRODISC: + if(!sto->start_disktype_set) sto->start_disktype = DRV_MICRODISC; + break; + + case IMG_TAPE: + printf("'%s' seems to be a tape image.\n", sto->start_disk); + strcpy(sto->start_tape, sto->start_disk); + sto->start_disk[0] = 0; + break; + + case IMG_SNAPSHOT: + printf("'%s' seems to be a snapshot file.\n", opt_arg); + strncpy(sto->start_snapshot, opt_arg, 1024); + sto->start_snapshot[1023] = 0; + sto->start_disk[0] = 0; + break; + } + + for(i=0; i<4; i++) + { + disk_eject(oric, i); + } + for(i=0; istart_disks_count; i++) + { + diskimage_load(oric, sto->start_disks[i], i); + } + switch(oric->drivetype) { case DRV_PRAVETZ: - pravdiskboot( oric ); + pravdiskboot(oric); break; case DRV_JASMIN: @@ -1154,63 +1522,64 @@ SDL_bool init( struct machine *oric, int argc, char *argv[] ) break; } } - if( sto->start_tape[0] ) + if(sto->start_tape[0]) { - if( tape_load_tap( oric, sto->start_tape ) ) - queuekeys( "CLOAD\"\"\x0d" ); + if(tape_load_tap(oric, sto->start_tape)) + queuekeys("CLOAD\"\"\x0d"); } - mon_init( oric ); - if( sto->start_syms[0] ) - mon_new_symbols( &oric->usersyms, oric, sto->start_syms, SYM_BESTGUESS, SDL_TRUE, SDL_TRUE ); +#ifndef WWW_NO_MONITOR + mon_init(oric); + if(sto->start_syms[0]) + mon_new_symbols(&oric->usersyms, oric, sto->start_syms, SYM_BESTGUESS, SDL_TRUE, SDL_TRUE); - for( i=0; istart_syms_count; i++ ) + for(i=0; istart_syms_count; i++) { - if( NULL!=sto->start_syms_files[i] ) + if(NULL!=sto->start_syms_files[i]) { - mon_new_symbols( &oric->usersyms, oric, sto->start_syms_files[i], SYM_BESTGUESS, SDL_TRUE, SDL_TRUE ); + mon_new_symbols(&oric->usersyms, oric, sto->start_syms_files[i], SYM_BESTGUESS, SDL_TRUE, SDL_TRUE); free(sto->start_syms_files[i]); sto->start_syms_files[i] = NULL; } } sto->start_syms_count = 0; - if( sto->start_breakpoint ) + if(sto->start_breakpoint) { - if( sto->start_breakpoint[0] == ':' ) + if(sto->start_breakpoint[0] == ':') { SDL_bool needrender = SDL_FALSE; char bsbuf[32]; char* fn = sto->start_breakpoint + 1; - FILE* f = fopen( fn, "rt" ); - if( !f ) + FILE* f = fopen(fn, "rt"); + if(!f) { - error_printf( "Invalid breakpoint file" ); - free( sto ); + error_printf("Invalid breakpoint file"); + free(sto); return SDL_FALSE; } - while( !feof( f ) ) + while(!feof(f)) { char* p; - if( !fgets( bsbuf, 32, f ) ) break; + if(!fgets(bsbuf, 32, f)) break; bsbuf[31] = 0; - while( NULL != (p = strchr( bsbuf, '\r' )) ) *p = 0; - while( NULL != (p = strchr( bsbuf, '\n' )) ) *p = 0; - while( NULL != (p = strchr( bsbuf, '\t' )) ) *p = ' '; + while(NULL != (p = strchr(bsbuf, '\r'))) *p = 0; + while(NULL != (p = strchr(bsbuf, '\n'))) *p = 0; + while(NULL != (p = strchr(bsbuf, '\t'))) *p = ' '; p = bsbuf; - while( *p && isws( *p ) ) p++; - if( *p ) mon_cmd( bsbuf, oric, &needrender ); + while(*p && isws(*p)) p++; + if(*p) mon_cmd(bsbuf, oric, &needrender); } - fclose( f ); + fclose(f); } else { int off = 0; unsigned int addr; - if( !mon_getnum( oric, &addr, sto->start_breakpoint, &off, SDL_FALSE, SDL_FALSE, SDL_FALSE, SDL_TRUE ) ) + if(!mon_getnum(oric, &addr, sto->start_breakpoint, &off, SDL_FALSE, SDL_FALSE, SDL_FALSE, SDL_TRUE)) { - error_printf( "Invalid breakpoint" ); - free( sto ); + error_printf("Invalid breakpoint"); + free(sto); return SDL_FALSE; } @@ -1219,60 +1588,65 @@ SDL_bool init( struct machine *oric, int argc, char *argv[] ) } } - if( sto->start_snapshot[0] ) - load_snapshot( oric, sto->start_snapshot ); - - if( sto->start_debug ) - setemumode( oric, NULL, EM_DEBUG ); + if(sto->start_snapshot[0]) + load_snapshot(oric, sto->start_snapshot); - free( sto ); + if(sto->start_debug) + setemumode(oric, NULL, EM_DEBUG); +#endif + free(sto); return SDL_TRUE; } -void shut( struct machine *oric ) +void shut(struct machine *oric) { - if( vidcap ) avi_close( &vidcap ); + if(vidcap) avi_close(&vidcap); #if defined(DEBUG_CPU_TRACE) && DEBUG_CPU_TRACE > 0 dump_cputrace(oric); #endif - if( oric ) + if(oric) { - shut_machine( oric ); - shut_joy( oric ); - shut_ula( oric ); - mon_shut( oric ); - shut_filerequester( oric ); - shut_msgbox( oric ); - shut_gui( oric ); + shut_machine(oric); + shut_joy(oric); + shut_ula(oric); +#ifndef WWW_NO_MONITOR + mon_shut(oric); +#endif + shut_filerequester(oric); + shut_msgbox(oric); + shut_gui(oric); } - if( need_sdl_quit ) SDL_COMPAT_Quit(); + if(need_sdl_quit) + SDL_COMPAT_Quit(SDL_TRUE); } -void frameloop_overclock( struct machine *oric, SDL_bool *framedone, SDL_bool *needrender ) +void frameloop_overclock(struct machine *oric, SDL_bool *framedone, SDL_bool *needrender) { int instloop, instcycles; - while( ( !(*framedone) ) && ( !(*needrender) ) ) + while((!(*framedone)) && (!(*needrender))) { - while( oric->cpu.rastercycles > 0 ) + while(oric->cpu.rastercycles > 0) { /* Do as many instructions as the overclock multiple */ - for( instloop=0, instcycles=0; instloop < oric->overclockmult; instloop++ ) + for(instloop=0, instcycles=0; instloop < oric->overclockmult; instloop++) { - if( m6502_set_icycles( &oric->cpu, SDL_TRUE, mon_bpmsg ) ) + if(m6502_set_icycles(&oric->cpu, SDL_TRUE, mon_bpmsg)) { +#ifndef WWW_NO_MONITOR // Hit breakpoint - setemumode( oric, NULL, EM_DEBUG ); + setemumode(oric, NULL, EM_DEBUG); *needrender = SDL_TRUE; +#endif break; } instcycles += oric->cpu.icycles; - tape_patches( oric ); + tape_patches(oric); - if( instloop < (oric->overclockmult-1) ) + if(instloop < (oric->overclockmult-1)) { - if (m6502_inst( &oric->cpu )) + if(m6502_inst(&oric->cpu)) break; } } @@ -1281,105 +1655,131 @@ void frameloop_overclock( struct machine *oric, SDL_bool *framedone, SDL_bool *n instcycles >>= oric->overclockshift; /* Move the emulation on */ - via_clock( &oric->via, instcycles ); - ay_ticktock( &oric->ay, instcycles ); - if((oric->drivetype == DRV_MICRODISC) || (oric->drivetype == DRV_JASMIN)) wd17xx_ticktock( &oric->wddisk, instcycles ); - if( oric->type == MACH_TELESTRAT ) + via_clock(&oric->via, instcycles); + ay_ticktock(&oric->ay, instcycles); + + switch(oric->drivetype) { - via_clock( &oric->tele_via, instcycles ); + case DRV_MICRODISC: + case DRV_BD500: + case DRV_JASMIN: + wd17xx_ticktock(&oric->wddisk, instcycles); + break; } - if( oric->aciabackend ) - acia_clock( &oric->tele_acia, instcycles ); + + if(oric->type == MACH_TELESTRAT) + { + via_clock(&oric->tele_via, instcycles); + } + if(oric->aciabackend) + acia_clock(&oric->tele_acia, instcycles); oric->cpu.rastercycles -= instcycles; /* If we hit a breakpoint above, we do not want to execute the */ /* instruction that caused the breakpoint */ - if( oric->emu_mode != EM_RUNNING ) break; - if( m6502_inst( &oric->cpu ) ) + if(oric->emu_mode != EM_RUNNING) break; + if(m6502_inst(&oric->cpu)) { // Hit JAM instruction - mon_printf_above( "Opcode %02X executed at %04X", oric->cpu.calcop, oric->cpu.lastpc ); - setemumode( oric, NULL, EM_DEBUG ); +#ifndef WWW_NO_MONITOR + mon_printf_above("Opcode %02X executed at %04X", oric->cpu.calcop, oric->cpu.lastpc); + setemumode(oric, NULL, EM_DEBUG); *needrender = SDL_TRUE; +#endif break; } } - if( oric->cpu.rastercycles <= 0 ) + if(oric->cpu.rastercycles <= 0) { - *framedone = ula_doraster( oric ); + *framedone = ula_doraster(oric); oric->cpu.rastercycles += oric->cyclesperraster; } } } -void frameloop_normal( struct machine *oric, SDL_bool *framedone, SDL_bool *needrender ) +void frameloop_normal(struct machine *oric, SDL_bool *framedone, SDL_bool *needrender) { - while( ( !(*framedone) ) && ( !(*needrender) ) ) + while((!(*framedone)) && (!(*needrender))) { - while( oric->cpu.rastercycles > 0 ) + while(oric->cpu.rastercycles > 0) { - if( m6502_set_icycles( &oric->cpu, SDL_TRUE, mon_bpmsg ) ) + if(m6502_set_icycles(&oric->cpu, SDL_TRUE, mon_bpmsg)) { +#ifndef WWW_NO_MONITOR // Hit breakpoint - setemumode( oric, NULL, EM_DEBUG ); + setemumode(oric, NULL, EM_DEBUG); *needrender = SDL_TRUE; +#endif break; } - tape_patches( oric ); - via_clock( &oric->via, oric->cpu.icycles ); - ay_ticktock( &oric->ay, oric->cpu.icycles ); - if((oric->drivetype == DRV_MICRODISC) || (oric->drivetype == DRV_JASMIN)) wd17xx_ticktock( &oric->wddisk, oric->cpu.icycles ); - if( oric->type == MACH_TELESTRAT ) + if(!oric->twilighteboard_activated) + tape_patches(oric); + + via_clock(&oric->via, oric->cpu.icycles); + ay_ticktock(&oric->ay, oric->cpu.icycles); + + switch(oric->drivetype) + { + case DRV_MICRODISC: + case DRV_BD500: + case DRV_JASMIN: + wd17xx_ticktock(&oric->wddisk, oric->cpu.icycles); + break; + } + + if(oric->type == MACH_TELESTRAT) { - via_clock( &oric->tele_via, oric->cpu.icycles ); + via_clock(&oric->tele_via, oric->cpu.icycles); } - if( oric->aciabackend ) - acia_clock( &oric->tele_acia, oric->cpu.icycles ); + if(oric->aciabackend) + acia_clock(&oric->tele_acia, oric->cpu.icycles); oric->cpu.rastercycles -= oric->cpu.icycles; - if( m6502_inst( &oric->cpu ) ) + if(m6502_inst(&oric->cpu)) { +#ifndef WWW_NO_MONITOR // Hit JAM instruction - mon_printf_above( "Opcode %02X executed at %04X", oric->cpu.calcop, oric->cpu.lastpc ); - setemumode( oric, NULL, EM_DEBUG ); + mon_printf_above("Opcode %02X executed at %04X", oric->cpu.calcop, oric->cpu.lastpc); + setemumode(oric, NULL, EM_DEBUG); *needrender = SDL_TRUE; +#endif break; } } - if( oric->cpu.rastercycles <= 0 ) + if(oric->cpu.rastercycles <= 0) { - *framedone = ula_doraster( oric ); + *framedone = ula_doraster(oric); oric->cpu.rastercycles += oric->cyclesperraster; } } } /* Tasks to do once per emulated frame */ -void once_per_frame( struct machine *oric ) +void once_per_frame(struct machine *oric) { int i; - if( oric->diskautosave ) + if(oric->diskautosave) { - for( i=0; i<4; i++ ) + for(i=0; i<4; i++) { - if( ( oric->wddisk.disk[i] ) && ( oric->wddisk.disk[i]->modified ) ) + if((oric->wddisk.disk[i]) && (oric->wddisk.disk[i]->modified)) { oric->wddisk.disk[i]->modified_time++; - if( oric->wddisk.disk[i]->modified_time >= 20 ) + if(oric->wddisk.disk[i]->modified_time >= 20) { - diskimage_save( oric, oric->wddisk.disk[i]->filename, i ); + diskimage_save(oric, oric->wddisk.disk[i]->filename, i); } } } } } -static void loop_handler( void* arg ) +static void loop_handler(void* arg) { struct context* ctx = arg; struct machine* oric = &ctx->oric; @@ -1388,28 +1788,28 @@ static void loop_handler( void* arg ) SDL_bool done = SDL_FALSE; Sint32 i; - while (!done) + while(!done) { - if ( oric->emu_mode == EM_PLEASEQUIT ) + if(oric->emu_mode == EM_PLEASEQUIT) break; - if ( oric->emu_mode == EM_RUNNING ) + if(oric->emu_mode == EM_RUNNING) { - if (oric->overclockmult == 1) - frameloop_normal( oric, &ctx->framedone, &ctx->needrender ); + if(oric->overclockmult == 1) + frameloop_normal(oric, &ctx->framedone, &ctx->needrender); else - frameloop_overclock( oric, &ctx->framedone, &ctx->needrender ); + frameloop_overclock(oric, &ctx->framedone, &ctx->needrender); - ay_unlockaudio( &oric->ay ); + ay_unlockaudio(&oric->ay); - if (ctx->framedone) + if(ctx->framedone) { ctx->nextframe_us += oric->vid_freq ? 20000LL : 16667LL; ctx->nextframe_ms = (Uint32)(ctx->nextframe_us / 1000LL); - if (warpspeed) + if(warpspeed) { - if ((oric->frames&3)==0) + if((oric->frames&3)==0) ctx->needrender = SDL_TRUE; } else @@ -1418,21 +1818,21 @@ static void loop_handler( void* arg ) } } - if (ctx->needrender) + if(ctx->needrender) { - render( oric ); + render(oric); ctx->needrender = SDL_FALSE; } - if (ctx->framedone) + if(ctx->framedone) { - once_per_frame( oric ); + once_per_frame(oric); ctx->then = ctx->now; ctx->now = SDL_GetTicks(); frametimeave = 0; - for (i = (FRAMES_TO_AVERAGE - 1); i > 0; i--) + for(i = (FRAMES_TO_AVERAGE - 1); i > 0; i--) { lastframetimes[i] = lastframetimes[i - 1]; frametimeave += lastframetimes[i]; @@ -1440,14 +1840,14 @@ static void loop_handler( void* arg ) lastframetimes[0] = ctx->now - ctx->then; frametimeave = (frametimeave + lastframetimes[0]) / FRAMES_TO_AVERAGE; - if (warpspeed) + if(warpspeed) { ctx->nextframe_ms = ctx->now; ctx->nextframe_us = ((Uint64)ctx->nextframe_ms) * 1000; } else { - if (ctx->now > ctx->nextframe_ms) + if(ctx->now > ctx->nextframe_ms) { ctx->nextframe_ms = ctx->now; ctx->nextframe_us = ((Uint64)ctx->nextframe_ms) * 1000; @@ -1460,67 +1860,283 @@ static void loop_handler( void* arg ) ctx->framedone = SDL_FALSE; } - if (!SDL_PollEvent(event)) +#if defined(WWW) + if(!SDL_PollEvent(event)) + break; +#else + if(!SDL_PollEvent(event)) continue; +#endif } else { - ay_unlockaudio( &oric->ay ); - if (ctx->needrender) + ay_unlockaudio(&oric->ay); + if(ctx->needrender) { - render( oric ); + render(oric); ctx->needrender = SDL_FALSE; } - if (!SDL_WaitEvent(event)) +#if defined(WWW) + if(!SDL_PollEvent(event)) + break; +#else + if(!SDL_WaitEvent(event)) break; +#endif } - do { - switch (event->type) + do + { + switch(event->type) { case SDL_COMPAT_ACTIVEEVENT: - { - if (SDL_COMPAT_IsAppActive(event)) { - oric->shut_render(oric); - oric->init_render(oric); - ctx->needrender = SDL_TRUE; + if(SDL_COMPAT_IsAppActive(event)) + { + oric->shut_render(oric); + oric->init_render(oric); + ctx->needrender = SDL_TRUE; + } } - } - break; + break; case SDL_QUIT: done = SDL_TRUE; break; default: - switch ( oric->emu_mode ) + switch(oric->emu_mode) { case EM_MENU: - done |= menu_event( event, oric, &ctx->needrender ); + done |= menu_event(event, oric, &ctx->needrender); break; case EM_RUNNING: - done |= emu_event( event, oric, &ctx->needrender ); + done |= emu_event(event, oric, &ctx->needrender); break; - +#ifndef WWW_NO_MONITOR case EM_DEBUG: - done |= mon_event( event, oric, &ctx->needrender ); + done |= mon_event(event, oric, &ctx->needrender); break; +#endif } } - if (oric->show_keyboard) - keyboard_event( event, oric, &ctx->needrender ); + if(oric->show_keyboard) + keyboard_event(event, oric, &ctx->needrender); + } + while(SDL_PollEvent(event)); + +#if defined(WWW) + // 1 loop only because emscripten will simulate the actual looping + done = SDL_TRUE; +#endif + + } +#if defined(WWW) +#else + ay_unlockaudio(&oric->ay); + shut(oric); +#endif +} + +#ifdef WWW + +#include +#include +#include + +struct context *gCtx = NULL; + +void success(char* path, const char* fileToLoad) +{ + int i; + printf("Loading disk %s\n", fileToLoad); + switch(detect_image_type(path)) + { + case IMG_SNAPSHOT: + load_snapshot(&gCtx->oric, path); + break; + + case IMG_ATMOS_MICRODISC: + if((gCtx->oric.type != MACH_ATMOS) && + (gCtx->oric.type != MACH_ORIC1) && + (gCtx->oric.type != MACH_PRAVETZ)) + { + swapmach(&gCtx->oric, NULL, (DRV_MICRODISC<<16)|MACH_ATMOS); + break; + } + + if((gCtx->oric.drivetype != DRV_MICRODISC) && + (gCtx->oric.drivetype != DRV_NONE)) + { + swapmach(&gCtx->oric, NULL, (DRV_MICRODISC<<16)|gCtx->oric.type); + } + break; + + case IMG_ATMOS_JASMIN: + if((gCtx->oric.type != MACH_ATMOS) && + (gCtx->oric.type != MACH_ORIC1) && + (gCtx->oric.type != MACH_PRAVETZ)) + { + swapmach(&gCtx->oric, NULL, (DRV_JASMIN<<16)|MACH_ATMOS); + gCtx->oric.auto_jasmin_reset = SDL_TRUE; + break; + } + + if(gCtx->oric.drivetype == DRV_NONE) + { + swapmach(&gCtx->oric, NULL, (DRV_JASMIN<<16)|gCtx->oric.type); + gCtx->oric.auto_jasmin_reset = SDL_TRUE; + break; + } + + if(gCtx->oric.drivetype != DRV_JASMIN) + { + swapmach(&gCtx->oric, NULL, (DRV_JASMIN<<16)|gCtx->oric.type); + gCtx->oric.auto_jasmin_reset = SDL_TRUE; + break; + } + break; + + case IMG_TELESTRAT_DISK: + if(gCtx->oric.type != MACH_TELESTRAT) + { + swapmach(&gCtx->oric, NULL, MACH_TELESTRAT); + break; + } + break; + + case IMG_PRAVETZ_DISK: + if(gCtx->oric.type != MACH_PRAVETZ) + { + swapmach(&gCtx->oric, NULL, (DRV_PRAVETZ<<16)|MACH_PRAVETZ); + pravdiskboot(&gCtx->oric); + break; + } + + if(gCtx->oric.drivetype == DRV_NONE) + { + swapmach(&gCtx->oric, NULL, (DRV_PRAVETZ<<16)|MACH_PRAVETZ); + pravdiskboot(&gCtx->oric); + break; + } - } while ( SDL_PollEvent( event ) ); + if(gCtx->oric.drivetype != DRV_PRAVETZ) + { + swapmach(&gCtx->oric, NULL, (DRV_PRAVETZ<<16)|MACH_PRAVETZ); + pravdiskboot(&gCtx->oric); + break; + } + break; + + case IMG_GUESS_MICRODISC: + if(gCtx->oric.drivetype == DRV_PRAVETZ) + { + swapmach(&gCtx->oric, NULL, (DRV_MICRODISC<<16)|gCtx->oric.type); + break; + } + break; + + case IMG_TAPE: + gCtx->oric.lasttapefile[0] = 0; + tape_load_tap(&(gCtx->oric), path); +#ifndef WWW_NO_MONITOR + if(gCtx->oric.symbolsautoload) mon_new_symbols(&gCtx->oric.usersyms, &(gCtx->oric), "symbols", SYM_BESTGUESS, SDL_TRUE, SDL_TRUE); +#endif + queuekeys("CLOAD\"\"\x0d"); + return; } + diskimage_load(&(gCtx->oric), path, 0); + + if(gCtx->oric.drivetype == DRV_NONE) { - ay_unlockaudio(&oric->ay); - shut(oric); + swapmach(&(gCtx->oric), NULL, (DRV_MICRODISC<<16)|gCtx->oric.type); + return; + } +} + +void downloadSucceeded(emscripten_fetch_t* fetch) +{ + int fd; + char path[1024]; + + printf("Finished downloading %llu bytes from URL %s.\n", fetch->numBytes, fetch->url); + // The data is now available at fetch->data[0] through fetch->data[fetch->numBytes-1]; + printf("%s\n",fetch->data); + printf("status %d\n",fetch->status); + + sprintf(path, "/readwritefs/%s", fetch->url), + fd = open(path, O_RDWR | O_CREAT, 0666); + if(fd == -1) + perror("Failing to create file"); + else + { + if(write(fd, fetch->data, fetch->numBytes) != fetch->numBytes) + { + perror("Failing to write to file"); + } + else if(close(fd) != 0) + { + perror("Failing to close file"); + } + else + { + success(path, fetch->url); + } } + + // sync from memory state to persisted + EM_ASM( + FS.syncfs(function(err) + { + assert(!err); + }); + ); + + emscripten_fetch_close(fetch); // Free data associated with the fetch. } -int main( int argc, char *argv[] ) +void downloadFailed(emscripten_fetch_t* fetch) +{ + printf("Downloading %s failed, HTTP failure status code: %d.\n", fetch->url, fetch->status); + emscripten_fetch_close(fetch); // Also free data on failure. +} + +void EMSCRIPTEN_KEEPALIVE www_async_dload() +{ + + // is the file here + char* fileToLoad = getenv("FILE"); + + printf("Downloading file %s\n", fileToLoad); + + if(fileToLoad == NULL) + return; + + char path[1024]; + sprintf(path, "/readwritefs/%s", fileToLoad); + + int fd = open(path, O_RDWR); + if(fd == -1) + { + emscripten_fetch_attr_t attr; + emscripten_fetch_attr_init(&attr); + strcpy(attr.requestMethod, "GET"); + attr.attributes = EMSCRIPTEN_FETCH_LOAD_TO_MEMORY; + + attr.onsuccess = downloadSucceeded; + attr.onerror = downloadFailed; + emscripten_fetch(&attr, fileToLoad); + } + else + { + printf("%s is already downloaded!\n", fileToLoad); + success(path, fileToLoad); + } +} +#endif + +int main(int argc, char* argv[]) { static struct context ctx; @@ -1533,26 +2149,29 @@ int main( int argc, char *argv[] ) putenv("SDL_VIDEO_CENTERED=center"); #endif - // ---------------------------------------------------------------------------- - // This makes relative paths work in C++ in Xcode by changing directory to the Resources folder inside the .app bundle +#ifndef WWW + init_fileprefix(argv); +#endif + // ---------------------------------------------------------------------------- + // This makes relative paths work in C++ in Xcode by changing directory to the Resources folder inside the .app bundle #ifdef __APPLE__ - CFBundleRef mainBundle = CFBundleGetMainBundle(); - CFURLRef resourcesURL = CFBundleCopyResourcesDirectoryURL(mainBundle); - char path[PATH_MAX]; - if (!CFURLGetFileSystemRepresentation(resourcesURL, TRUE, (UInt8 *)path, PATH_MAX)) - { - // error! - } - CFRelease(resourcesURL); - // this directory is something/Oricutron.app/Contents/Resources - // go down 3 times to find the app containing directory - strcat(path, "/../../.."); - chdir(path); - //printf("Current Path: %s\n", path); + CFBundleRef mainBundle = CFBundleGetMainBundle(); + CFURLRef resourcesURL = CFBundleCopyResourcesDirectoryURL(mainBundle); + char path[PATH_MAX]; + if(!CFURLGetFileSystemRepresentation(resourcesURL, TRUE, (UInt8 *)path, PATH_MAX)) + { + // error! + } + CFRelease(resourcesURL); + // this directory is something/Oricutron.app/Contents/Resources + // go down 3 times to find the app containing directory + strcat(path, "/../../.."); + chdir(path); + //printf("Current Path: %s\n", path); #endif memset(&ctx.oric, 0, sizeof(ctx.oric)); - if (!init(&ctx.oric, argc, argv)) + if(!init(&ctx.oric, argc, argv)) { shut(&ctx.oric); return EXIT_FAILURE; @@ -1564,13 +2183,34 @@ int main( int argc, char *argv[] ) ctx.needrender = SDL_TRUE; ctx.framedone = SDL_FALSE; - if (load_keymap) + if(load_keymap) { load_keyboard_mapping(&ctx.oric, keymap_path); load_keymap = SDL_FALSE; } +#ifdef WWW + // save the context to a global + gCtx = &ctx; + // create read-write fs + EM_ASM( + FS.mkdir('/readwritefs'); + FS.mount(IDBFS, {}, '/readwritefs'); + + // sync from persisted state into memory and then + // run the 'www_async_dload' function + FS.syncfs(true, function(err) + { + assert(!err); + // async download of space1999-fr.dsk + ccall('www_async_dload', 'v'); + }); + ); + + emscripten_set_main_loop_arg(loop_handler, &ctx, -1, 0); +#else loop_handler(&ctx); +#endif return EXIT_SUCCESS; } diff --git a/main.h b/main.h index 2a580deb..fc9ba71f 100644 --- a/main.h +++ b/main.h @@ -18,8 +18,8 @@ ** */ -SDL_bool read_config_string( char *buf, char *token, char *dest, Sint32 maxlen ); -SDL_bool read_config_bool( char *buf, char *token, SDL_bool *dest ); -SDL_bool read_config_option( char *buf, char *token, Sint32 *dest, char **options ); -SDL_bool read_config_int( char *buf, char *token, int *dest, int min, int max ); -void shut( struct machine *oric ); +SDL_bool read_config_string(char* buf, char* token, char* dest, Sint32 maxlen); +SDL_bool read_config_bool(char* buf, char* token, SDL_bool *dest); +SDL_bool read_config_option(char* buf, char* token, Sint32 *dest, char** options); +SDL_bool read_config_int(char* buf, char* token, int* dest, int min, int max); +void shut(struct machine *oric); diff --git a/monitor.c b/monitor.c index 3660bf33..0bd0adba 100644 --- a/monitor.c +++ b/monitor.c @@ -19,6 +19,8 @@ ** Monitor/Debugger */ +#ifndef WWW_NO_MONITOR + #define MAX_CONS_INPUT 127 // Max line length in console #define MAX_ASM_INPUT 36 #define CONS_WIDTH 46 // Actual console width for input @@ -29,7 +31,12 @@ #include #include +#endif + #include "system.h" + +#ifndef WWW_NO_MONITOR + #undef REG_PC // MorphOS should not define REG_PC #define REG_PC _REG_PC #include "6502.h" @@ -43,27 +50,28 @@ #include "ula.h" #include "tape.h" #include "snapshot.h" +#include "plugins/twilighte_board/oric_twilighte_board_plugin.h" #define LOG_DEBUG 0 #if LOG_DEBUG #if defined(__amigaos4__) || defined(__MORPHOS__) -static char *debug_logname = "RAM:debug.log"; +static char* debug_logname = "RAM:debug.log"; #else -static char *debug_logname = "debug_log.txt"; +static char* debug_logname = "debug_log.txt"; #endif FILE *debug_logfile = NULL; #endif struct disinf { - char *name; + char* name; int amode; }; struct asminf { - char *name; + char* name; short imp, imm, zp, zpx, zpy, abs, abx, aby, zix, ziy, rel, ind; }; @@ -87,11 +95,16 @@ static int ilen, iloff=0, cursx, histu=0, histp=-1; static unsigned short mon_addr, mon_asmmode = SDL_FALSE; static SDL_bool kshifted = SDL_FALSE, updatepreview = SDL_FALSE; static int helpcount=0; +static int memory_search_pos=0; static struct symboltable defaultsyms; +#endif + char mon_bpmsg[80]; +#ifndef WWW_NO_MONITOR + static SDL_bool mw_split = SDL_FALSE; static int mw_which = 0; static unsigned short mw_addr[2]; @@ -110,70 +123,87 @@ static struct via via2_old; static SDL_bool via2_oldvalid = SDL_FALSE; static SDL_bool modified = SDL_FALSE; +static uint16_t memory_search[0x9800-0x0500]; +static int memory_hits= 0; + +// auto repeat commands +enum +{ + ARPT_NULL = 0, + ARPT_SEARCH = 1, + ARPT_HELP = '?', + ARPT_MEMORY = 'm', + ARPT_DISASM = 'd', + ARPT_ASSEM = 'a', + ARPT_QUIT = 'q', +}; + // 12345678901 12345678 -static struct msym defsym_tele[] = { { 0x0300, 0, "VIA_IORB" , "VIA_IORB" , "VIA_IORB" }, - { 0x0301, 0, "VIA_IORA" , "VIA_IORA" , "VIA_IORA" }, - { 0x0302, 0, "VIA_DDRB" , "VIA_DDRB" , "VIA_DDRB" }, - { 0x0303, 0, "VIA_DDRA" , "VIA_DDRA" , "VIA_DDRA" }, - { 0x0304, 0, "VIA_T1C_L" , "VIA_T1C\x16", "VIA_T1C_L" }, - { 0x0305, 0, "VIA_T1C_H" , "VIA_T1C\x16", "VIA_T1C_H" }, - { 0x0306, 0, "VIA_T1L_L" , "VIA_T1L\x16", "VIA_T1L_L" }, - { 0x0307, 0, "VIA_T1L_H" , "VIA_T1L\x16", "VIA_T1L_H" }, - { 0x0308, 0, "VIA_T2C_L" , "VIA_T2C\x16", "VIA_T2C_L" }, - { 0x0309, 0, "VIA_T2C_H" , "VIA_T2C\x16", "VIA_T2C_H" }, - { 0x030A, 0, "VIA_SR" , "VIA_SR" , "VIA_SR" }, - { 0x030B, 0, "VIA_ACR" , "VIA_ACR" , "VIA_ACR" }, - { 0x030C, 0, "VIA_PCR" , "VIA_PCR" , "VIA_PCR" }, - { 0x030D, 0, "VIA_IFR" , "VIA_IFR" , "VIA_IFR" }, - { 0x030E, 0, "VIA_IER" , "VIA_IER" , "VIA_IER" }, - { 0x030F, 0, "VIA_IORA2" , "VIA_IORA2" , "VIA_IORA2" }, - { 0x0310, 0, "WD17_COMMA\x16", "WD17_CO\x16", "WD17_COMMAND" }, - { 0x0311, 0, "WD17_TRACK\x16", "WD17_TR\x16", "WD17_TRACK" }, - { 0x0312, 0, "WD17_SECTO\x16", "WD17_SE\x16", "WD17_SECTOR" }, - { 0x0313, 0, "WD17_DATA" , "WD17_DA\x16", "WD17_DATA" }, - { 0x0314, 0, "MDSC_STATUS" , "MDSC_ST\x16", "MDSC_STATUS" }, - { 0x0318, 0, "MDSC_DRQ" , "MDSC_DR\x16", "MDSC_DRQ" }, - { 0x031c, 0, "ACIA_DATA" , "ACIA_DA\x16", "ACIA_DATA" }, - { 0x031d, 0, "ACIA_STATUS" , "ACIA_ST\x16", "ACIA_STATUS" }, - { 0x031e, 0, "ACIA_COMMA\x16", "ACIA_CO\x16", "ACIA_COMMAND" }, - { 0x031f, 0, "ACIA_CONTR\x16", "ACIA_CO\x16", "ACIA_CONTROL" }, - { 0x0320, 0, "VIA2_IORB" , "VIA2_IORB" , "VIA2_IORB" }, - { 0x0321, 0, "VIA2_IORA" , "VIA2_IORA" , "VIA2_IORA" }, - { 0x0322, 0, "VIA2_DDRB" , "VIA2_DDRB" , "VIA2_DDRB" }, - { 0x0323, 0, "VIA2_DDRA" , "VIA2_DDRA" , "VIA2_DDRA" }, - { 0x0324, 0, "VIA2_T1C_L" , "VIA2_T1\x16", "VIA2_T1C_L" }, - { 0x0325, 0, "VIA2_T1C_H" , "VIA2_T1\x16", "VIA2_T1C_H" }, - { 0x0326, 0, "VIA2_T1L_L" , "VIA2_T1\x16", "VIA2_T1L_L" }, - { 0x0327, 0, "VIA2_T1L_H" , "VIA2_T1\x16", "VIA2_T1L_H" }, - { 0x0328, 0, "VIA2_T2C_L" , "VIA2_T2\x16", "VIA2_T2C_L" }, - { 0x0329, 0, "VIA2_T2C_H" , "VIA2_T2\x16", "VIA2_T2C_H" }, - { 0x032A, 0, "VIA2_SR" , "VIA2_SR" , "VIA2_SR" }, - { 0x032B, 0, "VIA2_ACR" , "VIA2_ACR" , "VIA2_ACR" }, - { 0x032C, 0, "VIA2_PCR" , "VIA2_PCR" , "VIA2_PCR" }, - { 0x032D, 0, "VIA2_IFR" , "VIA2_IFR" , "VIA2_IFR" }, - { 0x032E, 0, "VIA2_IER" , "VIA2_IER" , "VIA2_IER" }, - { 0x032F, 0, "VIA2_IORA2" , "VIA2_IO\x16", "VIA2_IORA2" }, - { 0xc000, 0, "BankedArea" , "BankedA\x16", "BankedArea" } }; +static struct msym defsym_tele[] = { { 0x0300, 0, "VIA_IORB", "VIA_IORB", "VIA_IORB" }, + { 0x0301, 0, "VIA_IORA", "VIA_IORA", "VIA_IORA" }, + { 0x0302, 0, "VIA_DDRB", "VIA_DDRB", "VIA_DDRB" }, + { 0x0303, 0, "VIA_DDRA", "VIA_DDRA", "VIA_DDRA" }, + { 0x0304, 0, "VIA_T1C_L", "VIA_T1C\x16", "VIA_T1C_L" }, + { 0x0305, 0, "VIA_T1C_H", "VIA_T1C\x16", "VIA_T1C_H" }, + { 0x0306, 0, "VIA_T1L_L", "VIA_T1L\x16", "VIA_T1L_L" }, + { 0x0307, 0, "VIA_T1L_H", "VIA_T1L\x16", "VIA_T1L_H" }, + { 0x0308, 0, "VIA_T2C_L", "VIA_T2C\x16", "VIA_T2C_L" }, + { 0x0309, 0, "VIA_T2C_H", "VIA_T2C\x16", "VIA_T2C_H" }, + { 0x030A, 0, "VIA_SR", "VIA_SR", "VIA_SR" }, + { 0x030B, 0, "VIA_ACR", "VIA_ACR", "VIA_ACR" }, + { 0x030C, 0, "VIA_PCR", "VIA_PCR", "VIA_PCR" }, + { 0x030D, 0, "VIA_IFR", "VIA_IFR", "VIA_IFR" }, + { 0x030E, 0, "VIA_IER", "VIA_IER", "VIA_IER" }, + { 0x030F, 0, "VIA_IORA2", "VIA_IORA2", "VIA_IORA2" }, + { 0x0310, 0, "WD17_COMMA\x16", "WD17_CO\x16", "WD17_COMMAND" }, + { 0x0311, 0, "WD17_TRACK\x16", "WD17_TR\x16", "WD17_TRACK" }, + { 0x0312, 0, "WD17_SECTO\x16", "WD17_SE\x16", "WD17_SECTOR" }, + { 0x0313, 0, "WD17_DATA", "WD17_DA\x16", "WD17_DATA" }, + { 0x0314, 0, "MDSC_STATUS", "MDSC_ST\x16", "MDSC_STATUS" }, + { 0x0318, 0, "MDSC_DRQ", "MDSC_DR\x16", "MDSC_DRQ" }, + { 0x031c, 0, "ACIA_DATA", "ACIA_DA\x16", "ACIA_DATA" }, + { 0x031d, 0, "ACIA_STATUS", "ACIA_ST\x16", "ACIA_STATUS" }, + { 0x031e, 0, "ACIA_COMMA\x16", "ACIA_CO\x16", "ACIA_COMMAND" }, + { 0x031f, 0, "ACIA_CONTR\x16", "ACIA_CO\x16", "ACIA_CONTROL" }, + { 0x0320, 0, "VIA2_IORB", "VIA2_IORB", "VIA2_IORB" }, + { 0x0321, 0, "VIA2_IORA", "VIA2_IORA", "VIA2_IORA" }, + { 0x0322, 0, "VIA2_DDRB", "VIA2_DDRB", "VIA2_DDRB" }, + { 0x0323, 0, "VIA2_DDRA", "VIA2_DDRA", "VIA2_DDRA" }, + { 0x0324, 0, "VIA2_T1C_L", "VIA2_T1\x16", "VIA2_T1C_L" }, + { 0x0325, 0, "VIA2_T1C_H", "VIA2_T1\x16", "VIA2_T1C_H" }, + { 0x0326, 0, "VIA2_T1L_L", "VIA2_T1\x16", "VIA2_T1L_L" }, + { 0x0327, 0, "VIA2_T1L_H", "VIA2_T1\x16", "VIA2_T1L_H" }, + { 0x0328, 0, "VIA2_T2C_L", "VIA2_T2\x16", "VIA2_T2C_L" }, + { 0x0329, 0, "VIA2_T2C_H", "VIA2_T2\x16", "VIA2_T2C_H" }, + { 0x032A, 0, "VIA2_SR", "VIA2_SR", "VIA2_SR" }, + { 0x032B, 0, "VIA2_ACR", "VIA2_ACR", "VIA2_ACR" }, + { 0x032C, 0, "VIA2_PCR", "VIA2_PCR", "VIA2_PCR" }, + { 0x032D, 0, "VIA2_IFR", "VIA2_IFR", "VIA2_IFR" }, + { 0x032E, 0, "VIA2_IER", "VIA2_IER", "VIA2_IER" }, + { 0x032F, 0, "VIA2_IORA2", "VIA2_IO\x16", "VIA2_IORA2" }, + { 0xc000, 0, "BankedArea", "BankedA\x16", "BankedArea" } +}; // 12345678901 12345678 -static struct msym defsym_atmos[] = { { 0x0300, 0, "VIA_IORB" , "VIA_IORB" , "VIA_IORB" }, - { 0x0301, 0, "VIA_IORA" , "VIA_IORA" , "VIA_IORA" }, - { 0x0302, 0, "VIA_DDRB" , "VIA_DDRB" , "VIA_DDRB" }, - { 0x0303, 0, "VIA_DDRA" , "VIA_DDRA" , "VIA_DDRA" }, - { 0x0304, 0, "VIA_T1C_L" , "VIA_T1C\x16", "VIA_T1C_L" }, - { 0x0305, 0, "VIA_T1C_H" , "VIA_T1C\x16", "VIA_T1C_H" }, - { 0x0306, 0, "VIA_T1L_L" , "VIA_T1L\x16", "VIA_T1L_L" }, - { 0x0307, 0, "VIA_T1L_H" , "VIA_T1L\x16", "VIA_T1L_H" }, - { 0x0308, 0, "VIA_T2C_L" , "VIA_T2C\x16", "VIA_T2C_L" }, - { 0x0309, 0, "VIA_T2C_H" , "VIA_T2C\x16", "VIA_T2C_H" }, - { 0x030A, 0, "VIA_SR" , "VIA_SR" , "VIA_SR" }, - { 0x030B, 0, "VIA_ACR" , "VIA_ACR" , "VIA_ACR" }, - { 0x030C, 0, "VIA_PCR" , "VIA_PCR" , "VIA_PCR" }, - { 0x030D, 0, "VIA_IFR" , "VIA_IFR" , "VIA_IFR" }, - { 0x030E, 0, "VIA_IER" , "VIA_IER" , "VIA_IER" }, - { 0x030F, 0, "VIA_IORA2" , "VIA_IORA2" , "VIA_IORA2" }, - { 0xc000, SYMF_ROMDIS0, "ROMStart" , "ROMStart" , "ROMStart" }, - { 0xc000, SYMF_ROMDIS1, "Overlay" , "Overlay" , "Overlay" } }; +static struct msym defsym_atmos[] = { { 0x0300, 0, "VIA_IORB", "VIA_IORB", "VIA_IORB" }, + { 0x0301, 0, "VIA_IORA", "VIA_IORA", "VIA_IORA" }, + { 0x0302, 0, "VIA_DDRB", "VIA_DDRB", "VIA_DDRB" }, + { 0x0303, 0, "VIA_DDRA", "VIA_DDRA", "VIA_DDRA" }, + { 0x0304, 0, "VIA_T1C_L", "VIA_T1C\x16", "VIA_T1C_L" }, + { 0x0305, 0, "VIA_T1C_H", "VIA_T1C\x16", "VIA_T1C_H" }, + { 0x0306, 0, "VIA_T1L_L", "VIA_T1L\x16", "VIA_T1L_L" }, + { 0x0307, 0, "VIA_T1L_H", "VIA_T1L\x16", "VIA_T1L_H" }, + { 0x0308, 0, "VIA_T2C_L", "VIA_T2C\x16", "VIA_T2C_L" }, + { 0x0309, 0, "VIA_T2C_H", "VIA_T2C\x16", "VIA_T2C_H" }, + { 0x030A, 0, "VIA_SR", "VIA_SR", "VIA_SR" }, + { 0x030B, 0, "VIA_ACR", "VIA_ACR", "VIA_ACR" }, + { 0x030C, 0, "VIA_PCR", "VIA_PCR", "VIA_PCR" }, + { 0x030D, 0, "VIA_IFR", "VIA_IFR", "VIA_IFR" }, + { 0x030E, 0, "VIA_IER", "VIA_IER", "VIA_IER" }, + { 0x030F, 0, "VIA_IORA2", "VIA_IORA2", "VIA_IORA2" }, + { 0xc000, SYMF_ROMDIS0, "ROMStart", "ROMStart", "ROMStart" }, + { 0xc000, SYMF_ROMDIS1, "Overlay", "Overlay", "Overlay" } +}; enum { @@ -181,6 +211,7 @@ enum MSHOW_VIA2, MSHOW_AY, MSHOW_DISK, + MSHOW_TWIL, MSHOW_LAST }; @@ -252,433 +283,439 @@ enum #define AMF_IND (1<= '0' ) && ( c <= '1' ) ) return SDL_TRUE; + if((c >= '0') && (c <= '1')) return SDL_TRUE; return SDL_FALSE; } -SDL_bool isnum( char c ) +SDL_bool isnum(char c) { - if( ( c >= '0' ) && ( c <= '9' ) ) return SDL_TRUE; + if((c >= '0') && (c <= '9')) return SDL_TRUE; return SDL_FALSE; } -SDL_bool ishex( char c ) +SDL_bool ishex(char c) { - if( isnum( c ) ) return SDL_TRUE; - if( ( c >= 'a' ) && ( c <= 'f' ) ) return SDL_TRUE; - if( ( c >= 'A' ) && ( c <= 'F' ) ) return SDL_TRUE; + if(isnum(c)) return SDL_TRUE; + if((c >= 'a') && (c <= 'f')) return SDL_TRUE; + if((c >= 'A') && (c <= 'F')) return SDL_TRUE; return SDL_FALSE; } -SDL_bool isalph( char c ) +SDL_bool isalph(char c) { - if( ( c >= 'a' ) && ( c <= 'z' ) ) return SDL_TRUE; - if( ( c >= 'A' ) && ( c <= 'Z' ) ) return SDL_TRUE; + if((c >= 'a') && (c <= 'z')) return SDL_TRUE; + if((c >= 'A') && (c <= 'Z')) return SDL_TRUE; return SDL_FALSE; } -SDL_bool issymstart( char c ) +SDL_bool issymstart(char c) { - if( isalph( c ) ) return SDL_TRUE; - if( c == '_' ) return SDL_TRUE; + if(isalph(c)) return SDL_TRUE; + if(c == '_') return SDL_TRUE; return SDL_FALSE; } -SDL_bool issymchar( char c ) +SDL_bool issymchar(char c) { - if( issymstart( c ) ) return SDL_TRUE; - if( isnum( c ) ) return SDL_TRUE; + if(issymstart(c)) return SDL_TRUE; + if(isnum(c)) return SDL_TRUE; return SDL_FALSE; } -int hexit( char c ) +int hexit(char c) { - if( isnum( c ) ) return c-'0'; - if( ( c >= 'a' ) && ( c <= 'f' ) ) return c-('a'-10); - if( ( c >= 'A' ) && ( c <= 'F' ) ) return c-('A'-10); + if(isnum(c)) return c-'0'; + if((c >= 'a') && (c <= 'f')) return c-('a'-10); + if((c >= 'A') && (c <= 'F')) return c-('A'-10); return -1; } -static int bp_at( struct machine *oric, unsigned short addr, int *xbp, int *mbp ) +#ifndef WWW_NO_MONITOR + +static int bp_at(struct machine *oric, unsigned short addr, int* xbp, int* mbp) { int bpmask = 0, i; - if( xbp ) *xbp = -1; - if( mbp ) *mbp = -1; + if(xbp) *xbp = -1; + if(mbp) *mbp = -1; oric->cpu.anybp = SDL_FALSE; - for( i=0; i<16; i++ ) + for(i=0; i<16; i++) { - if( oric->cpu.breakpoints[i] != -1 ) + if(oric->cpu.breakpoints[i] != -1) { oric->cpu.anybp = SDL_TRUE; - if( addr == oric->cpu.breakpoints[i] ) + if(addr == oric->cpu.breakpoints[i]) { bpmask |= 8; - if( xbp ) *xbp = i; + if(xbp) *xbp = i; break; } } } oric->cpu.anymbp = SDL_FALSE; - for( i=0; i<16; i++ ) + for(i=0; i<16; i++) { - if( oric->cpu.membreakpoints[i].flags ) + if(oric->cpu.membreakpoints[i].flags) { oric->cpu.anymbp = SDL_TRUE; - if( oric->cpu.membreakpoints[i].addr == addr ) + if(oric->cpu.membreakpoints[i].addr == addr) { bpmask |= oric->cpu.membreakpoints[i].flags; - if( mbp ) *mbp = i; + if(mbp) *mbp = i; break; } } @@ -688,12 +725,12 @@ static int bp_at( struct machine *oric, unsigned short addr, int *xbp, int *mbp } // Don't mess with registers that change because you read them! -unsigned char mon_read( struct machine *oric, unsigned short addr ) +unsigned char mon_read(struct machine *oric, unsigned short addr) { // microdisc registers could screw things up - if( oric->drivetype == DRV_MICRODISC ) + if(oric->drivetype == DRV_MICRODISC) { - switch( addr ) + switch(addr) { case 0x310: return oric->wddisk.r_status; @@ -715,38 +752,38 @@ unsigned char mon_read( struct machine *oric, unsigned short addr ) } } - if( oric->drivetype == DRV_PRAVETZ ) + if(oric->drivetype == DRV_PRAVETZ) { - if ( ( 0x300 <= addr ) && ( addr <= 0x30f ) ) + if((0x300 <= addr) && (addr <= 0x30f)) { - return via_mon_read( &oric->via, addr ); + return via_mon_read(&oric->via, addr); } - if ( ( 0x310 <= addr ) && ( addr <= 0x31f ) ) + if((0x310 <= addr) && (addr <= 0x31f)) { return 0xFF; } - return oric->cpu.read( &oric->cpu, addr ); + return oric->cpu.read(&oric->cpu, addr); } - if( ( addr & 0xff00 ) == 0x0300 ) + if((addr & 0xff00) == 0x0300) { - if ( ( !oric->lightpen ) || ( addr < 0x3e0 ) || ( addr > 0x3e1 ) ) + if((!oric->lightpen) || (addr < 0x3e0) || (addr > 0x3e1)) { - return via_mon_read( &oric->via, addr ); + return via_mon_read(&oric->via, addr); } } - return oric->cpu.read( &oric->cpu, addr ); + return oric->cpu.read(&oric->cpu, addr); } -void mon_store_state( struct machine *oric ) +void mon_store_state(struct machine *oric) { int k; - for( k=0; k<65536; k++ ) + for(k=0; k<65536; k++) { - if( isram( oric, k ) ) - mwatch_old[k] = mon_read( oric, k ); + if(isram(oric, k)) + mwatch_old[k] = mon_read(oric, k); } mwatch_oldvalid = SDL_TRUE; @@ -765,24 +802,24 @@ void mon_store_state( struct machine *oric ) via2_oldvalid = SDL_TRUE; } -void mon_set_modified( struct machine *oric ) +void mon_set_modified(struct machine *oric) { - if( modified ) return; + if(modified) return; modified = SDL_TRUE; - mon_store_state( oric ); + mon_store_state(oric); } -void dbg_scroll( void ) +void dbg_scroll(void) { int x, y, s, d; struct textzone *ptz = tz[TZ_DEBUG]; s = ptz->w*2+1; d = ptz->w+1; - for( y=0; y<18; y++ ) + for(y=0; y<18; y++) { - for( x=0; x<48; x++ ) + for(x=0; x<48; x++) { ptz->tx[d] = ptz->tx[s]; ptz->fc[d] = ptz->fc[s]; @@ -792,7 +829,7 @@ void dbg_scroll( void ) s += 2; } - for( x=0; x<48; x++ ) + for(x=0; x<48; x++) { ptz->tx[d] = ' '; ptz->fc[d] = 2; @@ -800,248 +837,262 @@ void dbg_scroll( void ) } } -void dbg_printf( char *fmt, ... ) +void dbg_printf(char* fmt, ...) { va_list ap; dbg_scroll(); - va_start( ap, fmt ); - if( vsnprintf( vsptmp, VSPTMPSIZE, fmt, ap ) != -1 ) + va_start(ap, fmt); + if(vsnprintf(vsptmp, VSPTMPSIZE, fmt, ap) != -1) { vsptmp[VSPTMPSIZE-1] = 0; #if LOG_DEBUG - if( debug_logfile ) + if(debug_logfile) { - fprintf( debug_logfile, "%s\n", vsptmp ); - fflush( debug_logfile ); + fprintf(debug_logfile, "%s\n", vsptmp); + fflush(debug_logfile); } #endif vsptmp[48] = 0; - tzstrpos( tz[TZ_DEBUG], 1, 19, vsptmp ); + tzstrpos(tz[TZ_DEBUG], 1, 19, vsptmp); } - va_end( ap ); + va_end(ap); } -struct msym *mon_tab_find_sym_by_addr( struct symboltable *stab, struct machine *oric, unsigned short addr, SDL_bool *override_romdis ) +struct msym *mon_tab_find_sym_by_addr(struct symboltable *stab, struct machine *oric, unsigned short addr, SDL_bool *override_romdis) { int i, j, k; SDL_bool romdis; romdis = oric->romdis; - if( ( oric->drivetype == DRV_JASMIN ) && ( oric->jasmin.olay ) ) + if((oric->drivetype == DRV_JASMIN) && (oric->jasmin.olay)) romdis = SDL_FALSE; - if (override_romdis) + if(override_romdis) romdis = *override_romdis; - for( i=0; inumsyms; i++ ) + for(i=0; inumsyms; i++) { - if( oric->type == MACH_TELESTRAT ) + if(oric->type == MACH_TELESTRAT) { - if( stab->syms[i].addr >= 0xc000 ) + if(stab->syms[i].addr >= 0xc000) { - for( j=0, k=SYMF_TELEBANK0; j<8; j++, k<<=1 ) + for(j=0, k=SYMF_TELEBANK0; j<8; j++, k<<=1) { - if( ((stab->syms[i].flags&k)==0) && ( oric->tele_currbank == j ) ) + if(((stab->syms[i].flags&k)==0) && (oric->tele_currbank == j)) break; } - if( j != 8 ) continue; + if(j != 8) continue; } - } else { - if( stab->syms[i].flags&SYMF_MICRODISC ) + } + else + { + if(stab->syms[i].flags&SYMF_MICRODISC) { - if( ( oric->drivetype != DRV_MICRODISC ) || ( !oric->md.diskrom ) ) + if((oric->drivetype != DRV_MICRODISC) || (!oric->md.diskrom)) continue; } - if( (stab->syms[i].flags&SYMF_JASMIN) && ( oric->drivetype != DRV_JASMIN ) ) + if((stab->syms[i].flags&SYMF_JASMIN) && (oric->drivetype != DRV_JASMIN)) continue; - if( romdis ) + if(romdis) { - if( (stab->syms[i].flags&SYMF_ROMDIS0) != 0 ) + if((stab->syms[i].flags&SYMF_ROMDIS0) != 0) continue; - } else { - if( (stab->syms[i].flags&SYMF_ROMDIS1) != 0 ) + } + else + { + if((stab->syms[i].flags&SYMF_ROMDIS1) != 0) continue; } } - if( addr == stab->syms[i].addr ) + if(addr == stab->syms[i].addr) return &stab->syms[i]; } return NULL; } -struct msym *mon_tab_find_sym_by_name( struct symboltable *stab, struct machine *oric, char *name, int *symnum ) +struct msym *mon_tab_find_sym_by_name(struct symboltable *stab, struct machine *oric, char* name, int* symnum) { int i, j, k, romdis; romdis = oric->romdis; - if( ( oric->drivetype == DRV_JASMIN ) && ( oric->jasmin.olay ) ) + if((oric->drivetype == DRV_JASMIN) && (oric->jasmin.olay)) romdis = 1; - for( i=0; inumsyms; i++ ) + for(i=0; inumsyms; i++) { - if( oric->type == MACH_TELESTRAT ) + if(oric->type == MACH_TELESTRAT) { - if( stab->syms[i].addr >= 0xc000 ) + if(stab->syms[i].addr >= 0xc000) { - for( j=0, k=SYMF_TELEBANK0; j<8; j++, k<<=1 ) + for(j=0, k=SYMF_TELEBANK0; j<8; j++, k<<=1) { - if( ((stab->syms[i].flags&k)==0) && ( oric->tele_currbank == j ) ) + if(((stab->syms[i].flags&k)==0) && (oric->tele_currbank == j)) break; } - if( j != 8 ) continue; + if(j != 8) continue; } - } else { - if( stab->syms[i].flags&SYMF_MICRODISC ) + } + else + { + if(stab->syms[i].flags&SYMF_MICRODISC) { - if( ( oric->drivetype != DRV_MICRODISC ) || ( !oric->md.diskrom ) ) + if((oric->drivetype != DRV_MICRODISC) || (!oric->md.diskrom)) continue; } - if( (stab->syms[i].flags&SYMF_JASMIN) && ( oric->drivetype != DRV_JASMIN ) ) + if((stab->syms[i].flags&SYMF_JASMIN) && (oric->drivetype != DRV_JASMIN)) continue; - if( romdis ) + if(romdis) { - if( (stab->syms[i].flags&SYMF_ROMDIS0) != 0 ) + if((stab->syms[i].flags&SYMF_ROMDIS0) != 0) continue; - } else { - if( (stab->syms[i].flags&SYMF_ROMDIS1) != 0 ) + } + else + { + if((stab->syms[i].flags&SYMF_ROMDIS1) != 0) continue; } } - if( !oric->symbolscase ) + if(!oric->symbolscase) { - if( strcasecmp( name, stab->syms[i].name ) == 0 ) + if(strcasecmp(name, stab->syms[i].name) == 0) { - if( symnum ) (*symnum) = i; + if(symnum)(*symnum) = i; return &stab->syms[i]; } - } else { - if( strcmp( name, stab->syms[i].name ) == 0 ) + } + else + { + if(strcmp(name, stab->syms[i].name) == 0) { - if( symnum ) (*symnum) = i; + if(symnum)(*symnum) = i; return &stab->syms[i]; } } } - if( symnum ) (*symnum) = -1; + if(symnum)(*symnum) = -1; return NULL; } -struct msym *mon_find_sym_by_addr( struct machine *oric, unsigned short addr, SDL_bool *override_romdis ) +struct msym *mon_find_sym_by_addr(struct machine *oric, unsigned short addr, SDL_bool *override_romdis) { struct msym *ret; - ret = mon_tab_find_sym_by_addr( &oric->usersyms, oric, addr, override_romdis ); - if( !ret ) ret = mon_tab_find_sym_by_addr( &oric->romsyms, oric, addr, override_romdis ); - if( ( !ret ) && ( oric->type == MACH_TELESTRAT ) ) ret = mon_tab_find_sym_by_addr( &oric->tele_banksyms[oric->tele_currbank], oric, addr, override_romdis ); - if( ( !ret ) && ( oric->disksyms ) ) ret = mon_tab_find_sym_by_addr( oric->disksyms, oric, addr, override_romdis ); - if( ret ) return ret; + ret = mon_tab_find_sym_by_addr(&oric->usersyms, oric, addr, override_romdis); + if(!ret) ret = mon_tab_find_sym_by_addr(&oric->romsyms, oric, addr, override_romdis); + if((!ret) && (oric->type == MACH_TELESTRAT)) ret = mon_tab_find_sym_by_addr(&oric->tele_banksyms[oric->tele_currbank], oric, addr, override_romdis); + if((!ret) && (oric->disksyms)) ret = mon_tab_find_sym_by_addr(oric->disksyms, oric, addr, override_romdis); + if(ret) return ret; - return mon_tab_find_sym_by_addr( &defaultsyms, oric, addr, override_romdis ); + return mon_tab_find_sym_by_addr(&defaultsyms, oric, addr, override_romdis); } -struct msym *mon_find_sym_by_name( struct machine *oric, char *name ) +struct msym *mon_find_sym_by_name(struct machine *oric, char* name) { struct msym *ret; - ret = mon_tab_find_sym_by_name( &oric->usersyms, oric, name, NULL ); - if( !ret ) ret = mon_tab_find_sym_by_name( &oric->romsyms, oric, name, NULL ); - if( ( !ret ) && ( oric->type == MACH_TELESTRAT ) ) ret = mon_tab_find_sym_by_name( &oric->tele_banksyms[oric->tele_currbank], oric, name, NULL ); - if( ( !ret ) && ( oric->disksyms ) ) ret = mon_tab_find_sym_by_name( oric->disksyms, oric, name, NULL ); - if( ret ) return ret; + ret = mon_tab_find_sym_by_name(&oric->usersyms, oric, name, NULL); + if(!ret) ret = mon_tab_find_sym_by_name(&oric->romsyms, oric, name, NULL); + if((!ret) && (oric->type == MACH_TELESTRAT)) ret = mon_tab_find_sym_by_name(&oric->tele_banksyms[oric->tele_currbank], oric, name, NULL); + if((!ret) && (oric->disksyms)) ret = mon_tab_find_sym_by_name(oric->disksyms, oric, name, NULL); + if(ret) return ret; - return mon_tab_find_sym_by_name( &defaultsyms, oric, name, NULL ); + return mon_tab_find_sym_by_name(&defaultsyms, oric, name, NULL); } -SDL_bool mon_addsym( struct symboltable *stab, unsigned short addr, unsigned short flags, char *name, struct msym **symptr ) +SDL_bool mon_addsym(struct symboltable *stab, unsigned short addr, unsigned short flags, char* name, struct msym **symptr) { int i; - if( symptr ) (*symptr) = NULL; + if(symptr)(*symptr) = NULL; // Is it a dynamic symbol table? - if( stab->symspace == -1 ) return SDL_FALSE; + if(stab->symspace == -1) return SDL_FALSE; - if( ( !stab->syms ) || ( stab->symspace < (stab->numsyms+1) ) ) + if((!stab->syms) || (stab->symspace < (stab->numsyms+1))) { struct msym *newbuf; - newbuf = malloc( sizeof( struct msym ) * (stab->symspace+64) ); - if( !newbuf ) return SDL_FALSE; + newbuf = malloc(sizeof(struct msym) * (stab->symspace+64)); + if(!newbuf) return SDL_FALSE; - if( ( stab->syms ) && ( stab->numsyms > 0 ) ) - memcpy( newbuf, stab->syms, sizeof( struct msym ) * stab->numsyms ); + if((stab->syms) && (stab->numsyms > 0)) + memcpy(newbuf, stab->syms, sizeof(struct msym) * stab->numsyms); - free( stab->syms ); + free(stab->syms); stab->syms = newbuf; stab->symspace += 64; - for( i=stab->numsyms; isymspace; i++ ) + for(i=stab->numsyms; isymspace; i++) stab->syms[i].name = NULL; } - if( !stab->syms[stab->numsyms].name ) + if(!stab->syms[stab->numsyms].name) { - stab->syms[stab->numsyms].name = malloc( 128 ); - if( !stab->syms[stab->numsyms].name ) return SDL_FALSE; + stab->syms[stab->numsyms].name = malloc(128); + if(!stab->syms[stab->numsyms].name) return SDL_FALSE; } stab->syms[stab->numsyms].addr = addr; stab->syms[stab->numsyms].flags = flags; - strncpy( stab->syms[stab->numsyms].name, name, 128 ); + strncpy(stab->syms[stab->numsyms].name, name, 128); stab->syms[stab->numsyms].name[127] = 0; - if( strlen( name ) > SNAME_LEN ) + if(strlen(name) > SNAME_LEN) { - strncpy( stab->syms[stab->numsyms].sname, name, (SNAME_LEN-1) ); + strncpy(stab->syms[stab->numsyms].sname, name, (SNAME_LEN-1)); stab->syms[stab->numsyms].sname[SNAME_LEN-1] = 22; stab->syms[stab->numsyms].sname[SNAME_LEN] = 0; - } else { - strcpy( stab->syms[stab->numsyms].sname, name ); + } + else + { + strcpy(stab->syms[stab->numsyms].sname, name); } - if( strlen( name ) > SSNAME_LEN ) + if(strlen(name) > SSNAME_LEN) { - strncpy( stab->syms[stab->numsyms].ssname, name, (SSNAME_LEN-1) ); + strncpy(stab->syms[stab->numsyms].ssname, name, (SSNAME_LEN-1)); stab->syms[stab->numsyms].ssname[SSNAME_LEN-1] = 22; stab->syms[stab->numsyms].ssname[SSNAME_LEN] = 0; - } else { - strcpy( stab->syms[stab->numsyms].ssname, name ); + } + else + { + strcpy(stab->syms[stab->numsyms].ssname, name); } - if( symptr ) *(symptr) = &stab->syms[stab->numsyms]; + if(symptr) *(symptr) = &stab->syms[stab->numsyms]; stab->numsyms++; return SDL_TRUE; } -void mon_init_symtab( struct symboltable *stab ) +void mon_init_symtab(struct symboltable *stab) { stab->syms = NULL; stab->numsyms = 0; stab->symspace = 0; } -void mon_freesyms( struct symboltable *stab ) +void mon_freesyms(struct symboltable *stab) { // Is it a dynamic table? - if( stab->symspace == -1 ) return; - if (stab->syms) + if(stab->symspace == -1) return; + if(stab->syms) { int i; - for (i = 0; i < stab->numsyms; i++) + for(i = 0; i < stab->numsyms; i++) { free(stab->syms[i].name); } @@ -1054,172 +1105,208 @@ void mon_freesyms( struct symboltable *stab ) -char *mon_disassemble( struct machine *oric, unsigned short *paddr, SDL_bool *looped, SDL_bool filemode ) +char* mon_disassemble(struct machine *oric, unsigned short* paddr, SDL_bool *looped, SDL_bool filemode) { unsigned short iaddr, addr; unsigned char op, a1, a2; int i; - char *tmpsname, *disptr; + char* tmpsname, *disptr; char sname[SNAME_LEN+1]; struct msym *csym; disptr = distmp; iaddr = *paddr; - if( looped ) *looped = SDL_FALSE; + if(looped) *looped = SDL_FALSE; tmpsname = ""; - if( !filemode ) + if(!filemode) { - csym = mon_find_sym_by_addr( oric, iaddr, NULL ); - if( csym ) tmpsname = csym->sname; - } else { - csym = mon_find_sym_by_addr( oric, iaddr, NULL ); - if( csym ) + csym = mon_find_sym_by_addr(oric, iaddr, NULL); + if(csym) tmpsname = csym->sname; + } + else + { + csym = mon_find_sym_by_addr(oric, iaddr, NULL); + if(csym) { tmpsname = csym->name; - if( strlen( tmpsname ) > SNAME_LEN ) + if(strlen(tmpsname) > SNAME_LEN) { - sprintf( distmp, "%s\n", tmpsname ); + int ln = strlen(tmpsname); + ln = (ln<127)? ln : 126; + memcpy(distmp, tmpsname, ln); + distmp[ln] = '\n'; + distmp[ln+1] = 0; disptr = &distmp[strlen(distmp)]; tmpsname = ""; } } } - strcpy( sname, tmpsname ); - for( i=(int)strlen(sname); iname : csym->sname ); + a1 = mon_read(oric, (*paddr)++); + csym = mon_find_sym_by_addr(oric, a1, NULL); + if(csym) + sprintf(disptr, "%s %04X %02X %02X %s %s", sname, iaddr, op, a1, distab[op].name, filemode ? csym->name : csym->sname); else - sprintf( disptr, "%s %04X %02X %02X %s $%02X", sname, iaddr, op, a1, distab[op].name, a1 ); - if( distab[op].amode == AM_ZP ) break; - strcat( disptr, distab[op].amode == AM_ZPX ? ",X" : ",Y" ); + sprintf(disptr, "%s %04X %02X %02X %s $%02X", sname, iaddr, op, a1, distab[op].name, a1); + if(distab[op].amode == AM_ZP) break; + strcat(disptr, distab[op].amode == AM_ZPX ? ",X" : ",Y"); break; case AM_ABS: case AM_ABX: case AM_ABY: - a1 = mon_read( oric, (*paddr)++ ); - a2 = mon_read( oric, (*paddr)++ ); - csym = mon_find_sym_by_addr( oric, (a2<<8)|a1, NULL ); - if( csym ) - sprintf( disptr, "%s %04X %02X %02X %02X %s %s", sname, iaddr, op, a1, a2, distab[op].name, filemode ? csym->name : csym->sname ); + a1 = mon_read(oric, (*paddr)++); + a2 = mon_read(oric, (*paddr)++); + csym = mon_find_sym_by_addr(oric, (a2<<8)|a1, NULL); + if(csym) + sprintf(disptr, "%s %04X %02X %02X %02X %s %s", sname, iaddr, op, a1, a2, distab[op].name, filemode ? csym->name : csym->sname); else - sprintf( disptr, "%s %04X %02X %02X %02X %s $%02X%02X", sname, iaddr, op, a1, a2, distab[op].name, a2, a1 ); - if( distab[op].amode == AM_ABS ) break; - strcat( disptr, distab[op].amode == AM_ABX ? ",X" : ",Y" ); + sprintf(disptr, "%s %04X %02X %02X %02X %s $%02X%02X", sname, iaddr, op, a1, a2, distab[op].name, a2, a1); + if(distab[op].amode == AM_ABS) break; + strcat(disptr, distab[op].amode == AM_ABX ? ",X" : ",Y"); break; case AM_ZIX: - a1 = mon_read( oric, (*paddr)++ ); - csym = mon_find_sym_by_addr( oric, a1, NULL ); - if( csym ) - sprintf( disptr, "%s %04X %02X %02X %s (%s,X)", sname, iaddr, op, a1, distab[op].name, filemode ? csym->name : csym->ssname ); + a1 = mon_read(oric, (*paddr)++); + csym = mon_find_sym_by_addr(oric, a1, NULL); + if(csym) + sprintf(disptr, "%s %04X %02X %02X %s (%s,X)", sname, iaddr, op, a1, distab[op].name, filemode ? csym->name : csym->ssname); else - sprintf( disptr, "%s %04X %02X %02X %s ($%02X,X)", sname, iaddr, op, a1, distab[op].name, a1 ); + sprintf(disptr, "%s %04X %02X %02X %s ($%02X,X)", sname, iaddr, op, a1, distab[op].name, a1); break; case AM_ZIY: - a1 = mon_read( oric, (*paddr)++ ); - csym = mon_find_sym_by_addr( oric, a1, NULL ); - if( csym ) - sprintf( disptr, "%s %04X %02X %02X %s (%s),Y", sname, iaddr, op, a1, distab[op].name, filemode ? csym->name : csym->ssname ); + a1 = mon_read(oric, (*paddr)++); + csym = mon_find_sym_by_addr(oric, a1, NULL); + if(csym) + sprintf(disptr, "%s %04X %02X %02X %s (%s),Y", sname, iaddr, op, a1, distab[op].name, filemode ? csym->name : csym->ssname); else - sprintf( disptr, "%s %04X %02X %02X %s ($%02X),Y", sname, iaddr, op, a1, distab[op].name, a1 ); + sprintf(disptr, "%s %04X %02X %02X %s ($%02X),Y", sname, iaddr, op, a1, distab[op].name, a1); break; case AM_REL: - a1 = mon_read( oric, (*paddr)++ ); + a1 = mon_read(oric, (*paddr)++); addr = ((*paddr)+((signed char)a1))&0xffff; - csym = mon_find_sym_by_addr( oric, addr, NULL ); - if( csym ) - sprintf( disptr, "%s %04X %02X %02X %s %s", sname, iaddr, op, a1, distab[op].name, filemode ? csym->name : csym->sname ); + csym = mon_find_sym_by_addr(oric, addr, NULL); + if(csym) + sprintf(disptr, "%s %04X %02X %02X %s %s", sname, iaddr, op, a1, distab[op].name, filemode ? csym->name : csym->sname); else - sprintf( disptr, "%s %04X %02X %02X %s $%04X", sname, iaddr, op, a1, distab[op].name, addr ); + sprintf(disptr, "%s %04X %02X %02X %s $%04X", sname, iaddr, op, a1, distab[op].name, addr); break; case AM_IND: - a1 = mon_read( oric, (*paddr)++ ); - a2 = mon_read( oric, (*paddr)++ ); - csym = mon_find_sym_by_addr( oric, (a2<<8)|a1, NULL ); - if( csym ) - sprintf( disptr, "%s %04X %02X %02X %02X %s (%s)", sname, iaddr, op, a1, a2, distab[op].name, filemode ? csym->name : csym->sname ); + a1 = mon_read(oric, (*paddr)++); + a2 = mon_read(oric, (*paddr)++); + csym = mon_find_sym_by_addr(oric, (a2<<8)|a1, NULL); + if(csym) + sprintf(disptr, "%s %04X %02X %02X %02X %s (%s)", sname, iaddr, op, a1, a2, distab[op].name, filemode ? csym->name : csym->sname); else - sprintf( disptr, "%s %04X %02X %02X %02X %s ($%02X%02X)", sname, iaddr, op, a1, a2, distab[op].name, a2, a1 ); + sprintf(disptr, "%s %04X %02X %02X %02X %s ($%02X%02X)", sname, iaddr, op, a1, a2, distab[op].name, a2, a1); break; default: - strcpy( disptr, " WTF?" ); + strcpy(disptr, " WTF?"); break; } - for( i=(int)strlen(disptr); i<47; i++ ) + for(i=(int)strlen(disptr); i<47; i++) disptr[i] = 32; disptr[i] = 0; - switch( bp_at( oric, iaddr, NULL, NULL ) ) + switch(bp_at(oric, iaddr, NULL, NULL)) { - case ( MBPF_READ): disptr[SNAME_LEN+1] = 'r'; break; - case ( MBPF_WRITE ): disptr[SNAME_LEN+1] = 'w'; break; - case ( MBPF_WRITE|MBPF_READ): disptr[SNAME_LEN+1] = 'a'; break; - case ( MBPF_CHANGE ): disptr[SNAME_LEN+1] = 'c'; break; - case ( MBPF_CHANGE |MBPF_READ): disptr[SNAME_LEN+1] = 'g'; break; - case ( MBPF_CHANGE|MBPF_WRITE ): disptr[SNAME_LEN+1] = 'm'; break; - case ( MBPF_CHANGE|MBPF_WRITE|MBPF_READ): disptr[SNAME_LEN+1] = '+'; break; - case (8 ): disptr[SNAME_LEN+1] = 'X'; break; - case (8| MBPF_READ): disptr[SNAME_LEN+1] = 'R'; break; - case (8| MBPF_WRITE ): disptr[SNAME_LEN+1] = 'W'; break; - case (8| MBPF_WRITE|MBPF_READ): disptr[SNAME_LEN+1] = 'A'; break; - case (8|MBPF_CHANGE ): disptr[SNAME_LEN+1] = 'C'; break; - case (8|MBPF_CHANGE |MBPF_READ): disptr[SNAME_LEN+1] = 'G'; break; - case (8|MBPF_CHANGE|MBPF_WRITE ): disptr[SNAME_LEN+1] = 'M'; break; - case (8|MBPF_CHANGE|MBPF_WRITE|MBPF_READ): disptr[SNAME_LEN+1] = '*'; break; + case(MBPF_READ): + disptr[SNAME_LEN+1] = 'r'; + break; + case(MBPF_WRITE): + disptr[SNAME_LEN+1] = 'w'; + break; + case(MBPF_WRITE|MBPF_READ): + disptr[SNAME_LEN+1] = 'a'; + break; + case(MBPF_CHANGE): + disptr[SNAME_LEN+1] = 'c'; + break; + case(MBPF_CHANGE |MBPF_READ): + disptr[SNAME_LEN+1] = 'g'; + break; + case(MBPF_CHANGE|MBPF_WRITE): + disptr[SNAME_LEN+1] = 'm'; + break; + case(MBPF_CHANGE|MBPF_WRITE|MBPF_READ): + disptr[SNAME_LEN+1] = '+'; + break; + case(8): + disptr[SNAME_LEN+1] = 'X'; + break; + case(8| MBPF_READ): + disptr[SNAME_LEN+1] = 'R'; + break; + case(8| MBPF_WRITE): + disptr[SNAME_LEN+1] = 'W'; + break; + case(8| MBPF_WRITE|MBPF_READ): + disptr[SNAME_LEN+1] = 'A'; + break; + case(8|MBPF_CHANGE): + disptr[SNAME_LEN+1] = 'C'; + break; + case(8|MBPF_CHANGE |MBPF_READ): + disptr[SNAME_LEN+1] = 'G'; + break; + case(8|MBPF_CHANGE|MBPF_WRITE): + disptr[SNAME_LEN+1] = 'M'; + break; + case(8|MBPF_CHANGE|MBPF_WRITE|MBPF_READ): + disptr[SNAME_LEN+1] = '*'; + break; } - if( iaddr == oric->cpu.pc ) + if(iaddr == oric->cpu.pc) disptr[SNAME_LEN+2] = '>'; - if( ( looped ) && ( iaddr > *paddr ) ) + if((looped) && (iaddr > *paddr)) *looped = SDL_TRUE; return distmp; } -static void mon_regmod( int x, int y, int w ) +static void mon_regmod(int x, int y, int w) { int offs, i; offs = y*tz[TZ_REGS]->w+x; - for( i=0; ifc[offs] = 1; tz[TZ_REGS]->bc[offs] = 8; } } -void mon_update_regs( struct machine *oric ) +void mon_update_regs(struct machine *oric) { int i; unsigned short addr, pc; @@ -1228,117 +1315,151 @@ void mon_update_regs( struct machine *oric ) pc = oric->cpu.pc; - if( ( oric->cpu.irq ) && ( oric->cpu.f_i == 0 ) ) - pc = (mon_read( oric, 0xffff )<<8) | mon_read( oric, 0xfffe ); + if((oric->cpu.irq) && (oric->cpu.f_i == 0)) + pc = (mon_read(oric, 0xffff)<<8) | mon_read(oric, 0xfffe); - tzprintfpos( tz[TZ_REGS], 2, 2, "PC=%04X SP=01%02X A=%02X X=%02X Y=%02X LPC=%04X", - pc, - oric->cpu.sp, - oric->cpu.a, - oric->cpu.x, - oric->cpu.y, - oric->cpu.lastpc ); + tzprintfpos(tz[TZ_REGS], 2, 2, "PC=%04X SP=01%02X A=%02X X=%02X Y=%02X LPC=%04X", + pc, + oric->cpu.sp, + oric->cpu.a, + oric->cpu.x, + oric->cpu.y, + oric->cpu.lastpc); - csym = mon_find_sym_by_addr( oric, pc, NULL ); - if( csym ) + csym = mon_find_sym_by_addr(oric, pc, NULL); + if(csym) { - if( strlen( csym->name ) > 46 ) + if(strlen(csym->name) > 46) { - strncpy( stmp, csym->name, 46 ); + strncpy(stmp, csym->name, 46); stmp[46] = 0; - } else { - strcpy( stmp, csym->name ); } - tzstrpos( tz[TZ_REGS], 2, 3, stmp ); - } else { - tzprintfpos( tz[TZ_REGS], 2, 3, "%46s", " " ); + else + { + strcpy(stmp, csym->name); + } + tzstrpos(tz[TZ_REGS], 2, 3, stmp); + } + else + { + tzprintfpos(tz[TZ_REGS], 2, 3, "%46s", " "); } - tzprintfpos( tz[TZ_REGS], 2, 4, "CY=%09d", oric->cpu.cycles ); - tzprintfpos( tz[TZ_REGS], 2, 5, "FM=%06d RS=%03d", oric->frames, oric->vid_raster ); + tzprintfpos(tz[TZ_REGS], 2, 4, "CY=%09d", oric->cpu.cycles); + tzprintfpos(tz[TZ_REGS], 2, 5, "FM=%06d RS=%03d", oric->frames, oric->vid_raster); - tzstrpos( tz[TZ_REGS], 35, 4, (oric->cpu.irq&IRQF_VIA) ? "VIA" : " " ); - tzstrpos( tz[TZ_REGS], 35, 5, (oric->cpu.irq&IRQF_DISK) ? "DISK" : " " ); + tzstrpos(tz[TZ_REGS], 35, 4, (oric->cpu.irq&IRQF_VIA) ? "VIA" : " "); + tzstrpos(tz[TZ_REGS], 35, 5, (oric->cpu.irq&IRQF_DISK) ? "DISK" : " "); - tzstrpos( tz[TZ_REGS], 20, 4, "NV-BDIZC" ); - tzprintfpos( tz[TZ_REGS], 20, 5, "%01X%01X1%01X%01X%01X%01X%01X", - oric->cpu.f_n, - oric->cpu.f_v, - oric->cpu.f_b, - oric->cpu.f_d, - oric->cpu.f_i, - oric->cpu.f_z, - oric->cpu.f_c ); + tzstrpos(tz[TZ_REGS], 20, 4, "NV-BDIZC"); + tzprintfpos(tz[TZ_REGS], 20, 5, "%01X%01X1%01X%01X%01X%01X%01X", + oric->cpu.f_n, + oric->cpu.f_v, + oric->cpu.f_b, + oric->cpu.f_d, + oric->cpu.f_i, + oric->cpu.f_z, + oric->cpu.f_c); - tzprintfpos( tz[TZ_REGS], 30, 4, "NMI=%04X RST=%04X", - (oric->cpu.read( &oric->cpu, 0xfffb )<<8)|oric->cpu.read( &oric->cpu, 0xfffa ), - (oric->cpu.read( &oric->cpu, 0xfffd )<<8)|oric->cpu.read( &oric->cpu, 0xfffc ) ); - tzprintfpos( tz[TZ_REGS], 30, 5, "IRQ=%04X", (oric->cpu.read( &oric->cpu, 0xffff )<<8)|oric->cpu.read( &oric->cpu, 0xfffe ) ); + tzprintfpos(tz[TZ_REGS], 30, 4, "NMI=%04X RST=%04X", + (oric->cpu.read(&oric->cpu, 0xfffb)<<8)|oric->cpu.read(&oric->cpu, 0xfffa), + (oric->cpu.read(&oric->cpu, 0xfffd)<<8)|oric->cpu.read(&oric->cpu, 0xfffc)); + tzprintfpos(tz[TZ_REGS], 30, 5, "IRQ=%04X", (oric->cpu.read(&oric->cpu, 0xffff)<<8)|oric->cpu.read(&oric->cpu, 0xfffe)); addr = pc; - for( i=0; i<10; i++ ) + for(i=0; i<10; i++) { disaddrs[i] = addr; - tzsetcol( tz[TZ_REGS], (addr==pc) ? 1 : 2, 3 ); - tzstrpos( tz[TZ_REGS], 23, 7+i, " " ); - tzstrpos( tz[TZ_REGS], 2, 7+i, mon_disassemble( oric, &addr, NULL, SDL_FALSE ) ); + tzsetcol(tz[TZ_REGS], (addr==pc) ? 1 : 2, 3); + tzstrpos(tz[TZ_REGS], 23, 7+i, " "); + tzstrpos(tz[TZ_REGS], 2, 7+i, mon_disassemble(oric, &addr, NULL, SDL_FALSE)); } - if( cpu_oldvalid ) + if(cpu_oldvalid) { - if( cpu_old.pc != pc ) mon_regmod( 5, 2, 4 ); - if( cpu_old.sp != oric->cpu.sp ) mon_regmod( 14, 2, 4 ); - if( cpu_old.a != oric->cpu.a ) mon_regmod( 22, 2, 2 ); - if( cpu_old.x != oric->cpu.x ) mon_regmod( 28, 2, 2 ); - if( cpu_old.y != oric->cpu.y ) mon_regmod( 34, 2, 2 ); - if( cpu_old.cycles != oric->cpu.cycles ) mon_regmod( 5, 4, 9 ); - if( frames_old != oric->frames ) mon_regmod( 5, 5, 6 ); - if( vidraster_old != oric->vid_raster ) mon_regmod( 15, 5, 3 ); - if( cpu_old.f_n != oric->cpu.f_n ) mon_regmod( 20, 5, 1 ); - if( cpu_old.f_v != oric->cpu.f_v ) mon_regmod( 21, 5, 1 ); - if( cpu_old.f_b != oric->cpu.f_b ) mon_regmod( 23, 5, 1 ); - if( cpu_old.f_d != oric->cpu.f_d ) mon_regmod( 24, 5, 1 ); - if( cpu_old.f_i != oric->cpu.f_i ) mon_regmod( 25, 5, 1 ); - if( cpu_old.f_z != oric->cpu.f_z ) mon_regmod( 26, 5, 1 ); - if( cpu_old.f_c != oric->cpu.f_c ) mon_regmod( 27, 5, 1 ); - - if( (cpu_old.irq&IRQF_VIA) != (oric->cpu.irq&IRQF_VIA) ) mon_regmod( 35, 4, 3 ); - if( (cpu_old.irq&IRQF_DISK) != (oric->cpu.irq&IRQF_DISK) ) mon_regmod( 35, 5, 4 ); + if(cpu_old.pc != pc) mon_regmod(5, 2, 4); + if(cpu_old.sp != oric->cpu.sp) mon_regmod(14, 2, 4); + if(cpu_old.a != oric->cpu.a) mon_regmod(22, 2, 2); + if(cpu_old.x != oric->cpu.x) mon_regmod(28, 2, 2); + if(cpu_old.y != oric->cpu.y) mon_regmod(34, 2, 2); + if(cpu_old.cycles != oric->cpu.cycles) mon_regmod(5, 4, 9); + if(frames_old != oric->frames) mon_regmod(5, 5, 6); + if(vidraster_old != oric->vid_raster) mon_regmod(15, 5, 3); + if(cpu_old.f_n != oric->cpu.f_n) mon_regmod(20, 5, 1); + if(cpu_old.f_v != oric->cpu.f_v) mon_regmod(21, 5, 1); + if(cpu_old.f_b != oric->cpu.f_b) mon_regmod(23, 5, 1); + if(cpu_old.f_d != oric->cpu.f_d) mon_regmod(24, 5, 1); + if(cpu_old.f_i != oric->cpu.f_i) mon_regmod(25, 5, 1); + if(cpu_old.f_z != oric->cpu.f_z) mon_regmod(26, 5, 1); + if(cpu_old.f_c != oric->cpu.f_c) mon_regmod(27, 5, 1); + + if((cpu_old.irq&IRQF_VIA) != (oric->cpu.irq&IRQF_VIA)) mon_regmod(35, 4, 3); + if((cpu_old.irq&IRQF_DISK) != (oric->cpu.irq&IRQF_DISK)) mon_regmod(35, 5, 4); } } -static void mon_click_regs( struct machine *oric, SDL_bool *needrender, int x, int y, SDL_bool dblclk ) +static void mon_click_regs(struct machine *oric, SDL_bool *needrender, int x, int y, SDL_bool dblclk) { char cmdtmp[32]; - if( ( dblclk ) && ( y == 5 ) ) + if((dblclk) && (y == 5)) { - switch( x ) + switch(x) { - case 20: mon_set_modified( oric ); oric->cpu.f_n ^= 1; *needrender = SDL_TRUE; return; - case 21: mon_set_modified( oric ); oric->cpu.f_v ^= 1; *needrender = SDL_TRUE; return; - case 23: mon_set_modified( oric ); oric->cpu.f_b ^= 1; *needrender = SDL_TRUE; return; - case 24: mon_set_modified( oric ); oric->cpu.f_d ^= 1; *needrender = SDL_TRUE; return; - case 25: mon_set_modified( oric ); oric->cpu.f_i ^= 1; *needrender = SDL_TRUE; return; - case 26: mon_set_modified( oric ); oric->cpu.f_z ^= 1; *needrender = SDL_TRUE; return; - case 27: mon_set_modified( oric ); oric->cpu.f_c ^= 1; *needrender = SDL_TRUE; return; + case 20: + mon_set_modified(oric); + oric->cpu.f_n ^= 1; + *needrender = SDL_TRUE; + return; + case 21: + mon_set_modified(oric); + oric->cpu.f_v ^= 1; + *needrender = SDL_TRUE; + return; + case 23: + mon_set_modified(oric); + oric->cpu.f_b ^= 1; + *needrender = SDL_TRUE; + return; + case 24: + mon_set_modified(oric); + oric->cpu.f_d ^= 1; + *needrender = SDL_TRUE; + return; + case 25: + mon_set_modified(oric); + oric->cpu.f_i ^= 1; + *needrender = SDL_TRUE; + return; + case 26: + mon_set_modified(oric); + oric->cpu.f_z ^= 1; + *needrender = SDL_TRUE; + return; + case 27: + mon_set_modified(oric); + oric->cpu.f_c ^= 1; + *needrender = SDL_TRUE; + return; } } - if( ( dblclk ) && ( y >= 7 ) && ( y < 17 ) ) + if((dblclk) && (y >= 7) && (y < 17)) { int i; - if( bp_at( oric, disaddrs[y-7], &i, NULL ) & 8 ) + if(bp_at(oric, disaddrs[y-7], &i, NULL) & 8) { - sprintf( cmdtmp, "bc %d", i ); - mon_do_cmd( cmdtmp, oric, needrender ); + sprintf(cmdtmp, "bc %d", i); + mon_do_cmd(cmdtmp, oric, needrender); *needrender = SDL_TRUE; - } else { - sprintf( cmdtmp, "bs $%04x", disaddrs[y-7] ); - mon_do_cmd( cmdtmp, oric, needrender ); + } + else + { + sprintf(cmdtmp, "bs $%04x", disaddrs[y-7]); + mon_do_cmd(cmdtmp, oric, needrender); *needrender = SDL_TRUE; } @@ -1346,102 +1467,102 @@ static void mon_click_regs( struct machine *oric, SDL_bool *needrender, int x, i } } -static void mon_viamod( int x, int y, int w, struct textzone *vtz ) +static void mon_viamod(int x, int y, int w, struct textzone *vtz) { int offs, i; offs = y*vtz->w+x; - for( i=0; ifc[offs] = 1; vtz->bc[offs] = 8; } } -void mon_update_via( struct machine *oric, struct textzone *vtz, struct via *v, struct via *old, SDL_bool *oldvalid ) +void mon_update_via(struct machine *oric, struct textzone *vtz, struct via *v, struct via *old, SDL_bool *oldvalid) { int i, j, o; unsigned char val; - char *names[] = { "IORB ", "IORAh", "DDRB ", "DDRA ", "T1CL ", "T1CH ", "T1LL ", "T1LH ", "T2CL ", "T2CH ", "SR ", "ACR ", "PCR ", "IFR ", "IER ", "IORA " }; + char* names[] = { "IORB ", "IORAh", "DDRB ", "DDRA ", "T1CL ", "T1CH ", "T1LL ", "T1LH ", "T2CL ", "T2CH ", "SR ", "ACR ", "PCR ", "IFR ", "IER ", "IORA " }; - for( i=0; i<16; i++ ) + for(i=0; i<16; i++) { - val = via_mon_read( v, v == &oric->via ? 0x300+i : 0x320+i ); - tzprintfpos( vtz, 2, i+1, "%04X: %s $%02X %%", (v == &oric->via) ? 0x300+i : 0x320+i, names[i], val ); - for( j=128; j; j>>=1 ) + val = via_mon_read(v, v == &oric->via ? 0x300+i : 0x320+i); + tzprintfpos(vtz, 2, i+1, "%04X: %s $%02X %%", (v == &oric->via) ? 0x300+i : 0x320+i, names[i], val); + for(j=128; j; j>>=1) tzputc(vtz, (val&j)?'1':'0'); - if( *oldvalid ) + if(*oldvalid) { - unsigned char oval = via_mon_read(old, (v == &oric->via) ? 0x300+i : 0x320+i ); - if( val != oval ) mon_viamod( 16, i+1, 2, vtz ); - for( j=128, o=19; j; j>>=1, o++ ) + unsigned char oval = via_mon_read(old, (v == &oric->via) ? 0x300+i : 0x320+i); + if(val != oval) mon_viamod(16, i+1, 2, vtz); + for(j=128, o=19; j; j>>=1, o++) { - if ((val&j) != (oval&j)) - mon_viamod( o, i+1, 1, vtz ); + if((val&j) != (oval&j)) + mon_viamod(o, i+1, 1, vtz); } } } - tzprintfpos( vtz, 2, 18, "---------- TAPE ----------"); - tzprintfpos( vtz, 2, 19, "OFS %08u LEN %08u", oric->tapeoffs, oric->tapelen ); + tzprintfpos(vtz, 2, 18, "---------- TAPE ----------"); + tzprintfpos(vtz, 2, 19, "OFS %08u LEN %08u", oric->tapeoffs, oric->tapelen); -/* - if( v == &oric->via ) - { - tzprintfpos( vtz, 2, 11, "TAPE OFFS = %07d", oric->tapeoffs ); - tzprintfpos( vtz, 2, 12, "TAPE LEN = %07d", oric->tapelen ); - tzprintfpos( vtz, 2, 13, "COUNT = %07d", oric->tapecount ); - tzprintfpos( vtz, 2, 14, "BIT = %02X DATA = %1X", - oric->tapebit, - oric->tapetime == TAPE_1_PULSE ); - tzprintfpos( vtz, 2, 15, "MOTOR = %1X", oric->tapemotor ); - } + /* + if( v == &oric->via ) + { + tzprintfpos( vtz, 2, 11, "TAPE OFFS = %07d", oric->tapeoffs ); + tzprintfpos( vtz, 2, 12, "TAPE LEN = %07d", oric->tapelen ); + tzprintfpos( vtz, 2, 13, "COUNT = %07d", oric->tapecount ); + tzprintfpos( vtz, 2, 14, "BIT = %02X DATA = %1X", + oric->tapebit, + oric->tapetime == TAPE_1_PULSE ); + tzprintfpos( vtz, 2, 15, "MOTOR = %1X", oric->tapemotor ); + } - if( v == &oric->tele_via ) - { - tzprintfpos( vtz, 2, 11, "BANK = %02X", oric->tele_currbank ); - } + if( v == &oric->tele_via ) + { + tzprintfpos( vtz, 2, 11, "BANK = %02X", oric->tele_currbank ); + } - if( *oldvalid ) - { - if( old->pcr != v->pcr ) mon_viamod( 6, 2, 2, vtz ); - if( old->acr != v->acr ) mon_viamod( 13, 2, 2, vtz ); - if( old->sr != v->sr ) mon_viamod( 19, 2, 2, vtz ); - if( old->ifr != v->ifr ) mon_viamod( 6, 3, 2, vtz ); - if( old->ier != v->ier ) mon_viamod( 13, 3, 2, vtz ); - if( old->ddra != v->ddra ) mon_viamod( 12, 5, 2, vtz ); - if( old->ddrb != v->ddrb ) mon_viamod( 18, 5, 2, vtz ); - if( old->ca1 != v->ca1 ) mon_viamod( 6, 6, 1, vtz ); - if( old->ca2 != v->ca2 ) mon_viamod( 12, 6, 1, vtz ); - if( old->cb1 != v->cb1 ) mon_viamod( 20, 6, 1, vtz ); - if( old->cb2 != v->cb2 ) mon_viamod( 26, 6, 1, vtz ); - if( old->t1c != v->t1c ) mon_viamod( 15, 8, 4, vtz ); - if( old->t2c != v->t2c ) mon_viamod( 15, 9, 4, vtz ); - - if( ((old->t1l_h<<8)|(old->t1l_l)) != ((v->t1l_h<<8)|(v->t1l_l)) ) mon_viamod( 6, 8, 4, vtz ); - if( ((old->t2l_h<<8)|(old->t2l_l)) != ((v->t2l_h<<8)|(v->t2l_l)) ) mon_viamod( 6, 9, 4, vtz ); - - if( ((v->ora&v->ddra)|(v->ira&(~v->ddra))) != ((old->ora&old->ddra)|(old->ira&(~old->ddra))) ) mon_viamod( 4, 5, 2, vtz ); - if( ((v->orb&v->ddrb)|(v->irb&(~v->ddrb))) != ((old->orb&old->ddrb)|(old->irb&(~old->ddrb))) ) mon_viamod( 26, 5, 2, vtz ); - } -*/ + if( *oldvalid ) + { + if( old->pcr != v->pcr ) mon_viamod( 6, 2, 2, vtz ); + if( old->acr != v->acr ) mon_viamod( 13, 2, 2, vtz ); + if( old->sr != v->sr ) mon_viamod( 19, 2, 2, vtz ); + if( old->ifr != v->ifr ) mon_viamod( 6, 3, 2, vtz ); + if( old->ier != v->ier ) mon_viamod( 13, 3, 2, vtz ); + if( old->ddra != v->ddra ) mon_viamod( 12, 5, 2, vtz ); + if( old->ddrb != v->ddrb ) mon_viamod( 18, 5, 2, vtz ); + if( old->ca1 != v->ca1 ) mon_viamod( 6, 6, 1, vtz ); + if( old->ca2 != v->ca2 ) mon_viamod( 12, 6, 1, vtz ); + if( old->cb1 != v->cb1 ) mon_viamod( 20, 6, 1, vtz ); + if( old->cb2 != v->cb2 ) mon_viamod( 26, 6, 1, vtz ); + if( old->t1c != v->t1c ) mon_viamod( 15, 8, 4, vtz ); + if( old->t2c != v->t2c ) mon_viamod( 15, 9, 4, vtz ); + + if( ((old->t1l_h<<8)|(old->t1l_l)) != ((v->t1l_h<<8)|(v->t1l_l)) ) mon_viamod( 6, 8, 4, vtz ); + if( ((old->t2l_h<<8)|(old->t2l_l)) != ((v->t2l_h<<8)|(v->t2l_l)) ) mon_viamod( 6, 9, 4, vtz ); + + if( ((v->ora&v->ddra)|(v->ira&(~v->ddra))) != ((old->ora&old->ddra)|(old->ira&(~old->ddra))) ) mon_viamod( 4, 5, 2, vtz ); + if( ((v->orb&v->ddrb)|(v->irb&(~v->ddrb))) != ((old->orb&old->ddrb)|(old->irb&(~old->ddrb))) ) mon_viamod( 26, 5, 2, vtz ); + } + */ } -static void mon_aymod( int x, int y, int w ) +static void mon_aymod(int x, int y, int w) { int offs, i; offs = y*tz[TZ_AY]->w+x; - for( i=0; ifc[offs] = 1; tz[TZ_AY]->bc[offs] = 8; } } -static void printayregbits( struct machine *oric, char *str, Sint16 x, Sint16 y, int reg, Uint8 bits ) +static void printayregbits(struct machine *oric, char* str, Sint16 x, Sint16 y, int reg, Uint8 bits) { int i, o, fc, bc; Uint8 vnew, vold; @@ -1450,32 +1571,34 @@ static void printayregbits( struct machine *oric, char *str, Sint16 x, Sint16 y, vnew = oric->ay.eregs[reg]; vold = ay_old.eregs[reg]; - tzprintfpos( ptz, x, y, str, vnew ); + tzprintfpos(ptz, x, y, str, vnew); fc = 2; bc = 3; - if( ( ay_oldvalid ) && ( ay_old.eregs[reg] != oric->ay.eregs[reg] ) ) + if((ay_oldvalid) && (ay_old.eregs[reg] != oric->ay.eregs[reg])) { fc = 1; bc = 8; - mon_aymod( x+14, y, 2 ); + mon_aymod(x+14, y, 2); } x+=18; o = (y*ptz->w)+x; bits = 8-bits; - for( i=0; i<8; i++ ) + for(i=0; i<8; i++) { - if( i >= bits ) + if(i >= bits) ptz->tx[o] = (vnew&(0x80>>i)) ? '1' : '0'; else ptz->tx[o] = ' '; - if( (vnew&(0x80)>>i) != (vold&(0x80)>>i) ) + if((vnew&(0x80)>>i) != (vold&(0x80)>>i)) { ptz->fc[o] = fc; ptz->bc[o] = bc; - } else { + } + else + { ptz->fc[o] = 2; ptz->bc[o] = 3; } @@ -1483,59 +1606,60 @@ static void printayregbits( struct machine *oric, char *str, Sint16 x, Sint16 y, } } -void mon_update_ay( struct machine *oric ) +void mon_update_ay(struct machine *oric) { - char *strs[] = { "INACTIVE", + char* strs[] = { "INACTIVE", "READ ", "WRITE ", - "LATCH " }; - tzprintfpos( tz[TZ_AY], 2, 1, "CTRL=%s REG=%02X", - strs[oric->ay.bmode&3], - oric->ay.creg ); + "LATCH " + }; + tzprintfpos(tz[TZ_AY], 2, 1, "CTRL=%s REG=%02X", + strs[oric->ay.bmode&3], + oric->ay.creg); - if( ay_oldvalid ) + if(ay_oldvalid) { - if( (ay_old.bmode&3) != (oric->ay.bmode&3) ) mon_aymod( 7, 1, 8 ); - if( ay_old.creg != oric->ay.creg ) mon_aymod( 21, 1, 2 ); + if((ay_old.bmode&3) != (oric->ay.bmode&3)) mon_aymod(7, 1, 8); + if(ay_old.creg != oric->ay.creg) mon_aymod(21, 1, 2); } - printayregbits( oric, "R0 Pitch A L $%02X %%", 2, 2, AY_CHA_PER_L, 8 ); - printayregbits( oric, "R1 Pitch A H $%02X %%", 2, 3, AY_CHA_PER_H, 4 ); - printayregbits( oric, "R2 Pitch B L $%02X %%", 2, 4, AY_CHB_PER_L, 8 ); - printayregbits( oric, "R3 Pitch B H $%02X %%", 2, 5, AY_CHB_PER_H, 4 ); - printayregbits( oric, "R4 Pitch C L $%02X %%", 2, 6, AY_CHC_PER_L, 8 ); - printayregbits( oric, "R5 Pitch C H $%02X %%", 2, 7, AY_CHC_PER_H, 4 ); - - printayregbits( oric, "R6 Noise $%02X %%", 2, 9, AY_NOISE_PER, 5 ); - printayregbits( oric, "R7 Status $%02X %%", 2,10, AY_STATUS, 7 ); - - printayregbits( oric, "R8 Volume A $%02X %%", 2,12, AY_CHA_AMP, 5 ); - printayregbits( oric, "R9 Volume B $%02X %%", 2,13, AY_CHB_AMP, 5 ); - printayregbits( oric, "RA Volume C $%02X %%", 2,14, AY_CHC_AMP, 5 ); - - printayregbits( oric, "RB Env Per L $%02X %%", 2,16, AY_ENV_PER_L, 8 ); - printayregbits( oric, "RC Env Per H $%02X %%", 2,17, AY_ENV_PER_H, 8 ); - printayregbits( oric, "RD Env Cycle $%02X %%", 2,18, AY_ENV_CYCLE, 4 ); - printayregbits( oric, "RE Key Col $%02X %%", 2,19, AY_PORT_A, 8 ); - -/* - tzprintfpos( tz[TZ_AY], 2, 4, "A:P=%04X A=%02X N:PER=%02X", - (oric->ay.regs[AY_CHA_PER_H]<<8)|(oric->ay.regs[AY_CHA_PER_L]), - oric->ay.regs[AY_CHA_AMP], - oric->ay.regs[AY_NOISE_PER] ); - tzprintfpos( tz[TZ_AY], 2, 5, "B:P=%04X A=%02X E:PER=%04X", - (oric->ay.regs[AY_CHB_PER_H]<<8)|(oric->ay.regs[AY_CHB_PER_L]), - oric->ay.regs[AY_CHB_AMP], - (oric->ay.regs[AY_ENV_PER_H]<<8)|(oric->ay.regs[AY_ENV_PER_L]) ); - tzprintfpos( tz[TZ_AY], 2, 6, "C:P=%04X A=%02X E:CYC=%02X", - (oric->ay.regs[AY_CHC_PER_H]<<8)|(oric->ay.regs[AY_CHC_PER_L]), - oric->ay.regs[AY_CHC_AMP], - oric->ay.regs[AY_ENV_CYCLE] ); - tzprintfpos( tz[TZ_AY], 2, 8, "STATUS=%02X", - oric->ay.regs[AY_STATUS] ); - tzprintfpos( tz[TZ_AY], 2, 9, "PORT=%02X", - oric->ay.regs[AY_PORT_A] ); -*/ + printayregbits(oric, "R0 Pitch A L $%02X %%", 2, 2, AY_CHA_PER_L, 8); + printayregbits(oric, "R1 Pitch A H $%02X %%", 2, 3, AY_CHA_PER_H, 4); + printayregbits(oric, "R2 Pitch B L $%02X %%", 2, 4, AY_CHB_PER_L, 8); + printayregbits(oric, "R3 Pitch B H $%02X %%", 2, 5, AY_CHB_PER_H, 4); + printayregbits(oric, "R4 Pitch C L $%02X %%", 2, 6, AY_CHC_PER_L, 8); + printayregbits(oric, "R5 Pitch C H $%02X %%", 2, 7, AY_CHC_PER_H, 4); + + printayregbits(oric, "R6 Noise $%02X %%", 2, 9, AY_NOISE_PER, 5); + printayregbits(oric, "R7 Status $%02X %%", 2,10, AY_STATUS, 7); + + printayregbits(oric, "R8 Volume A $%02X %%", 2,12, AY_CHA_AMP, 5); + printayregbits(oric, "R9 Volume B $%02X %%", 2,13, AY_CHB_AMP, 5); + printayregbits(oric, "RA Volume C $%02X %%", 2,14, AY_CHC_AMP, 5); + + printayregbits(oric, "RB Env Per L $%02X %%", 2,16, AY_ENV_PER_L, 8); + printayregbits(oric, "RC Env Per H $%02X %%", 2,17, AY_ENV_PER_H, 8); + printayregbits(oric, "RD Env Cycle $%02X %%", 2,18, AY_ENV_CYCLE, 4); + printayregbits(oric, "RE Key Col $%02X %%", 2,19, AY_PORT_A, 8); + + /* + tzprintfpos( tz[TZ_AY], 2, 4, "A:P=%04X A=%02X N:PER=%02X", + (oric->ay.regs[AY_CHA_PER_H]<<8)|(oric->ay.regs[AY_CHA_PER_L]), + oric->ay.regs[AY_CHA_AMP], + oric->ay.regs[AY_NOISE_PER] ); + tzprintfpos( tz[TZ_AY], 2, 5, "B:P=%04X A=%02X E:PER=%04X", + (oric->ay.regs[AY_CHB_PER_H]<<8)|(oric->ay.regs[AY_CHB_PER_L]), + oric->ay.regs[AY_CHB_AMP], + (oric->ay.regs[AY_ENV_PER_H]<<8)|(oric->ay.regs[AY_ENV_PER_L]) ); + tzprintfpos( tz[TZ_AY], 2, 6, "C:P=%04X A=%02X E:CYC=%02X", + (oric->ay.regs[AY_CHC_PER_H]<<8)|(oric->ay.regs[AY_CHC_PER_L]), + oric->ay.regs[AY_CHC_AMP], + oric->ay.regs[AY_ENV_CYCLE] ); + tzprintfpos( tz[TZ_AY], 2, 8, "STATUS=%02X", + oric->ay.regs[AY_STATUS] ); + tzprintfpos( tz[TZ_AY], 2, 9, "PORT=%02X", + oric->ay.regs[AY_PORT_A] ); + */ } /* @@ -1558,72 +1682,124 @@ void mon_update_ay( struct machine *oric ) int currentop; int delayedint; */ -void mon_update_disk( struct machine *oric ) +void mon_update_disk(struct machine *oric) { - char *opname; + char* opname; - if( oric->drivetype == DRV_NONE ) + if(oric->drivetype == DRV_NONE) return; - if( oric->drivetype == DRV_PRAVETZ ) + if(oric->drivetype == DRV_PRAVETZ) { int i = oric->wddisk.c_drive; - tzprintfpos( tz[TZ_DISK], 2, 2, "DRIVE=%02X EXT=%04X", - oric->wddisk.c_drive, - oric->pravetz.extension ); - tzprintfpos( tz[TZ_DISK], 2, 3, "VOL=%02X SEL=%02X", - oric->pravetz.drv[i].volume, - oric->pravetz.drv[i].select ); - tzprintfpos( tz[TZ_DISK], 2, 4, "MOTOR=%01X WRRDY=%01X", - oric->pravetz.drv[i].motor_on, - oric->pravetz.drv[i].write_ready ); - tzprintfpos( tz[TZ_DISK], 2, 5, "OVRAM=%s", oric->pravetz.olay ? "ON " : "OFF" ); + tzprintfpos(tz[TZ_DISK], 2, 2, "DRIVE=%02X EXT=%04X", + oric->wddisk.c_drive, + oric->pravetz.extension); + tzprintfpos(tz[TZ_DISK], 2, 3, "VOL=%02X SEL=%02X", + oric->pravetz.drv[i].volume, + oric->pravetz.drv[i].select); + tzprintfpos(tz[TZ_DISK], 2, 4, "MOTOR=%01X WRRDY=%01X", + oric->pravetz.drv[i].motor_on, + oric->pravetz.drv[i].write_ready); + tzprintfpos(tz[TZ_DISK], 2, 5, "OVRAM=%s", oric->pravetz.olay ? "ON " : "OFF"); return; } opname = "Unknown "; - switch( oric->wddisk.currentop ) + switch(oric->wddisk.currentop) { - case COP_NUFFINK: opname = "Idle "; break; - case COP_READ_TRACK: opname = "Read track "; break; - case COP_READ_SECTOR: opname = "Read sector "; break; - case COP_READ_SECTORS: opname = "Read sectors "; break; - case COP_WRITE_TRACK: opname = "Write track "; break; - case COP_WRITE_SECTOR: opname = "Write sector "; break; - case COP_WRITE_SECTORS: opname = "Write sectors"; break; - case COP_READ_ADDRESS: opname = "Read address "; break; + case COP_NUFFINK: + opname = "Idle "; + break; + case COP_READ_TRACK: + opname = "Read track "; + break; + case COP_READ_SECTOR: + opname = "Read sector "; + break; + case COP_READ_SECTORS: + opname = "Read sectors "; + break; + case COP_WRITE_TRACK: + opname = "Write track "; + break; + case COP_WRITE_SECTOR: + opname = "Write sector "; + break; + case COP_WRITE_SECTORS: + opname = "Write sectors"; + break; + case COP_READ_ADDRESS: + opname = "Read address "; + break; } - tzprintfpos( tz[TZ_DISK], 2, 2, "STATUS=%02X ROMDIS=%1X", oric->wddisk.r_status, oric->romdis ); - tzprintfpos( tz[TZ_DISK], 2, 3, "DRIVE=%02X SIDE=%02X TRACK=%02X", - oric->wddisk.c_drive, - oric->wddisk.c_side, - oric->wddisk.c_track ); - tzprintfpos( tz[TZ_DISK], 2, 4, "SECTR=%02X DATA=%02X", - oric->wddisk.r_sector, - oric->wddisk.r_data ); - tzprintfpos( tz[TZ_DISK], 2, 5, "OP=%s", opname ); - tzprintfpos( tz[TZ_DISK], 2, 6, "IRQC=%03d DRQC=%03d", - oric->wddisk.delayedint, - oric->wddisk.delayeddrq ); - - switch( oric->drivetype ) + tzprintfpos(tz[TZ_DISK], 2, 2, "STATUS=%02X ROMDIS=%1X", oric->wddisk.r_status, oric->romdis); + tzprintfpos(tz[TZ_DISK], 2, 3, "DRIVE=%02X SIDE=%02X TRACK=%02X", + oric->wddisk.c_drive, + oric->wddisk.c_side, + oric->wddisk.c_track); + tzprintfpos(tz[TZ_DISK], 2, 4, "SECTR=%02X DATA=%02X", + oric->wddisk.r_sector, + oric->wddisk.r_data); + tzprintfpos(tz[TZ_DISK], 2, 5, "OP=%s", opname); + tzprintfpos(tz[TZ_DISK], 2, 6, "IRQC=%03d DRQC=%03d", + oric->wddisk.delayedint, + oric->wddisk.delayeddrq); + + switch(oric->drivetype) { case DRV_MICRODISC: - tzprintfpos( tz[TZ_DISK], 2, 8, "MDSTAT=%02X INTRQ=%1X DRQ=%1X", - oric->md.status, - oric->md.intrq!=0, - oric->md.drq!=0 ); - tzprintfpos( tz[TZ_DISK], 2, 9, "EPROM=%1X", oric->md.diskrom ); + tzprintfpos(tz[TZ_DISK], 2, 8, "MDSTAT=%02X INTRQ=%1X DRQ=%1X", + oric->md.status, + oric->md.intrq!=0, + oric->md.drq!=0); + tzprintfpos(tz[TZ_DISK], 2, 9, "EPROM=%1X", oric->md.diskrom); break; case DRV_JASMIN: - tzprintfpos( tz[TZ_DISK], 2, 8, "OVRAM=%s", oric->jasmin.olay ? "ON " : "OFF" ); + tzprintfpos(tz[TZ_DISK], 2, 8, "OVRAM=%s", oric->jasmin.olay ? "ON " : "OFF"); break; } } -void mon_state_reset( struct machine *oric ) +void mon_update_twil(struct machine *oric) +{ + if((oric->twilighteboard_activated == SDL_FALSE) && (oric->ch376_activated == SDL_FALSE)) + return; + + + if(oric->twilighteboard_activated) + { + int current_bank = oric->twilighte->current_bank & 0x07; + int is_ram = (current_bank == 0) || ((twilighteboard_oric_read(oric->twilighte, 0x342) & 0x20) && (current_bank < 5)); + tzprintfpos(tz[TZ_TWIL], 2, 2, "Board version = %02X", (twilighteboard_oric_read(oric->twilighte, 0x342) & 0x07)); + tzprintfpos(tz[TZ_TWIL], 2, 4, "Bank set = %02X", twilighteboard_oric_read(oric->twilighte, 0x343)); + tzprintfpos(tz[TZ_TWIL], 2, 5, "Bank hardware number = %02X", twilighte_board_mapping_bank(oric->twilighte)); + tzprintfpos(tz[TZ_TWIL], 2, 6, "Bank software number = %02X", twilighte_board_mapping_software_bank(oric->twilighte)); + tzprintfpos(tz[TZ_TWIL], 2, 7, "Bank type = %s", is_ram ? "SRAM ": "EEPROM"); + tzprintfpos(tz[TZ_TWIL], 2, 9, "Twil register = %02X", twilighteboard_oric_read(oric->twilighte, 0x342)); + tzprintfpos(tz[TZ_TWIL], 2, 10, "Bank register = %02X", twilighteboard_oric_read(oric->twilighte, 0x343)); + tzprintfpos(tz[TZ_TWIL], 2, 12, "IORB = %02X", twilighteboard_oric_read(oric->twilighte, 0x320)); + tzprintfpos(tz[TZ_TWIL], 2, 13, "IORAh = %02X", twilighteboard_oric_read(oric->twilighte, 0x321)); + tzprintfpos(tz[TZ_TWIL], 2, 14, "DDRB = %02X", twilighteboard_oric_read(oric->twilighte, 0x322)); + tzprintfpos(tz[TZ_TWIL], 2, 15, "DDRA = %02X", twilighteboard_oric_read(oric->twilighte, 0x323)); + } + + int offs = 8*tz[TZ_TWIL]->w+1; + for(int k=0; k<28; k++) + { + tz[TZ_TWIL]->tx[offs+k] = 2; + tz[TZ_TWIL]->bc[offs+k] = 3; + tz[TZ_TWIL]->fc[offs+k] = 2; + } + + if(oric->ch376_activated) + { + } +} + +void mon_state_reset(struct machine *oric) { mwatch_oldvalid = SDL_FALSE; cpu_oldvalid = SDL_FALSE; @@ -1632,19 +1808,21 @@ void mon_state_reset( struct machine *oric ) via2_oldvalid = SDL_FALSE; } -void mon_update_mwatch( struct machine *oric ) +void mon_update_mwatch(struct machine *oric) { unsigned short addr; int j,k,l; unsigned int v; - if( mw_split ) + if(mw_split) { tz[TZ_MEMWATCH]->tx[ 50] = mw_which==0 ? 14 : 5; tz[TZ_MEMWATCH]->tx[550] = mw_which==1 ? 14 : 5; - } else { + } + else + { int offs = 10*tz[TZ_MEMWATCH]->w+1; - for( k=0; k<48; k++ ) + for(k=0; k<48; k++) tz[TZ_MEMWATCH]->tx[offs+k] = 32; tz[TZ_MEMWATCH]->tx[ 50] = 5; tz[TZ_MEMWATCH]->tx[550] = 5; @@ -1652,12 +1830,12 @@ void mon_update_mwatch( struct machine *oric ) } addr = mw_addr[0]; - for( j=0; j<19; j++, addr+=8 ) + for(j=0; j<19; j++, addr+=8) { - if( ( mw_split ) && ( j == 9 ) ) + if((mw_split) && (j == 9)) { int offs = 10*tz[TZ_MEMWATCH]->w+1; - for( k=0; k<48; k++ ) + for(k=0; k<48; k++) { tz[TZ_MEMWATCH]->tx[offs+k] = 2; tz[TZ_MEMWATCH]->bc[offs+k] = 3; @@ -1667,30 +1845,30 @@ void mon_update_mwatch( struct machine *oric ) addr = mw_addr[1]; } - sprintf( vsptmp, "%04X ", addr ); - for( k=0; k<8; k++ ) + sprintf(vsptmp, "%04X ", addr); + for(k=0; k<8; k++) { char tmp[8]; - snprintf( tmp, 7, "%02X ", mon_read( oric, addr+k ) ); - strcat( vsptmp, tmp ); + snprintf(tmp, 7, "%02X ", mon_read(oric, addr+k)); + strcat(vsptmp, tmp); } - l = (int)strlen( vsptmp ); + l = (int)strlen(vsptmp); vsptmp[l++] = 32; vsptmp[l++] = '\''; - for( k=0; k<8; k++ ) + for(k=0; k<8; k++) { - v = mon_read( oric, addr+k ); + v = mon_read(oric, addr+k); vsptmp[l++] = ((v>31)&&(v<128))?v:'.'; } vsptmp[l++] = '\''; vsptmp[l++] = 0; - tzstrpos( tz[TZ_MEMWATCH], 1, j+1, vsptmp ); + tzstrpos(tz[TZ_MEMWATCH], 1, j+1, vsptmp); - if( mwatch_oldvalid ) + if(mwatch_oldvalid) { - for( k=0; k<8; k++ ) + for(k=0; k<8; k++) { - if( isram( oric, addr+k ) && ( mwatch_old[addr+k] != mon_read( oric, addr+k ) ) ) + if(isram(oric, addr+k) && (mwatch_old[addr+k] != mon_read(oric, addr+k))) { int offs = (j+1)*tz[TZ_MEMWATCH]->w; tz[TZ_MEMWATCH]->fc[offs+(k*3+7)] = 1; @@ -1704,119 +1882,127 @@ void mon_update_mwatch( struct machine *oric ) } } - if( mw_mode == 0 ) return; + if(mw_mode == 0) return; - makebox( tz[TZ_MEMWATCH], 17, 8, 7, 3, 2, 3 ); - tzstrpos( tz[TZ_MEMWATCH], 18, 9, mw_ibuf ); + makebox(tz[TZ_MEMWATCH], 17, 8, 7, 3, 2, 3); + tzstrpos(tz[TZ_MEMWATCH], 18, 9, mw_ibuf); } -void mon_update( struct machine *oric ) +void mon_update(struct machine *oric) { - mon_update_regs( oric ); - switch( mshow ) + mon_update_regs(oric); + switch(mshow) { case MSHOW_VIA: - mon_update_via( oric, tz[TZ_VIA], &oric->via, &via_old, &via_oldvalid ); + mon_update_via(oric, tz[TZ_VIA], &oric->via, &via_old, &via_oldvalid); break; case MSHOW_VIA2: - mon_update_via( oric, tz[TZ_VIA2], &oric->tele_via, &via2_old, &via2_oldvalid ); + mon_update_via(oric, tz[TZ_VIA2], &oric->tele_via, &via2_old, &via2_oldvalid); break; case MSHOW_AY: - mon_update_ay( oric ); + mon_update_ay(oric); break; case MSHOW_DISK: - mon_update_disk( oric ); + mon_update_disk(oric); + break; + + case MSHOW_TWIL: + mon_update_twil(oric); break; } - switch( cshow ) + switch(cshow) { case CSHOW_MWATCH: - mon_update_mwatch( oric ); + mon_update_mwatch(oric); break; } } -void mon_render( struct machine *oric ) +void mon_render(struct machine *oric) { - if (updatepreview) - ula_renderscreen( oric ); - oric->render_video( oric, SDL_FALSE ); + if(updatepreview) + ula_renderscreen(oric); + oric->render_video(oric, SDL_FALSE); - switch( mshow ) + switch(mshow) { case MSHOW_VIA: - oric->render_textzone( oric, TZ_VIA ); + oric->render_textzone(oric, TZ_VIA); break; case MSHOW_VIA2: - oric->render_textzone( oric, TZ_VIA2 ); + oric->render_textzone(oric, TZ_VIA2); break; case MSHOW_AY: - oric->render_textzone( oric, TZ_AY ); + oric->render_textzone(oric, TZ_AY); break; case MSHOW_DISK: - oric->render_textzone( oric, TZ_DISK ); + oric->render_textzone(oric, TZ_DISK); + break; + + case MSHOW_TWIL: + oric->render_textzone(oric, TZ_TWIL); break; } - switch( cshow ) + switch(cshow) { case CSHOW_CONSOLE: - oric->render_textzone( oric, TZ_MONITOR ); + oric->render_textzone(oric, TZ_MONITOR); break; case CSHOW_DEBUG: - oric->render_textzone( oric, TZ_DEBUG ); + oric->render_textzone(oric, TZ_DEBUG); break; case CSHOW_MWATCH: - oric->render_textzone( oric, TZ_MEMWATCH ); + oric->render_textzone(oric, TZ_MEMWATCH); break; } - oric->render_textzone( oric, TZ_REGS ); + oric->render_textzone(oric, TZ_REGS); } -void mon_hide_curs( void ) +void mon_hide_curs(void) { struct textzone *ptz = tz[TZ_MONITOR]; int x = cursx-iloff; - if( mon_asmmode ) + if(mon_asmmode) { ptz->fc[ptz->w*19+8+x] = 2; ptz->bc[ptz->w*19+8+x] = 3; return; } - if( ( x < 0 ) || ( x > CONS_WIDTH ) ) return; + if((x < 0) || (x > CONS_WIDTH)) return; ptz->fc[ptz->w*19+2+x] = 2; ptz->bc[ptz->w*19+2+x] = 3; } -void mon_show_curs( void ) +void mon_show_curs(void) { struct textzone *ptz = tz[TZ_MONITOR]; int x = cursx-iloff; - if( mon_asmmode ) + if(mon_asmmode) { ptz->fc[ptz->w*19+8+x] = 3; ptz->bc[ptz->w*19+8+x] = 2; return; } - if( ( x < 0 ) || ( x > CONS_WIDTH ) ) return; + if((x < 0) || (x > CONS_WIDTH)) return; ptz->fc[ptz->w*19+2+x] = 3; ptz->bc[ptz->w*19+2+x] = 2; } -void mon_scroll( SDL_bool above ) +void mon_scroll(SDL_bool above) { int x, y, s, d, h; struct textzone *ptz = tz[TZ_MONITOR]; @@ -1825,9 +2011,9 @@ void mon_scroll( SDL_bool above ) s = ptz->w*2+1; d = ptz->w+1; - for( y=0; ytx[d] = ptz->tx[s]; ptz->fc[d] = ptz->fc[s]; @@ -1837,7 +2023,7 @@ void mon_scroll( SDL_bool above ) s += 2; } - for( x=0; x<48; x++ ) + for(x=0; x<48; x++) { ptz->tx[d] = ' '; ptz->fc[d] = 2; @@ -1845,136 +2031,136 @@ void mon_scroll( SDL_bool above ) } } -void mon_oprintf( char *fmt, ... ) +void mon_oprintf(char* fmt, ...) { va_list ap; int i; char stmp[48]; - va_start( ap, fmt ); - if( vsnprintf( vsptmp, VSPTMPSIZE, fmt, ap ) != -1 ) + va_start(ap, fmt); + if(vsnprintf(vsptmp, VSPTMPSIZE, fmt, ap) != -1) { vsptmp[VSPTMPSIZE-1] = 0; i = 0; - while( strlen( &vsptmp[i] ) > 47 ) + while(strlen(&vsptmp[i]) > 47) { - strncpy( stmp, &vsptmp[i], 47 ); + strncpy(stmp, &vsptmp[i], 47); stmp[47] = 0; - tzstrpos( tz[TZ_MONITOR], 1, 19, stmp ); - mon_scroll( SDL_FALSE ); + tzstrpos(tz[TZ_MONITOR], 1, 19, stmp); + mon_scroll(SDL_FALSE); i += 47; } - tzstrpos( tz[TZ_MONITOR], 1, 19, &vsptmp[i] ); + tzstrpos(tz[TZ_MONITOR], 1, 19, &vsptmp[i]); } - va_end( ap ); + va_end(ap); } -void mon_printf( char *fmt, ... ) +void mon_printf(char* fmt, ...) { va_list ap; int i; char stmp[48]; - mon_scroll( SDL_FALSE ); + mon_scroll(SDL_FALSE); - va_start( ap, fmt ); - if( vsnprintf( vsptmp, VSPTMPSIZE, fmt, ap ) != -1 ) + va_start(ap, fmt); + if(vsnprintf(vsptmp, VSPTMPSIZE, fmt, ap) != -1) { vsptmp[VSPTMPSIZE-1] = 0; i = 0; - while( strlen( &vsptmp[i] ) > 46 ) + while(strlen(&vsptmp[i]) > 46) { - strncpy( stmp, &vsptmp[i], 46 ); + strncpy(stmp, &vsptmp[i], 46); stmp[46] = 0; - tzstrpos( tz[TZ_MONITOR], 1, 19, stmp ); - mon_scroll( SDL_FALSE ); + tzstrpos(tz[TZ_MONITOR], 1, 19, stmp); + mon_scroll(SDL_FALSE); i += 46; } - tzstrpos( tz[TZ_MONITOR], 1, 19, &vsptmp[i] ); + tzstrpos(tz[TZ_MONITOR], 1, 19, &vsptmp[i]); } - va_end( ap ); + va_end(ap); } -void mon_printf_above( char *fmt, ... ) +void mon_printf_above(char* fmt, ...) { va_list ap; int i; char stmp[48]; - mon_scroll( SDL_TRUE ); + mon_scroll(SDL_TRUE); - va_start( ap, fmt ); - if( vsnprintf( vsptmp, VSPTMPSIZE, fmt, ap ) != -1 ) + va_start(ap, fmt); + if(vsnprintf(vsptmp, VSPTMPSIZE, fmt, ap) != -1) { vsptmp[VSPTMPSIZE-1] = 0; i = 0; - while( strlen( &vsptmp[i] ) > 46 ) + while(strlen(&vsptmp[i]) > 46) { - strncpy( stmp, &vsptmp[i], 46 ); + strncpy(stmp, &vsptmp[i], 46); stmp[46] = 0; - tzstrpos( tz[TZ_MONITOR], 1, 18, stmp ); - mon_scroll( SDL_TRUE ); + tzstrpos(tz[TZ_MONITOR], 1, 18, stmp); + mon_scroll(SDL_TRUE); i += 46; } - tzstrpos( tz[TZ_MONITOR], 1, 18, &vsptmp[i] ); + tzstrpos(tz[TZ_MONITOR], 1, 18, &vsptmp[i]); } - va_end( ap ); + va_end(ap); } -void mon_str( char *str ) +void mon_str(char* str) { - mon_scroll( SDL_FALSE ); - tzstrpos( tz[TZ_MONITOR], 1, 19, str ); + mon_scroll(SDL_FALSE); + tzstrpos(tz[TZ_MONITOR], 1, 19, str); } -void mon_str_above( char *str ) +void mon_str_above(char* str) { - mon_scroll( SDL_TRUE ); - tzstrpos( tz[TZ_MONITOR], 1, 18, str ); + mon_scroll(SDL_TRUE); + tzstrpos(tz[TZ_MONITOR], 1, 18, str); } -void mon_start_input( void ) +void mon_start_input(void) { - mon_scroll( SDL_FALSE ); + mon_scroll(SDL_FALSE); ibuf[0] = 0; ilen = 0; iloff = 0; cursx = 0; - if( mon_asmmode ) + if(mon_asmmode) { - tzsetcol( tz[TZ_MONITOR], 1, 3 ); - tzprintfpos( tz[TZ_MONITOR], 1, 19, " %04X:", mon_addr ); + tzsetcol(tz[TZ_MONITOR], 1, 3); + tzprintfpos(tz[TZ_MONITOR], 1, 19, " %04X:", mon_addr); return; } - tzsetcol( tz[TZ_MONITOR], 1, 3 ); - tzstrpos( tz[TZ_MONITOR], 1, 19, "]" ); + tzsetcol(tz[TZ_MONITOR], 1, 3); + tzstrpos(tz[TZ_MONITOR], 1, 19, "]"); } -void mon_enter( struct machine *oric ) +void mon_enter(struct machine *oric) { defaultsyms.syms = NULL; defaultsyms.numsyms = 0; defaultsyms.symspace = -1; // Not a dynamic symbol table - switch( oric->type ) + switch(oric->type) { case MACH_ORIC1: case MACH_ORIC1_16K: case MACH_ATMOS: case MACH_PRAVETZ: defaultsyms.syms = defsym_atmos; - defaultsyms.numsyms = sizeof( defsym_atmos ) / sizeof( struct msym ); + defaultsyms.numsyms = sizeof(defsym_atmos) / sizeof(struct msym); break; case MACH_TELESTRAT: defaultsyms.syms = defsym_tele; - defaultsyms.numsyms = sizeof( defsym_tele ) / sizeof( struct msym ); + defaultsyms.numsyms = sizeof(defsym_tele) / sizeof(struct msym); break; } - if( mon_bpmsg[0] ) + if(mon_bpmsg[0]) { - mon_printf_above( mon_bpmsg ); + mon_printf_above(mon_bpmsg); mon_bpmsg[0] = 0; } @@ -1982,13 +2168,13 @@ void mon_enter( struct machine *oric ) updatepreview = SDL_TRUE; } -void mon_warminit( struct machine *oric ) +void mon_warminit(struct machine *oric) { mon_start_input(); mon_show_curs(); } -void mon_init( struct machine *oric ) +void mon_init(struct machine *oric) { defaultsyms.numsyms = 0; defaultsyms.symspace = 0; @@ -2012,156 +2198,156 @@ void mon_init( struct machine *oric ) ay_oldvalid = SDL_FALSE; via_oldvalid = SDL_FALSE; #if LOG_DEBUG - debug_logfile = fopen( debug_logname, "w" ); + debug_logfile = fopen(debug_logname, "w"); #endif } -void mon_shut( struct machine *oric ) +void mon_shut(struct machine *oric) { - mon_freesyms( &oric->usersyms ); + mon_freesyms(&oric->usersyms); #if LOG_DEBUG - if( debug_logfile ) fclose( debug_logfile ); + if(debug_logfile) fclose(debug_logfile); debug_logfile = NULL; #endif } -int mon_getreg( char *buf, int *off, SDL_bool addrregs, SDL_bool nregs, SDL_bool viaregs ) +int mon_getreg(char* buf, int* off, SDL_bool addrregs, SDL_bool nregs, SDL_bool viaregs) { int i; i = *off; - while( isws( buf[i] ) ) i++; + while(isws(buf[i])) i++; - if( viaregs ) + if(viaregs) { - if( strncasecmp( &buf[i], "vpcr", 4 ) == 0 ) + if(strncasecmp(&buf[i], "vpcr", 4) == 0) { i+=4; *off = i; return REG_VIA_PCR; } - if( strncasecmp( &buf[i], "vacr", 4 ) == 0 ) + if(strncasecmp(&buf[i], "vacr", 4) == 0) { i+=4; *off = i; return REG_VIA_ACR; } - if( strncasecmp( &buf[i], "vsr", 3 ) == 0 ) + if(strncasecmp(&buf[i], "vsr", 3) == 0) { i+=3; *off = i; return REG_VIA_SR; } - if( strncasecmp( &buf[i], "vifr", 4 ) == 0 ) + if(strncasecmp(&buf[i], "vifr", 4) == 0) { i+=4; *off = i; return REG_VIA_IFR; } - if( strncasecmp( &buf[i], "vier", 4 ) == 0 ) + if(strncasecmp(&buf[i], "vier", 4) == 0) { i+=4; *off = i; return REG_VIA_IER; } - if( strncasecmp( &buf[i], "vira", 4 ) == 0 ) + if(strncasecmp(&buf[i], "vira", 4) == 0) { i+=4; *off = i; return REG_VIA_IRA; } - if( strncasecmp( &buf[i], "vora", 4 ) == 0 ) + if(strncasecmp(&buf[i], "vora", 4) == 0) { i+=4; *off = i; return REG_VIA_ORA; } - if( strncasecmp( &buf[i], "vddra", 5 ) == 0 ) + if(strncasecmp(&buf[i], "vddra", 5) == 0) { i+=5; *off = i; return REG_VIA_DDRA; } - if( strncasecmp( &buf[i], "virb", 4 ) == 0 ) + if(strncasecmp(&buf[i], "virb", 4) == 0) { i+=4; *off = i; return REG_VIA_IRB; } - if( strncasecmp( &buf[i], "vorb", 4 ) == 0 ) + if(strncasecmp(&buf[i], "vorb", 4) == 0) { i+=4; *off = i; return REG_VIA_ORB; } - if( strncasecmp( &buf[i], "vddrb", 5 ) == 0 ) + if(strncasecmp(&buf[i], "vddrb", 5) == 0) { i+=5; *off = i; return REG_VIA_DDRB; } - if( strncasecmp( &buf[i], "vt1l", 4 ) == 0 ) + if(strncasecmp(&buf[i], "vt1l", 4) == 0) { i+=4; *off = i; return REG_VIA_T1L; } - if( strncasecmp( &buf[i], "vt1c", 4 ) == 0 ) + if(strncasecmp(&buf[i], "vt1c", 4) == 0) { i+=4; *off = i; return REG_VIA_T1C; } - if( strncasecmp( &buf[i], "vt2l", 4 ) == 0 ) + if(strncasecmp(&buf[i], "vt2l", 4) == 0) { i+=4; *off = i; return REG_VIA_T2L; } - if( strncasecmp( &buf[i], "vt2c", 4 ) == 0 ) + if(strncasecmp(&buf[i], "vt2c", 4) == 0) { i+=4; *off = i; return REG_VIA_T2C; } - if( strncasecmp( &buf[i], "vca1", 4 ) == 0 ) + if(strncasecmp(&buf[i], "vca1", 4) == 0) { i+=4; *off = i; return REG_VIA_CA1; } - if( strncasecmp( &buf[i], "vca2", 4 ) == 0 ) + if(strncasecmp(&buf[i], "vca2", 4) == 0) { i+=4; *off = i; return REG_VIA_CA2; } - if( strncasecmp( &buf[i], "vcb1", 4 ) == 0 ) + if(strncasecmp(&buf[i], "vcb1", 4) == 0) { i+=4; *off = i; return REG_VIA_CB1; } - if( strncasecmp( &buf[i], "vcb2", 4 ) == 0 ) + if(strncasecmp(&buf[i], "vcb2", 4) == 0) { i+=4; *off = i; @@ -2169,16 +2355,16 @@ int mon_getreg( char *buf, int *off, SDL_bool addrregs, SDL_bool nregs, SDL_bool } } - if( addrregs ) + if(addrregs) { - if( strncasecmp( &buf[i], "pc", 2 ) == 0 ) + if(strncasecmp(&buf[i], "pc", 2) == 0) { i+=2; *off = i; return REG_PC; } - if( strncasecmp( &buf[i], "sp", 2 ) == 0 ) + if(strncasecmp(&buf[i], "sp", 2) == 0) { i+=2; *off = i; @@ -2186,9 +2372,9 @@ int mon_getreg( char *buf, int *off, SDL_bool addrregs, SDL_bool nregs, SDL_bool } } - if( nregs ) + if(nregs) { - switch( buf[i] ) + switch(buf[i]) { case 'a': case 'A': @@ -2213,27 +2399,27 @@ int mon_getreg( char *buf, int *off, SDL_bool addrregs, SDL_bool nregs, SDL_bool return -1; } -SDL_bool mon_getnum( struct machine *oric, unsigned int *num, char *buf, int *off, SDL_bool addrregs, SDL_bool nregs, SDL_bool viaregs, SDL_bool symbols ) +SDL_bool mon_getnum(struct machine *oric, unsigned int* num, char* buf, int* off, SDL_bool addrregs, SDL_bool nregs, SDL_bool viaregs, SDL_bool symbols) { int i, j; char c; unsigned int v; i = *off; - while( isws( buf[i] ) ) i++; + while(isws(buf[i])) i++; - if( ( symbols ) && ( issymstart( buf[i] ) ) ) + if((symbols) && (issymstart(buf[i]))) { struct msym *fsym; - for( j=0; issymchar( buf[i+j] ); j++ ) ; + for(j=0; issymchar(buf[i+j]); j++) ; c = buf[i+j]; - if( isws( c ) || ( c == 13 ) || ( c == 10 ) || ( c == 0 ) || ( c == ',' ) || ( c == ')' ) ) + if(isws(c) || (c == 13) || (c == 10) || (c == 0) || (c == ',') || (c == ')')) { buf[i+j] = 0; - fsym = mon_find_sym_by_name( oric, &buf[i] ); + fsym = mon_find_sym_by_name(oric, &buf[i]); buf[i+j] = c; - if( fsym ) + if(fsym) { (*num) = fsym->addr; (*off) = i+j; @@ -2242,10 +2428,10 @@ SDL_bool mon_getnum( struct machine *oric, unsigned int *num, char *buf, int *of } } - j = mon_getreg( buf, off, addrregs, nregs, viaregs ); - if( j != -1 ) + j = mon_getreg(buf, off, addrregs, nregs, viaregs); + if(j != -1) { - switch( j ) + switch(j) { case REG_A: *num = oric->cpu.a; @@ -2322,14 +2508,14 @@ SDL_bool mon_getnum( struct machine *oric, unsigned int *num, char *buf, int *of } } - if( buf[i] == '%' ) + if(buf[i] == '%') { // Binary i++; - if( !isbin( buf[i] ) ) return SDL_FALSE; + if(!isbin(buf[i])) return SDL_FALSE; v = 0; - while( isbin( buf[i] ) ) + while(isbin(buf[i])) { v = (v<<1) | (buf[i]-'0'); i++; @@ -2340,17 +2526,17 @@ SDL_bool mon_getnum( struct machine *oric, unsigned int *num, char *buf, int *of return SDL_TRUE; } - if( buf[i] == '$' ) + if(buf[i] == '$' || buf[i] == '#') { // Hex i++; - if( !ishex( buf[i] ) ) return SDL_FALSE; + if(!ishex(buf[i])) return SDL_FALSE; v = 0; - for( ;; ) + for(;;) { - j = hexit( buf[i] ); - if( j == -1 ) break; + j = hexit(buf[i]); + if(j == -1) break; v = (v<<4) | j; i++; } @@ -2360,10 +2546,10 @@ SDL_bool mon_getnum( struct machine *oric, unsigned int *num, char *buf, int *of return SDL_TRUE; } - if( !isnum( buf[i] ) ) return SDL_FALSE; + if(!isnum(buf[i])) return SDL_FALSE; v = 0; - while( isnum( buf[i] ) ) + while(isnum(buf[i])) { v = (v*10) + (buf[i]-'0'); i++; @@ -2374,22 +2560,22 @@ SDL_bool mon_getnum( struct machine *oric, unsigned int *num, char *buf, int *of return SDL_TRUE; } -Uint16 mon_sym_best_guess( struct machine *oric, Uint16 addr, char *symname, SDL_bool use_emu_state ) +Uint16 mon_sym_best_guess(struct machine *oric, Uint16 addr, char* symname, SDL_bool use_emu_state) { // In the ROM area? - if( addr >= 0xc000 ) + if(addr >= 0xc000) { // In a telestrat bank? - if( oric->type == MACH_TELESTRAT ) + if(oric->type == MACH_TELESTRAT) { // Labels starting t0_ are assumed to be telestrat bank 0 (etc.) - if( ( symname[0] == 't' ) && - ( ( symname[1] >= '0' ) && ( symname[1] <= '7' ) ) && - ( symname[2] == '_' ) ) + if((symname[0] == 't') && + ((symname[1] >= '0') && (symname[1] <= '7')) && + (symname[2] == '_')) return SYMF_TELEBANK0 << (symname[1]-'0'); // No hint from the label name. Can we attempt to use the current telestrat bank? - if( use_emu_state ) + if(use_emu_state) return SYMF_TELEBANK0 << oric->tele_currbank; // Just make it valid in any telestrat bank @@ -2397,10 +2583,10 @@ Uint16 mon_sym_best_guess( struct machine *oric, Uint16 addr, char *symname, SDL } // Its not a telestrat, so its ROM or overlay - if( use_emu_state ) + if(use_emu_state) { int romdis = oric->romdis; - if( ( oric->drivetype == DRV_JASMIN ) && ( oric->jasmin.olay ) ) + if((oric->drivetype == DRV_JASMIN) && (oric->jasmin.olay)) romdis = 1; return romdis ? SYMF_ROMDIS1 : SYMF_ROMDIS0; @@ -2413,61 +2599,63 @@ Uint16 mon_sym_best_guess( struct machine *oric, Uint16 addr, char *symname, SDL return 0; } -struct msym *mon_replace_or_add_symbol( struct symboltable *stab, struct machine *oric, char *symname, unsigned short flags, Uint16 addr ) +struct msym *mon_replace_or_add_symbol(struct symboltable *stab, struct machine *oric, char* symname, unsigned short flags, Uint16 addr) { int i; char symtmp[160]; struct msym *retval = NULL; - for( i=0; issymchar(symname[i]); i++ ) + for(i=0; issymchar(symname[i]); i++) symtmp[i] = symname[i]; symtmp[i] = 0; // Is it a dynamic symbol table? - if( stab->symspace == -1 ) return retval; + if(stab->symspace == -1) return retval; - if( flags == SYM_BESTGUESS ) - flags = mon_sym_best_guess( oric, addr, symtmp, SDL_TRUE ); + if(flags == SYM_BESTGUESS) + flags = mon_sym_best_guess(oric, addr, symtmp, SDL_TRUE); - for( i=0; inumsyms; i++ ) + for(i=0; inumsyms; i++) { - if( !oric->symbolscase ) + if(!oric->symbolscase) { - if( strcasecmp( symtmp, stab->syms[i].name ) == 0 ) + if(strcasecmp(symtmp, stab->syms[i].name) == 0) break; - } else { - if( strcmp( symtmp, stab->syms[i].name ) == 0 ) + } + else + { + if(strcmp(symtmp, stab->syms[i].name) == 0) break; } } // Replace existing symbol? - if( i < stab->numsyms ) + if(i < stab->numsyms) { stab->syms[i].addr = addr; stab->syms[i].flags = flags; return &stab->syms[i]; } - mon_addsym( stab, addr, flags, symtmp, &retval ); + mon_addsym(stab, addr, flags, symtmp, &retval); return retval; } -SDL_bool mon_symsfromsnapshot( struct symboltable *stab, unsigned char *buffer, unsigned int len) +SDL_bool mon_symsfromsnapshot(struct symboltable *stab, unsigned char* buffer, unsigned int len) { int offs, symlen, addr, flags; - char *symname; + char* symname; stab->numsyms = 0; offs = 0; - while (offs < len) + while(offs < len) { symlen = (buffer[offs]<<24)|(buffer[offs+1]<<16)|(buffer[offs+2]<<8)|buffer[offs+3]; offs+=4; - if (symlen+offs >= len) return SDL_FALSE; + if(symlen+offs >= len) return SDL_FALSE; - symname = (char *)(&buffer[offs]); + symname = (char*)(&buffer[offs]); offs += symlen; addr = (buffer[offs]<<8)|buffer[offs+1]; @@ -2476,7 +2664,7 @@ SDL_bool mon_symsfromsnapshot( struct symboltable *stab, unsigned char *buffer, flags = (buffer[offs]<<8)|buffer[offs+1]; offs += 2; - mon_addsym( stab, addr, flags, symname, NULL ); + mon_addsym(stab, addr, flags, symname, NULL); } return SDL_TRUE; @@ -2484,95 +2672,97 @@ SDL_bool mon_symsfromsnapshot( struct symboltable *stab, unsigned char *buffer, -SDL_bool mon_new_symbols( struct symboltable *stab, struct machine *oric, char *fname, unsigned short flags, SDL_bool above, SDL_bool verbose ) +SDL_bool mon_new_symbols(struct symboltable *stab, struct machine *oric, char* fname, unsigned short flags, SDL_bool above, SDL_bool verbose) { FILE *f; int i, j; unsigned int v; - f = fopen( fname, "r" ); - if( !f ) + f = fopen(fname, "r"); + if(!f) { - if( verbose ) + if(verbose) { - if( above ) - mon_printf_above( "Unable to open '%s'", fname ); + if(above) + mon_printf_above("Unable to open '%s'", fname); else - mon_printf( "Unable to open '%s'", fname ); + mon_printf("Unable to open '%s'", fname); } return SDL_FALSE; } stab->numsyms = 0; - while( !feof( f ) ) + while(!feof(f)) { char linetmp[256]; - if( !fgets( linetmp, 256, f ) ) break; + if(!fgets(linetmp, 256, f)) break; - if( sscanf( linetmp, "al %06X .%s", &v, linetmp ) != 2 ) + if(sscanf(linetmp, "al %06X .%s", &v, linetmp) != 2) { - for( i=0, v=0; i<4; i++ ) - { - j = hexit( linetmp[i] ); - if( j == -1 ) break; - v = (v<<4)|j; - } - if( i < 4 ) continue; - if( linetmp[4] != 32 ) continue; - if( !issymstart( linetmp[5] ) ) continue; + for(i=0, v=0; i<4; i++) + { + j = hexit(linetmp[i]); + if(j == -1) break; + v = (v<<4)|j; + } + if(i < 4) continue; + if(linetmp[4] != 32) continue; + if(!issymstart(linetmp[5])) continue; - for( i=5,j=0; issymchar(linetmp[i]); i++,j++ ) - linetmp[j] = linetmp[i]; - linetmp[j] = 0; + for(i=5,j=0; issymchar(linetmp[i]); i++,j++) + linetmp[j] = linetmp[i]; + linetmp[j] = 0; } -// printf( "'%s' = %04X\n", linetmp, v ); - fflush( stdout ); + // printf( "'%s' = %04X\n", linetmp, v ); + fflush(stdout); // Guess the flags! - if( flags == SYM_BESTGUESS ) + if(flags == SYM_BESTGUESS) { - mon_addsym( stab, v, mon_sym_best_guess( oric, v, linetmp, SDL_FALSE ), linetmp, NULL ); - } else { - mon_addsym( stab, v, flags, linetmp, NULL ); + mon_addsym(stab, v, mon_sym_best_guess(oric, v, linetmp, SDL_FALSE), linetmp, NULL); + } + else + { + mon_addsym(stab, v, flags, linetmp, NULL); } } - fclose( f ); + fclose(f); - if( verbose ) + if(verbose) { - if( above ) - mon_printf_above( "Symbols loaded from '%s'", fname ); + if(above) + mon_printf_above("Symbols loaded from '%s'", fname); else - mon_printf( "Symbols loaded from '%s'", fname ); + mon_printf("Symbols loaded from '%s'", fname); } return SDL_TRUE; } -SDL_bool mon_cmd( char *cmd, struct machine *oric, SDL_bool *needrender ) +SDL_bool mon_cmd(char* cmd, struct machine *oric, SDL_bool *needrender) { int i, j, k, l; unsigned int v, w; SDL_bool done = SDL_FALSE; - unsigned char *tmem; + unsigned char* tmem; struct msym *tmpsym; FILE *f; i=0; - while( isws( cmd[i] ) ) i++; + while(isws(cmd[i])) i++; - if( cmd[i] != '?' ) + if(cmd[i] != '?') helpcount = 0; - switch( cmd[i] ) + switch(cmd[i]) { case 'a': - lastcmd = cmd[i]; + lastcmd = ARPT_ASSEM; i++; - if( mon_getnum( oric, &v, cmd, &i, SDL_TRUE, SDL_FALSE, SDL_FALSE, SDL_TRUE ) ) + if(mon_getnum(oric, &v, cmd, &i, SDL_TRUE, SDL_FALSE, SDL_FALSE, SDL_TRUE)) mon_addr = v; mon_asmmode = SDL_TRUE; @@ -2581,138 +2771,138 @@ SDL_bool mon_cmd( char *cmd, struct machine *oric, SDL_bool *needrender ) case 's': // Symbols lastcmd = 0; i++; - switch( cmd[i] ) + switch(cmd[i]) { case 'c': // Case insensitive oric->symbolscase = SDL_FALSE; - mon_str( "Symbols are not case-sensitive" ); + mon_str("Symbols are not case-sensitive"); break; case 'C': // Case sensitive oric->symbolscase = SDL_TRUE; - mon_str( "Symbols are case-sensitive" ); + mon_str("Symbols are case-sensitive"); break; case 'a': // add - if( !isws( cmd[i+1] ) ) + if(!isws(cmd[i+1])) { - mon_str( "???" ); + mon_str("???"); break; } i+=2; - while( isws( cmd[i] ) ) i++; + while(isws(cmd[i])) i++; - if( !issymstart( cmd[i] ) ) + if(!issymstart(cmd[i])) { - mon_str( "Expected symbol name and address" ); + mon_str("Expected symbol name and address"); break; } j = i; - while( issymchar( cmd[i] ) ) i++; + while(issymchar(cmd[i])) i++; - if( !isws( cmd[i] ) ) + if(!isws(cmd[i])) { - mon_str( "Expected symbol name and address" ); + mon_str("Expected symbol name and address"); break; } - if( !mon_getnum( oric, &v, cmd, &i, SDL_TRUE, SDL_FALSE, SDL_FALSE, SDL_TRUE ) ) + if(!mon_getnum(oric, &v, cmd, &i, SDL_TRUE, SDL_FALSE, SDL_FALSE, SDL_TRUE)) { - mon_str( "Address expected" ); + mon_str("Address expected"); break; } - tmpsym = mon_replace_or_add_symbol( &oric->usersyms, oric, &cmd[j], SYM_BESTGUESS, v ); - if( !tmpsym ) + tmpsym = mon_replace_or_add_symbol(&oric->usersyms, oric, &cmd[j], SYM_BESTGUESS, v); + if(!tmpsym) { - mon_str( "Failed for some reason" ); + mon_str("Failed for some reason"); break; } - mon_printf( "%s = %04X", tmpsym->name, tmpsym->addr ); + mon_printf("%s = %04X", tmpsym->name, tmpsym->addr); break; case 'k': // kill - if( !isws( cmd[i+1] ) ) + if(!isws(cmd[i+1])) { - mon_str( "???" ); + mon_str("???"); break; } i+=2; - while( isws( cmd[i] ) ) i++; + while(isws(cmd[i])) i++; - if( !issymstart( cmd[i] ) ) + if(!issymstart(cmd[i])) { - mon_str( "Symbol expected" ); + mon_str("Symbol expected"); break; } j = i; - while( issymchar( cmd[i] ) ) i++; + while(issymchar(cmd[i])) i++; - if( cmd[i] != 0 ) + if(cmd[i] != 0) { - mon_printf( "Expected end of line at '%s'", &cmd[i] ); + mon_printf("Expected end of line at '%s'", &cmd[i]); break; } - if( !mon_tab_find_sym_by_name( &oric->usersyms, oric, &cmd[j], &k ) ) + if(!mon_tab_find_sym_by_name(&oric->usersyms, oric, &cmd[j], &k)) { - mon_printf( "Couldn't find '%s' in the user symbol table", &cmd[j] ); + mon_printf("Couldn't find '%s' in the user symbol table", &cmd[j]); break; } - for( ; k<(oric->usersyms.numsyms-1); k++ ) + for(; k<(oric->usersyms.numsyms-1); k++) oric->usersyms.syms[k] = oric->usersyms.syms[k+1]; oric->usersyms.numsyms--; - mon_printf( "Killed symbol '%s'", &cmd[j] ); + mon_printf("Killed symbol '%s'", &cmd[j]); break; case 'z': // Zap oric->usersyms.numsyms = 0; - mon_str( "Symbols zapped!" ); + mon_str("Symbols zapped!"); break; case 'l': // Load - if( !isws( cmd[i+1] ) ) + if(!isws(cmd[i+1])) { - mon_str( "???" ); + mon_str("???"); break; } i+=2; - mon_new_symbols( &oric->usersyms, oric, &cmd[i], SYM_BESTGUESS, SDL_FALSE, SDL_TRUE ); + mon_new_symbols(&oric->usersyms, oric, &cmd[i], SYM_BESTGUESS, SDL_FALSE, SDL_TRUE); break; case 'x': // Export - if( !isws( cmd[i+1] ) ) + if(!isws(cmd[i+1])) { - mon_str( "???" ); + mon_str("???"); break; } i+=2; - f = fopen( &cmd[i], "w" ); - if( !f ) + f = fopen(&cmd[i], "w"); + if(!f) { - mon_printf( "Unable to open '%s' for writing", &cmd[i] ); + mon_printf("Unable to open '%s' for writing", &cmd[i]); break; } - for( j=0; jusersyms.numsyms; j++ ) - fprintf( f, "%04X %s\n", oric->usersyms.syms[j].addr, oric->usersyms.syms[j].name ); - fclose( f ); + for(j=0; jusersyms.numsyms; j++) + fprintf(f, "%04X %s\n", oric->usersyms.syms[j].addr, oric->usersyms.syms[j].name); + fclose(f); - mon_printf( "User symbols exported to '%s'", &cmd[i] ); + mon_printf("User symbols exported to '%s'", &cmd[i]); break; default: - mon_str( "???" ); + mon_str("???"); break; } break; @@ -2720,22 +2910,22 @@ SDL_bool mon_cmd( char *cmd, struct machine *oric, SDL_bool *needrender ) case 'b': lastcmd = 0; i++; - switch( cmd[i] ) + switch(cmd[i]) { case 'l': - if( cmd[i+1] == 'm' ) + if(cmd[i+1] == 'm') { oric->cpu.anymbp = SDL_FALSE; - for( j=0; j<16; j++ ) + for(j=0; j<16; j++) { - if( oric->cpu.membreakpoints[j].flags ) + if(oric->cpu.membreakpoints[j].flags) { - mon_printf( "%02d: $%04X %c%c%c", - j, - oric->cpu.membreakpoints[j].addr, - (oric->cpu.membreakpoints[j].flags&MBPF_READ) ? 'r' : ' ', - (oric->cpu.membreakpoints[j].flags&MBPF_WRITE) ? 'w' : ' ', - (oric->cpu.membreakpoints[j].flags&MBPF_CHANGE) ? 'c' : ' ' ); + mon_printf("%02d: $%04X %c%c%c", + j, + oric->cpu.membreakpoints[j].addr, + (oric->cpu.membreakpoints[j].flags&MBPF_READ) ? 'r' : ' ', + (oric->cpu.membreakpoints[j].flags&MBPF_WRITE) ? 'w' : ' ', + (oric->cpu.membreakpoints[j].flags&MBPF_CHANGE) ? 'c' : ' '); oric->cpu.anymbp = SDL_TRUE; } } @@ -2743,51 +2933,52 @@ SDL_bool mon_cmd( char *cmd, struct machine *oric, SDL_bool *needrender ) } oric->cpu.anybp = SDL_FALSE; - for( j=0; j<16; j++ ) + for(j=0; j<16; j++) { - if( oric->cpu.breakpoints[j] != -1 ) + if(oric->cpu.breakpoints[j] != -1) { - mon_printf( "%02d: $%04X %s%s", - j, - oric->cpu.breakpoints[j], - (oric->cpu.breakpoint_flags[j]&MBPF_RESETCYCLES) ? "z" : "", - (oric->cpu.breakpoint_flags[j]&MBPF_RESETCYCLESCONTINUE) ? "c" : ""); + mon_printf("%02d: $%04X %s%s%s", + j, + oric->cpu.breakpoints[j], + (oric->cpu.breakpoint_flags[j]&MBPF_RESETCYCLES) ? "z" : "", + (oric->cpu.breakpoint_flags[j]&MBPF_RESETCYCLESCONTINUE) ? "c" : "", + (oric->cpu.breakpoint_flags[j]&MBPF_RESETCYCLESPRINT) ? "t" : ""); oric->cpu.anybp = SDL_TRUE; } } break; case 's': - if( cmd[i+1] == 'm' ) + if(cmd[i+1] == 'm') { - for( j=0; j<16; j++ ) + for(j=0; j<16; j++) { - if( oric->cpu.membreakpoints[j].flags == 0 ) + if(oric->cpu.membreakpoints[j].flags == 0) break; } - if( j == 16 ) + if(j == 16) { - mon_str( "Max 16 breakpoints" ); + mon_str("Max 16 breakpoints"); break; } i += 2; - if( !mon_getnum( oric, &v, cmd, &i, SDL_TRUE, SDL_TRUE, SDL_TRUE, SDL_TRUE ) ) + if(!mon_getnum(oric, &v, cmd, &i, SDL_TRUE, SDL_TRUE, SDL_TRUE, SDL_TRUE)) { - mon_str( "Address expected" ); + mon_str("Address expected"); break; } oric->cpu.membreakpoints[j].addr = v & 0xffff; - oric->cpu.membreakpoints[j].lastval = mon_read( oric, v&0xffff ); + oric->cpu.membreakpoints[j].lastval = mon_read(oric, v&0xffff); oric->cpu.membreakpoints[j].flags = 0; - while( isws( cmd[i] ) ) i++; + while(isws(cmd[i])) i++; - for( ;; ) + for(;;) { - switch( cmd[i] ) + switch(cmd[i]) { case 'r': oric->cpu.membreakpoints[j].flags |= MBPF_READ; @@ -2807,33 +2998,33 @@ SDL_bool mon_cmd( char *cmd, struct machine *oric, SDL_bool *needrender ) break; } - if( !oric->cpu.membreakpoints[j].flags ) + if(!oric->cpu.membreakpoints[j].flags) oric->cpu.membreakpoints[j].flags = MBPF_READ|MBPF_WRITE; oric->cpu.anymbp = SDL_TRUE; - mon_printf( "m%02d: $%04X %s%s%s", j, oric->cpu.membreakpoints[j].addr, - (oric->cpu.membreakpoints[j].flags&MBPF_READ) ? "r" : "", - (oric->cpu.membreakpoints[j].flags&MBPF_WRITE) ? "w" : "", - (oric->cpu.membreakpoints[j].flags&MBPF_CHANGE) ? "c" : "" ); + mon_printf("m%02d: $%04X %s%s%s", j, oric->cpu.membreakpoints[j].addr, + (oric->cpu.membreakpoints[j].flags&MBPF_READ) ? "r" : "", + (oric->cpu.membreakpoints[j].flags&MBPF_WRITE) ? "w" : "", + (oric->cpu.membreakpoints[j].flags&MBPF_CHANGE) ? "c" : ""); break; } - for( j=0; j<16; j++ ) + for(j=0; j<16; j++) { - if( oric->cpu.breakpoints[j] == -1 ) + if(oric->cpu.breakpoints[j] == -1) break; } - if( j == 16 ) + if(j == 16) { - mon_str( "Max 16 breakpoints" ); + mon_str("Max 16 breakpoints"); break; } i++; - if( !mon_getnum( oric, &v, cmd, &i, SDL_TRUE, SDL_TRUE, SDL_TRUE, SDL_TRUE ) ) + if(!mon_getnum(oric, &v, cmd, &i, SDL_TRUE, SDL_TRUE, SDL_TRUE, SDL_TRUE)) { - mon_str( "Address expected" ); + mon_str("Address expected"); break; } @@ -2841,11 +3032,11 @@ SDL_bool mon_cmd( char *cmd, struct machine *oric, SDL_bool *needrender ) oric->cpu.breakpoint_flags[j] = 0; oric->cpu.anybp = SDL_TRUE; - while( isws( cmd[i] ) ) i++; + while(isws(cmd[i])) i++; - for( ;; ) + for(;;) { - switch( cmd[i] ) + switch(cmd[i]) { case 'z': oric->cpu.breakpoint_flags[j] |= MBPF_RESETCYCLES; @@ -2855,45 +3046,50 @@ SDL_bool mon_cmd( char *cmd, struct machine *oric, SDL_bool *needrender ) oric->cpu.breakpoint_flags[j] |= MBPF_RESETCYCLESCONTINUE; i++; continue; + case 't': + oric->cpu.breakpoint_flags[j] |= MBPF_RESETCYCLESPRINT; + i++; + continue; } break; } - mon_printf( "%02d: $%04X %s%s", - j, - oric->cpu.breakpoints[j], - (oric->cpu.breakpoint_flags[j]&MBPF_RESETCYCLES) ? "z" : "", - (oric->cpu.breakpoint_flags[j]&MBPF_RESETCYCLESCONTINUE) ? "c" : "" ); + mon_printf("%02d: $%04X %s%s%s", + j, + oric->cpu.breakpoints[j], + (oric->cpu.breakpoint_flags[j]&MBPF_RESETCYCLES) ? "z" : "", + (oric->cpu.breakpoint_flags[j]&MBPF_RESETCYCLESCONTINUE) ? "c" : "", + (oric->cpu.breakpoint_flags[j]&MBPF_RESETCYCLESPRINT) ? "t" : ""); break; case 'c': j = 0; - if( cmd[i+1] == 'm' ) + if(cmd[i+1] == 'm') { j = 1; i++; } i++; - if( !mon_getnum( oric, &v, cmd, &i, SDL_FALSE, SDL_FALSE, SDL_FALSE, SDL_FALSE ) ) + if(!mon_getnum(oric, &v, cmd, &i, SDL_FALSE, SDL_FALSE, SDL_FALSE, SDL_FALSE)) { - mon_str( "Breakpoint ID expected" ); + mon_str("Breakpoint ID expected"); break; } - if( v > 15 ) + if(v > 15) { - mon_str( "Invalid breakpoint ID" ); + mon_str("Invalid breakpoint ID"); break; } - if( j ) + if(j) { oric->cpu.membreakpoints[v].flags = 0; oric->cpu.anymbp = SDL_FALSE; - for( j=0; j<16; j++ ) + for(j=0; j<16; j++) { - if( oric->cpu.membreakpoints[j].flags != 0 ) + if(oric->cpu.membreakpoints[j].flags != 0) { oric->cpu.anymbp = SDL_TRUE; break; @@ -2904,9 +3100,9 @@ SDL_bool mon_cmd( char *cmd, struct machine *oric, SDL_bool *needrender ) oric->cpu.breakpoints[v] = -1; oric->cpu.anybp = SDL_FALSE; - for( j=0; j<16; j++ ) + for(j=0; j<16; j++) { - if( oric->cpu.breakpoints[j] != -1 ) + if(oric->cpu.breakpoints[j] != -1) { oric->cpu.anybp = SDL_TRUE; break; @@ -2915,66 +3111,159 @@ SDL_bool mon_cmd( char *cmd, struct machine *oric, SDL_bool *needrender ) break; case 'z': - if( cmd[i+1] == 'm' ) + if(cmd[i+1] == 'm') { - for( i=0; i<16; i++ ) + for(i=0; i<16; i++) oric->cpu.membreakpoints[i].flags = 0; oric->cpu.anymbp = SDL_FALSE; break; } - for( i=0; i<16; i++ ) + for(i=0; i<16; i++) oric->cpu.breakpoints[i] = -1; oric->cpu.anybp = SDL_FALSE; break; default: - mon_str( "???" ); + mon_str("???"); break; } break; case 'm': - lastcmd = cmd[i]; + lastcmd = ARPT_MEMORY; i++; - switch( cmd[i] ) + switch(cmd[i]) { + case 's': + lastcmd = 0; + i++; + + if(!mon_getnum(oric, &w, cmd, &i, SDL_TRUE, SDL_FALSE, SDL_FALSE, SDL_TRUE)) + { + mon_str("Value expected"); + } + else + { + Uint16* collection = memory_search; + memory_search_pos = 0; + memory_hits = 0; + for(j=0x500; j < 0x9800; j++) + { + if((unsigned char)w == mon_read(oric, j)) + { + *collection++ = j; + memory_hits++; + } + } + sprintf(vsptmp, "Found %i match(es)", memory_hits); + mon_str(vsptmp); + } + break; + + case 'r': + lastcmd = 0; + i++; + + if(!mon_getnum(oric, &w, cmd, &i, SDL_TRUE, SDL_FALSE, SDL_FALSE, SDL_TRUE)) + { + mon_str("Value expected"); + } + else + { + int newhits = 0; + memory_search_pos = 0; + for(j = 0; j < memory_hits; j++) + { + Uint16 curr_mem_addr = memory_search[j]; + if((unsigned char)w == mon_read(oric, curr_mem_addr)) + { + memory_search[newhits++] = curr_mem_addr; + } + } + memory_hits = newhits; + + sprintf(vsptmp, "Refined match(es) : %i", memory_hits); + mon_str(vsptmp); + } + break; + + case 'p': + { + char tmp[16]; + int lines = 0; + int j, k = 0; + + lastcmd = ARPT_SEARCH; + vsptmp[0] = 0; + + for(j = memory_search_pos; j < memory_hits; j++, k++) + { + sprintf(tmp, "[%04X]:[%02X] ", memory_search[j], mon_read(oric, memory_search[j])); + strcat(vsptmp, tmp); + if(k == 4) + { + mon_str(vsptmp); + vsptmp[0] = 0; + lines++; + k = 0; + } + if(lines > 16) + { + memory_search_pos = j; + break; + } + } + if(strlen(vsptmp)) + { + mon_str(vsptmp); + } + if(j >= memory_hits) + { + memory_search_pos = 0; + lastcmd = 0; + } + break; + } + case 'm': lastcmd = 0; i++; - if( !mon_getnum( oric, &v, cmd, &i, SDL_TRUE, SDL_FALSE, SDL_FALSE, SDL_TRUE ) ) + if(!mon_getnum(oric, &v, cmd, &i, SDL_TRUE, SDL_FALSE, SDL_FALSE, SDL_TRUE)) { - mon_str( "Bad address" ); + mon_str("Bad address"); break; } - if( !mon_getnum( oric, &w, cmd, &i, SDL_TRUE, SDL_FALSE, SDL_FALSE, SDL_TRUE ) ) + if(!mon_getnum(oric, &w, cmd, &i, SDL_TRUE, SDL_FALSE, SDL_FALSE, SDL_TRUE)) { - mon_str( "Value expected" ); + mon_str("Value expected"); break; } - mon_set_modified( oric ); - oric->cpu.write( &oric->cpu, v, w ); - updatepreview = SDL_TRUE; + mon_set_modified(oric); + oric->cpu.write(&oric->cpu, v, w); + updatepreview = SDL_TRUE; break; case 'w': lastcmd = 0; i++; - if( !mon_getnum( oric, &v, cmd, &i, SDL_TRUE, SDL_FALSE, SDL_FALSE, SDL_TRUE ) ) + if(!mon_getnum(oric, &v, cmd, &i, SDL_TRUE, SDL_FALSE, SDL_FALSE, SDL_TRUE)) { - mon_str( "Bad address" ); + mon_str("Bad address"); break; } - if( mw_split ) + if(mw_split) { mw_addr[mw_which] = v; - } else { + } + else + { mw_which = 0; mw_addr[0] = v; } @@ -2982,146 +3271,170 @@ SDL_bool mon_cmd( char *cmd, struct machine *oric, SDL_bool *needrender ) break; default: - if( ( cmd[i] != 0 ) && ( !isws( cmd[i] ) ) ) + if((cmd[i] != 0) && (!isws(cmd[i]))) { - mon_str( "???" ); + mon_str("???"); break; } - if( mon_getnum( oric, &v, cmd, &i, SDL_TRUE, SDL_FALSE, SDL_FALSE, SDL_TRUE ) ) + if(mon_getnum(oric, &v, cmd, &i, SDL_TRUE, SDL_FALSE, SDL_FALSE, SDL_TRUE)) mon_addr = v; - for( j=0; j<16; j++ ) + for(j=0; j<16; j++) { - sprintf( vsptmp, "%04X ", mon_addr ); - for( k=0; k<8; k++ ) + sprintf(vsptmp, "%04X ", mon_addr); + for(k=0; k<8; k++) { char tmp[8]; - snprintf( tmp, 7, "%02X ", mon_read( oric, mon_addr+k ) ); - strcat( vsptmp, tmp ); + snprintf(tmp, 7, "%02X ", mon_read(oric, mon_addr+k)); + strcat(vsptmp, tmp); } - l = (int)strlen( vsptmp ); + l = (int)strlen(vsptmp); vsptmp[l++] = 32; vsptmp[l++] = '\''; - for( k=0; k<8; k++ ) + for(k=0; k<8; k++) { - v = mon_read( oric, mon_addr++ ); + v = mon_read(oric, mon_addr++); vsptmp[l++] = ((v>31)&&(v<128))?v:'.'; } vsptmp[l++] = '\''; vsptmp[l++] = 0; - mon_str( vsptmp ); + mon_str(vsptmp); } break; } break; case 'd': - if( cmd[i+1] == 'f' ) - { - i+=2; - - if( !mon_getnum( oric, &v, cmd, &i, SDL_TRUE, SDL_FALSE, SDL_FALSE, SDL_TRUE ) ) - { - mon_str( "Start address expected\n" ); - break; - } - - mon_addr = v; - if( !mon_getnum( oric, &v, cmd, &i, SDL_TRUE, SDL_FALSE, SDL_FALSE, SDL_TRUE ) ) - { - mon_str( "End address expected\n" ); - break; - } - - while( isws( cmd[i] ) ) i++; - if( !cmd[i] ) - { - mon_str( "Filename expected" ); - break; - } - - f = fopen( &cmd[i], "w" ); - if( !f ) - { - mon_printf( "Unable to open '%s'", &cmd[i] ); - break; - } - - while( mon_addr <= v ) - { - SDL_bool looped; - fprintf( f, "%s\n", mon_disassemble( oric, &mon_addr, &looped, SDL_TRUE ) ); - if( looped ) break; - } - - fclose( f ); - break; - } - - lastcmd = cmd[i]; + lastcmd = ARPT_DISASM; i++; - if( mon_getnum( oric, &v, cmd, &i, SDL_TRUE, SDL_FALSE, SDL_FALSE, SDL_TRUE ) ) + if(mon_getnum(oric, &v, cmd, &i, SDL_TRUE, SDL_FALSE, SDL_FALSE, SDL_TRUE)) mon_addr = v; - for( j=0; j<16; j++ ) - mon_str( mon_disassemble( oric, &mon_addr, NULL, SDL_FALSE ) ); + for(j=0; j<16; j++) + mon_str(mon_disassemble(oric, &mon_addr, NULL, SDL_FALSE)); break; case 'r': lastcmd = 0; i++; - j = mon_getreg( cmd, &i, SDL_TRUE, SDL_TRUE, SDL_TRUE ); - if( j == -1 ) + j = mon_getreg(cmd, &i, SDL_TRUE, SDL_TRUE, SDL_TRUE); + if(j == -1) { - mon_str( "Register expected" ); + mon_str("Register expected"); break; } - if( !mon_getnum( oric, &v, cmd, &i, SDL_TRUE, SDL_TRUE, SDL_TRUE, SDL_TRUE ) ) + if(!mon_getnum(oric, &v, cmd, &i, SDL_TRUE, SDL_TRUE, SDL_TRUE, SDL_TRUE)) { - mon_str( "Expression expected" ); + mon_str("Expression expected"); break; } - switch( j ) + switch(j) { - case REG_PC: mon_set_modified( oric ); oric->cpu.pc = v; break; - case REG_SP: mon_set_modified( oric ); oric->cpu.sp = v; break; - case REG_A: mon_set_modified( oric ); oric->cpu.a = v; break; - case REG_X: mon_set_modified( oric ); oric->cpu.x = v; break; - case REG_Y: mon_set_modified( oric ); oric->cpu.y = v; break; - - case REG_VIA_PCR: mon_set_modified( oric ); via_write( &oric->via, VIA_PCR, v ); break; - case REG_VIA_ACR: mon_set_modified( oric ); via_write( &oric->via, VIA_ACR, v ); break; - case REG_VIA_SR: mon_set_modified( oric ); via_write( &oric->via, VIA_SR, v ); break; - case REG_VIA_IFR: mon_set_modified( oric ); via_mon_write_ifr( &oric->via, v ); break; - case REG_VIA_IER: mon_set_modified( oric ); oric->via.ier = v&0x7f; break; - case REG_VIA_IRA: mon_set_modified( oric ); oric->via.write_port_a( &oric->via, 0xff, v ); break; - case REG_VIA_ORA: mon_set_modified( oric ); via_write( &oric->via, VIA_IORA, v ); break; - case REG_VIA_DDRA: mon_set_modified( oric ); via_write( &oric->via, VIA_DDRA, v ); break; - case REG_VIA_IRB: mon_set_modified( oric ); oric->via.write_port_b( &oric->via, 0xff, v ); break; - case REG_VIA_ORB: mon_set_modified( oric ); via_write( &oric->via, VIA_IORB, v ); break; - case REG_VIA_DDRB: mon_set_modified( oric ); via_write( &oric->via, VIA_DDRB, v ); break; - case REG_VIA_T1C: mon_set_modified( oric ); oric->via.t1c = v; break; - case REG_VIA_CA1: mon_set_modified( oric ); via_write_CA1( &oric->via, v ); break; - case REG_VIA_CA2: mon_set_modified( oric ); via_write_CA2( &oric->via, v ); break; - case REG_VIA_CB1: mon_set_modified( oric ); via_write_CB1( &oric->via, v ); break; - case REG_VIA_CB2: mon_set_modified( oric ); via_write_CB2( &oric->via, v ); break; - case REG_VIA_T2C: mon_set_modified( oric ); oric->via.t2c = v; break; + case REG_PC: + mon_set_modified(oric); + oric->cpu.pc = v; + break; + case REG_SP: + mon_set_modified(oric); + oric->cpu.sp = v; + break; + case REG_A: + mon_set_modified(oric); + oric->cpu.a = v; + break; + case REG_X: + mon_set_modified(oric); + oric->cpu.x = v; + break; + case REG_Y: + mon_set_modified(oric); + oric->cpu.y = v; + break; + + case REG_VIA_PCR: + mon_set_modified(oric); + via_write(&oric->via, VIA_PCR, v); + break; + case REG_VIA_ACR: + mon_set_modified(oric); + via_write(&oric->via, VIA_ACR, v); + break; + case REG_VIA_SR: + mon_set_modified(oric); + via_write(&oric->via, VIA_SR, v); + break; + case REG_VIA_IFR: + mon_set_modified(oric); + via_mon_write_ifr(&oric->via, v); + break; + case REG_VIA_IER: + mon_set_modified(oric); + oric->via.ier = v&0x7f; + break; + case REG_VIA_IRA: + mon_set_modified(oric); + oric->via.write_port_a(&oric->via, 0xff, v); + break; + case REG_VIA_ORA: + mon_set_modified(oric); + via_write(&oric->via, VIA_IORA, v); + break; + case REG_VIA_DDRA: + mon_set_modified(oric); + via_write(&oric->via, VIA_DDRA, v); + break; + case REG_VIA_IRB: + mon_set_modified(oric); + oric->via.write_port_b(&oric->via, 0xff, v); + break; + case REG_VIA_ORB: + mon_set_modified(oric); + via_write(&oric->via, VIA_IORB, v); + break; + case REG_VIA_DDRB: + mon_set_modified(oric); + via_write(&oric->via, VIA_DDRB, v); + break; + case REG_VIA_T1C: + mon_set_modified(oric); + oric->via.t1c = v; + break; + case REG_VIA_CA1: + mon_set_modified(oric); + via_write_CA1(&oric->via, v); + break; + case REG_VIA_CA2: + mon_set_modified(oric); + via_write_CA2(&oric->via, v); + break; + case REG_VIA_CB1: + mon_set_modified(oric); + via_write_CB1(&oric->via, v); + break; + case REG_VIA_CB2: + mon_set_modified(oric); + via_write_CB2(&oric->via, v); + break; + case REG_VIA_T2C: + mon_set_modified(oric); + oric->via.t2c = v; + break; case REG_VIA_T1L: - mon_set_modified( oric ); - via_write( &oric->via, VIA_T1L_L, v&0xff ); - via_write( &oric->via, VIA_T1L_H, (v>>8)&0xff ); + mon_set_modified(oric); + via_write(&oric->via, VIA_T1L_L, v&0xff); + via_write(&oric->via, VIA_T1L_H, (v>>8)&0xff); break; case REG_VIA_T2L: - mon_set_modified( oric ); - via_write( &oric->via, VIA_T2C_L, v&0xff ); - via_write( &oric->via, VIA_T2C_H, (v>>8)&0xff ); + mon_set_modified(oric); + via_write(&oric->via, VIA_T2C_L, v&0xff); + via_write(&oric->via, VIA_T2C_H, (v>>8)&0xff); break; } @@ -3133,14 +3446,14 @@ SDL_bool mon_cmd( char *cmd, struct machine *oric, SDL_bool *needrender ) return SDL_FALSE; case 'q': - lastcmd = cmd[i]; - switch( cmd[i+1] ) + lastcmd = ARPT_QUIT; + switch(cmd[i+1]) { case 32: case 0: case 'm': - mon_store_state( oric ); - setemumode( oric, NULL, EM_RUNNING ); + mon_store_state(oric); + setemumode(oric, NULL, EM_RUNNING); break; case 'e': @@ -3148,64 +3461,148 @@ SDL_bool mon_cmd( char *cmd, struct machine *oric, SDL_bool *needrender ) break; default: - mon_printf( "???" ); + mon_printf("???"); break; } break; case 'x': - mon_store_state( oric ); - setemumode( oric, NULL, EM_RUNNING ); + mon_store_state(oric); + setemumode(oric, NULL, EM_RUNNING); break; - case 'w': + case 'f': lastcmd = 0; i++; - switch( cmd[i] ) + switch(cmd[i]) { - case 'm': + // fd - disassemble to file + case 'd': i++; - if( !mon_getnum( oric, &v, cmd, &i, SDL_TRUE, SDL_TRUE, SDL_TRUE, SDL_TRUE ) ) + if(!mon_getnum(oric, &v, cmd, &i, SDL_TRUE, SDL_FALSE, SDL_FALSE, SDL_TRUE)) { - mon_str( "Address expected" ); + mon_str("Start address expected\n"); break; } - if( !mon_getnum( oric, &w, cmd, &i, SDL_TRUE, SDL_TRUE, SDL_TRUE, SDL_TRUE ) ) + mon_addr = v; + if(!mon_getnum(oric, &v, cmd, &i, SDL_TRUE, SDL_FALSE, SDL_FALSE, SDL_TRUE)) { - mon_str( "Size expected" ); + mon_str("End address expected\n"); break; } - while( isws( cmd[i] ) ) i++; - if( !cmd[i] ) + while(isws(cmd[i])) i++; + if(!cmd[i]) { - mon_str( "Filename expected" ); + mon_str("Filename expected"); break; } - tmem = malloc( w ); - if( !tmem ) + f = fopen(&cmd[i], "w"); + if(!f) { - mon_str( "Amnesia!" ); + mon_printf("Unable to open '%s'", &cmd[i]); break; } - for( j=0; jcpu.write(&oric->cpu, v & 0xffff, w & 0xff); + v++; + j++; + } + } + fclose(f); + mon_printf("%d bytes read from '%s'", j, &cmd[i]); + updatepreview = SDL_TRUE; break; } break; @@ -3214,29 +3611,29 @@ SDL_bool mon_cmd( char *cmd, struct machine *oric, SDL_bool *needrender ) lastcmd = 0; i++; j = cmd[i]; - switch( j ) + switch(j) { case 'l': case 's': i++; - while( isws( cmd[i] ) ) i++; - if( !cmd[i] ) + while(isws(cmd[i])) i++; + if(!cmd[i]) { - mon_str( "Filename expected" ); + mon_str("Filename expected"); break; } joinpath(snappath, &cmd[i]); - if (j == 'l') + if(j == 'l') { - if (!load_snapshot(oric, filetmp)) + if(!load_snapshot(oric, filetmp)) mon_printf("Snapshot load failed"); else mon_printf("Snapshot loaded"); } else { - if (!save_snapshot(oric, filetmp)) + if(!save_snapshot(oric, filetmp)) mon_printf("Snapshot save failed"); else mon_printf("Snapshot saved"); @@ -3244,56 +3641,82 @@ SDL_bool mon_cmd( char *cmd, struct machine *oric, SDL_bool *needrender ) break; default: - mon_printf( "???" ); + mon_printf("???"); break; } break; case '?': - lastcmd = cmd[i]; - switch( helpcount ) + lastcmd = ARPT_HELP; + switch(helpcount) { case 0: - mon_str( "KEYS:" ); + mon_str("KEYS:"); // | - | - | - mon_str( " F2 : Quit Monitor F3 : Toggle Console" ); - mon_str( " F4 : Toggle info F9 : Reset cycles" ); - mon_str( " F10: Step into F11: Step over" ); - mon_str( " F12: Skip inst." ); - mon_str( " " ); - mon_str( "COMMANDS:" ); - mon_str( " a - Assemble" ); - mon_str( " bc - Clear breakpoint" ); - mon_str( " bcm - Clear mem breakpoint" ); - mon_str( " bl - List breakpoints" ); - mon_str( " blm - List mem breakpoints" ); - mon_str( " bs [zc] - Set breakpoint/cycles" ); - mon_str( " bsm [rwc] - Set mem breakpoint" ); - mon_str( " bz - Zap breakpoints" ); - mon_str( " bzm - Zap mem breakpoints" ); - mon_str( " d - Disassemble" ); - mon_str( "---- MORE" ); + mon_str(" F2 : Quit Monitor F3 : Toggle Console"); + mon_str(" F4 : Toggle info F9 : Reset cycles"); + mon_str(" F10: Step into F11: Step over"); + mon_str(" F12: Skip inst."); + mon_str(" "); + mon_str("COMMANDS:"); + mon_str(" a - Assemble"); + mon_str(" bc - Clear breakpoint"); + mon_str(" bcm - Clear mem breakpoint"); + mon_str(" bl - List breakpoints"); + mon_str(" blm - List mem breakpoints"); + mon_str(" bs [zct] - Set breakpoint/cycles"); + mon_str(" bsm [rwc] - Set mem breakpoint"); + mon_str(" bz - Zap breakpoints"); + mon_str(" bzm - Zap mem breakpoints"); + mon_str(" d - Disassemble"); + mon_str("---- MORE"); helpcount++; break; case 1: - mon_str( " df - Disassemble to file" ); - mon_str( " m - Dump memory" ); - mon_str( " mm - Modify memory" ); - mon_str( " mw - Memory watch at addr" ); - mon_str( " nl - Load snapshot" ); - mon_str( " ns - Save snapshot" ); - mon_str( " r - Set to " ); - mon_str( " q, x or qm - Quit monitor" ); - mon_str( " qe - Quit emulator" ); - mon_str( " sa - Add or move user sym." ); - mon_str( " sk - Kill user symbol" ); - mon_str( " sc - Symbols not case-sens." ); - mon_str( " sC - Symbols case-sensitive" ); - mon_str( " sl - Load user symbols" ); - mon_str( " sx - Export user symbols" ); - mon_str( " sz - Zap user symbols" ); - mon_str( " wm - Write mem to disk" ); + mon_str(" m - Dump memory"); + mon_str(" mm - Modify memory"); + mon_str(" mw - Memory watch at addr"); + mon_str(" ms - Memory search"); + mon_str(" mr - Memory search refine"); + mon_str(" mp - Memory print search"); + mon_str(" nl - Load snapshot"); + mon_str(" ns - Save snapshot"); + mon_str(" r - Set to "); + mon_str(" q, x or qm - Quit monitor"); + mon_str(" qe - Quit emulator"); + mon_str(" sa - Add or move user sym."); + mon_str(" sk - Kill user symbol"); + mon_str(" sc - Symbols not case-sens."); + mon_str(" sC - Symbols case-sensitive"); + mon_str(" sl - Load user symbols"); + mon_str(" sx - Export user symbols"); + mon_str(" sz - Zap user symbols"); + mon_str(" "); + mon_str("---- MORE"); + helpcount++; + break; + + case 2: + mon_str(" fd - Disassemble to file"); + mon_str(" fw - Write mem to bin file"); + // ToDo: mon_str( " ft - Write mem to tap file" ); + mon_str(" fr - Read bin file to mem"); + mon_str(" "); + mon_str(" "); + mon_str(" "); + mon_str(" "); + mon_str(" "); + mon_str(" "); + mon_str(" "); + mon_str(" "); + mon_str(" "); + mon_str(" "); + mon_str(" "); + mon_str(" "); + mon_str(" "); + mon_str(" "); + mon_str(" "); helpcount = 0; lastcmd = 0; break; @@ -3302,69 +3725,71 @@ SDL_bool mon_cmd( char *cmd, struct machine *oric, SDL_bool *needrender ) default: lastcmd = 0; - mon_printf( "???" ); + mon_printf("???"); break; } return done; } -SDL_bool mon_do_cmd( char *cmd, struct machine *oric, SDL_bool *needrender ) +SDL_bool mon_do_cmd(char* cmd, struct machine *oric, SDL_bool *needrender) { int i; SDL_bool ret; mon_hide_curs(); for(i=2; i<49; i++) tz[TZ_MONITOR]->tx[50*19+i] = 32; - tzstrpos( tz[TZ_MONITOR], 2, 19, cmd ); - tzsetcol( tz[TZ_MONITOR], 2, 3 ); - ret = mon_cmd( cmd, oric, needrender ); + tzstrpos(tz[TZ_MONITOR], 2, 19, cmd); + tzsetcol(tz[TZ_MONITOR], 2, 3); + ret = mon_cmd(cmd, oric, needrender); mon_start_input(); mon_show_curs(); return ret; } -static void mon_write_ibuf( void ) +static void mon_write_ibuf(void) { char ibtmp[CONS_WIDTH+1]; - strncpy( ibtmp, &ibuf[iloff], CONS_WIDTH ); + strncpy(ibtmp, &ibuf[iloff], CONS_WIDTH); ibtmp[CONS_WIDTH] = 0; - tzstrpos( tz[TZ_MONITOR], 1, 19, iloff > 0 ? "\x16" : "]" ); - tzstrpos( tz[TZ_MONITOR], 2, 19, ibtmp ); - if( strlen( &ibuf[iloff] ) > CONS_WIDTH ) + tzstrpos(tz[TZ_MONITOR], 1, 19, iloff > 0 ? "\x16" : "]"); + tzstrpos(tz[TZ_MONITOR], 2, 19, ibtmp); + if(strlen(&ibuf[iloff]) > CONS_WIDTH) { - tzstrpos( tz[TZ_MONITOR], 2+CONS_WIDTH, 19, "\x16" ); - } else { - tzstr( tz[TZ_MONITOR], " " ); - tzstrpos( tz[TZ_MONITOR], 2+CONS_WIDTH, 19, " " ); + tzstrpos(tz[TZ_MONITOR], 2+CONS_WIDTH, 19, "\x16"); + } + else + { + tzstr(tz[TZ_MONITOR], " "); + tzstrpos(tz[TZ_MONITOR], 2+CONS_WIDTH, 19, " "); } } -static void mon_write_ibuf_asm( void ) +static void mon_write_ibuf_asm(void) { char ibtmp[CONS_WIDTH+1]; - strncpy( ibtmp, ibuf, CONS_WIDTH ); + strncpy(ibtmp, ibuf, CONS_WIDTH); ibtmp[CONS_WIDTH] = 0; - tzstrpos( tz[TZ_MONITOR], 8, 19, ibtmp ); - tzstr( tz[TZ_MONITOR], " " ); + tzstrpos(tz[TZ_MONITOR], 8, 19, ibtmp); + tzstr(tz[TZ_MONITOR], " "); } -static void mon_set_curs_to_end( void ) +static void mon_set_curs_to_end(void) { cursx = ilen; iloff = ilen-CONS_WIDTH; - if( iloff < 0 ) iloff = 0; + if(iloff < 0) iloff = 0; } -static void mon_set_iloff( void ) +static void mon_set_iloff(void) { - if( cursx < iloff ) iloff = cursx; - if( cursx >= (iloff+CONS_WIDTH) ) iloff = cursx-CONS_WIDTH; - if( iloff < 0 ) iloff =0; + if(cursx < iloff) iloff = cursx; + if(cursx >= (iloff+CONS_WIDTH)) iloff = cursx-CONS_WIDTH; + if(iloff < 0) iloff =0; } /* @@ -3381,26 +3806,26 @@ static void mon_set_iloff( void ) AM_REL, <-- AM_ABS - AM_IND (nnnn) */ -static SDL_bool mon_decodeoperand( struct machine *oric, char *ptr, int *type, unsigned short *val ) +static SDL_bool mon_decodeoperand(struct machine *oric, char* ptr, int* type, unsigned short* val) { int i; unsigned int v; i=0; - while( isws( ptr[i] ) ) i++; + while(isws(ptr[i])) i++; // Implied - if( ptr[i] == 0 ) + if(ptr[i] == 0) { (*type) = AM_IMP; return SDL_TRUE; } // Immediate - if( ptr[i] == '#' ) + if(ptr[i] == '#') { i++; - if( !mon_getnum( oric, &v, ptr, &i, SDL_FALSE, SDL_FALSE, SDL_FALSE, SDL_TRUE ) ) + if(!mon_getnum(oric, &v, ptr, &i, SDL_FALSE, SDL_FALSE, SDL_FALSE, SDL_TRUE)) return SDL_FALSE; (*type) = AM_IMM; (*val) = v; @@ -3408,27 +3833,27 @@ static SDL_bool mon_decodeoperand( struct machine *oric, char *ptr, int *type, u } // ZIX, ZIY, IND - if( ptr[i] == '(' ) + if(ptr[i] == '(') { i++; - if( !mon_getnum( oric, &v, ptr, &i, SDL_TRUE, SDL_TRUE, SDL_FALSE, SDL_TRUE ) ) + if(!mon_getnum(oric, &v, ptr, &i, SDL_TRUE, SDL_TRUE, SDL_FALSE, SDL_TRUE)) return SDL_FALSE; - if( strncasecmp( &ptr[i], ",X)", 3 ) == 0 ) + if(strncasecmp(&ptr[i], ",X)", 3) == 0) { (*type) = AM_ZIX; (*val) = v&0xff; return SDL_TRUE; } - if( strncasecmp( &ptr[i], "),Y", 3 ) == 0 ) + if(strncasecmp(&ptr[i], "),Y", 3) == 0) { (*type) = AM_ZIY; (*val) = v&0xff; return SDL_TRUE; } - if( ptr[i] == ')' ) + if(ptr[i] == ')') { (*type) = AM_IND; (*val) = v; @@ -3438,17 +3863,17 @@ static SDL_bool mon_decodeoperand( struct machine *oric, char *ptr, int *type, u return SDL_FALSE; } - if( !mon_getnum( oric, &v, ptr, &i, SDL_TRUE, SDL_TRUE, SDL_FALSE, SDL_TRUE ) ) + if(!mon_getnum(oric, &v, ptr, &i, SDL_TRUE, SDL_TRUE, SDL_FALSE, SDL_TRUE)) return SDL_FALSE; - if( strncasecmp( &ptr[i], ",X", 2 ) == 0 ) + if(strncasecmp(&ptr[i], ",X", 2) == 0) { (*type) = AM_ABX; (*val) = v; return SDL_TRUE; } - if( strncasecmp( &ptr[i], ",Y", 2 ) == 0 ) + if(strncasecmp(&ptr[i], ",Y", 2) == 0) { (*type) = AM_ABY; (*val) = v; @@ -3460,183 +3885,223 @@ static SDL_bool mon_decodeoperand( struct machine *oric, char *ptr, int *type, u return SDL_TRUE; } -static SDL_bool mon_assemble_line( struct machine *oric ) +static SDL_bool mon_assemble_line(struct machine *oric) { int i, j, addsym, amode; unsigned short val; i=0; - while( isws( ibuf[i] ) ) i++; + while(isws(ibuf[i])) i++; - if( ibuf[i] == 0 ) return SDL_TRUE; + if(ibuf[i] == 0) return SDL_TRUE; // Starts with a label? j = i; addsym = -1; - if( issymstart( ibuf[j] ) ) + if(issymstart(ibuf[j])) { - while( issymchar( ibuf[j] ) ) j++; - if( ibuf[j] == ':' ) + while(issymchar(ibuf[j])) j++; + if(ibuf[j] == ':') { addsym = i; i = j+1; - while( isws( ibuf[i] ) ) i++; + while(isws(ibuf[i])) i++; } } - for( j=0; asmtab[j].name; j++ ) + for(j=0; asmtab[j].name; j++) { - if( strncasecmp( asmtab[j].name, &ibuf[i], 3 ) == 0 ) + if(strncasecmp(asmtab[j].name, &ibuf[i], 3) == 0) break; } - if( !asmtab[j].name ) + if(!asmtab[j].name) { - mon_oprintf( " %04X %c%c%c ??? ", mon_addr, ibuf[i], ibuf[i+1], ibuf[i+2] ); + mon_oprintf(" %04X %c%c%c ??? ", mon_addr, ibuf[i], ibuf[i+1], ibuf[i+2]); return SDL_FALSE; } i += 3; - if( !mon_decodeoperand( oric, &ibuf[i], &amode, &val ) ) + if(!mon_decodeoperand(oric, &ibuf[i], &amode, &val)) { - mon_str( "Illegal operand" ); + mon_str("Illegal operand"); return SDL_FALSE; } - switch( amode ) + switch(amode) { case AM_IMP: - if( asmtab[j].imp == -1 ) { mon_str( "Operand expected" ); return SDL_FALSE; } - mon_set_modified( oric ); - oric->cpu.write( &oric->cpu, mon_addr, asmtab[j].imp ); + if(asmtab[j].imp == -1) + { + mon_str("Operand expected"); + return SDL_FALSE; + } + mon_set_modified(oric); + oric->cpu.write(&oric->cpu, mon_addr, asmtab[j].imp); break; case AM_IMM: - if( asmtab[j].imm == -1 ) { mon_str( "Illegal operand" ); return SDL_FALSE; } - mon_set_modified( oric ); - oric->cpu.write( &oric->cpu, mon_addr, asmtab[j].imm ); - oric->cpu.write( &oric->cpu, mon_addr+1, val ); + if(asmtab[j].imm == -1) + { + mon_str("Illegal operand"); + return SDL_FALSE; + } + mon_set_modified(oric); + oric->cpu.write(&oric->cpu, mon_addr, asmtab[j].imm); + oric->cpu.write(&oric->cpu, mon_addr+1, val); break; case AM_ABS: - if( asmtab[j].rel != -1 ) + if(asmtab[j].rel != -1) { i = ((int)val)-((int)(mon_addr+2)); - if( ( i < -128 ) || ( i > 127 ) ) + if((i < -128) || (i > 127)) { - mon_str( "Branch out of range" ); + mon_str("Branch out of range"); return SDL_FALSE; } - mon_set_modified( oric ); - oric->cpu.write( &oric->cpu, mon_addr, asmtab[j].rel ); - oric->cpu.write( &oric->cpu, mon_addr+1, i&0xff ); + mon_set_modified(oric); + oric->cpu.write(&oric->cpu, mon_addr, asmtab[j].rel); + oric->cpu.write(&oric->cpu, mon_addr+1, i&0xff); break; } - if( ( asmtab[j].zp != -1 ) && ( (val&0xff00)==0 ) ) + if((asmtab[j].zp != -1) && ((val&0xff00)==0)) { - mon_set_modified( oric ); - oric->cpu.write( &oric->cpu, mon_addr, asmtab[j].zp ); - oric->cpu.write( &oric->cpu, mon_addr+1, val ); + mon_set_modified(oric); + oric->cpu.write(&oric->cpu, mon_addr, asmtab[j].zp); + oric->cpu.write(&oric->cpu, mon_addr+1, val); break; } - if( asmtab[j].abs == -1 ) { mon_str( "Illegal operand" ); return SDL_FALSE; } - mon_set_modified( oric ); - oric->cpu.write( &oric->cpu, mon_addr, asmtab[j].abs ); - oric->cpu.write( &oric->cpu, mon_addr+1, val&0xff ); - oric->cpu.write( &oric->cpu, mon_addr+2, (val>>8)&0xff ); + if(asmtab[j].abs == -1) + { + mon_str("Illegal operand"); + return SDL_FALSE; + } + mon_set_modified(oric); + oric->cpu.write(&oric->cpu, mon_addr, asmtab[j].abs); + oric->cpu.write(&oric->cpu, mon_addr+1, val&0xff); + oric->cpu.write(&oric->cpu, mon_addr+2, (val>>8)&0xff); break; case AM_IND: - if( asmtab[j].ind == -1 ) { mon_str( "Illegal operand" ); return SDL_FALSE; } - mon_set_modified( oric ); - oric->cpu.write( &oric->cpu, mon_addr, asmtab[j].ind ); - oric->cpu.write( &oric->cpu, mon_addr+1, val&0xff ); - oric->cpu.write( &oric->cpu, mon_addr+2, (val>>8)&0xff ); + if(asmtab[j].ind == -1) + { + mon_str("Illegal operand"); + return SDL_FALSE; + } + mon_set_modified(oric); + oric->cpu.write(&oric->cpu, mon_addr, asmtab[j].ind); + oric->cpu.write(&oric->cpu, mon_addr+1, val&0xff); + oric->cpu.write(&oric->cpu, mon_addr+2, (val>>8)&0xff); break; case AM_ZPX: - if( asmtab[j].zpx == -1 ) { mon_str( "Illegal operand" ); return SDL_FALSE; } - mon_set_modified( oric ); - oric->cpu.write( &oric->cpu, mon_addr, asmtab[j].zpx ); - oric->cpu.write( &oric->cpu, mon_addr+1, val ); + if(asmtab[j].zpx == -1) + { + mon_str("Illegal operand"); + return SDL_FALSE; + } + mon_set_modified(oric); + oric->cpu.write(&oric->cpu, mon_addr, asmtab[j].zpx); + oric->cpu.write(&oric->cpu, mon_addr+1, val); break; case AM_ZPY: - if( asmtab[j].zpy == -1 ) { mon_str( "Illegal operand" ); return SDL_FALSE; } - mon_set_modified( oric ); - oric->cpu.write( &oric->cpu, mon_addr, asmtab[j].zpy ); - oric->cpu.write( &oric->cpu, mon_addr+1, val ); + if(asmtab[j].zpy == -1) + { + mon_str("Illegal operand"); + return SDL_FALSE; + } + mon_set_modified(oric); + oric->cpu.write(&oric->cpu, mon_addr, asmtab[j].zpy); + oric->cpu.write(&oric->cpu, mon_addr+1, val); break; case AM_ZIX: - if( asmtab[j].zix == -1 ) { mon_str( "Illegal operand" ); return SDL_FALSE; } - mon_set_modified( oric ); - oric->cpu.write( &oric->cpu, mon_addr, asmtab[j].zix ); - oric->cpu.write( &oric->cpu, mon_addr+1, val ); + if(asmtab[j].zix == -1) + { + mon_str("Illegal operand"); + return SDL_FALSE; + } + mon_set_modified(oric); + oric->cpu.write(&oric->cpu, mon_addr, asmtab[j].zix); + oric->cpu.write(&oric->cpu, mon_addr+1, val); break; case AM_ZIY: - if( asmtab[j].ziy == -1 ) { mon_str( "Illegal operand" ); return SDL_FALSE; } - mon_set_modified( oric ); - oric->cpu.write( &oric->cpu, mon_addr, asmtab[j].ziy ); - oric->cpu.write( &oric->cpu, mon_addr+1, val ); + if(asmtab[j].ziy == -1) + { + mon_str("Illegal operand"); + return SDL_FALSE; + } + mon_set_modified(oric); + oric->cpu.write(&oric->cpu, mon_addr, asmtab[j].ziy); + oric->cpu.write(&oric->cpu, mon_addr+1, val); break; case AM_ABX: - if( ( asmtab[j].zpx != -1 ) && ( (val&0xff00)==0 ) ) + if((asmtab[j].zpx != -1) && ((val&0xff00)==0)) { - mon_set_modified( oric ); - oric->cpu.write( &oric->cpu, mon_addr, asmtab[j].zpx ); - oric->cpu.write( &oric->cpu, mon_addr+1, val ); + mon_set_modified(oric); + oric->cpu.write(&oric->cpu, mon_addr, asmtab[j].zpx); + oric->cpu.write(&oric->cpu, mon_addr+1, val); break; } - if( asmtab[j].abx == -1 ) { mon_str( "Illegal operand" ); return SDL_FALSE; } - mon_set_modified( oric ); - oric->cpu.write( &oric->cpu, mon_addr, asmtab[j].abx ); - oric->cpu.write( &oric->cpu, mon_addr+1, val&0xff ); - oric->cpu.write( &oric->cpu, mon_addr+2, (val>>8)&0xff ); + if(asmtab[j].abx == -1) + { + mon_str("Illegal operand"); + return SDL_FALSE; + } + mon_set_modified(oric); + oric->cpu.write(&oric->cpu, mon_addr, asmtab[j].abx); + oric->cpu.write(&oric->cpu, mon_addr+1, val&0xff); + oric->cpu.write(&oric->cpu, mon_addr+2, (val>>8)&0xff); break; case AM_ABY: - if( ( asmtab[j].zpy != -1 ) && ( (val&0xff00)==0 ) ) + if((asmtab[j].zpy != -1) && ((val&0xff00)==0)) { - mon_set_modified( oric ); - oric->cpu.write( &oric->cpu, mon_addr, asmtab[j].zpy ); - oric->cpu.write( &oric->cpu, mon_addr+1, val ); + mon_set_modified(oric); + oric->cpu.write(&oric->cpu, mon_addr, asmtab[j].zpy); + oric->cpu.write(&oric->cpu, mon_addr+1, val); break; } - if( asmtab[j].aby == -1 ) { mon_str( "Illegal operand" ); return SDL_FALSE; } - mon_set_modified( oric ); - oric->cpu.write( &oric->cpu, mon_addr, asmtab[j].aby ); - oric->cpu.write( &oric->cpu, mon_addr+1, val&0xff ); - oric->cpu.write( &oric->cpu, mon_addr+2, (val>>8)&0xff ); + if(asmtab[j].aby == -1) + { + mon_str("Illegal operand"); + return SDL_FALSE; + } + mon_set_modified(oric); + oric->cpu.write(&oric->cpu, mon_addr, asmtab[j].aby); + oric->cpu.write(&oric->cpu, mon_addr+1, val&0xff); + oric->cpu.write(&oric->cpu, mon_addr+2, (val>>8)&0xff); break; } - if( addsym != -1 ) - mon_replace_or_add_symbol( &oric->usersyms, oric, &ibuf[addsym], SYM_BESTGUESS, mon_addr ); + if(addsym != -1) + mon_replace_or_add_symbol(&oric->usersyms, oric, &ibuf[addsym], SYM_BESTGUESS, mon_addr); - mon_oprintf( mon_disassemble( oric, &mon_addr, NULL, SDL_FALSE ) ); + mon_oprintf(mon_disassemble(oric, &mon_addr, NULL, SDL_FALSE)); return SDL_FALSE; } -static SDL_bool mon_console_keydown( SDL_Event *ev, struct machine *oric, SDL_bool *needrender ) +static SDL_bool mon_console_keydown(SDL_Event *ev, struct machine *oric, SDL_bool *needrender) { int i; SDL_bool done; done = SDL_FALSE; - if( mon_asmmode ) + if(mon_asmmode) { - switch( ev->key.keysym.sym ) + switch(ev->key.keysym.sym) { case SDLK_LEFT: - if( cursx > 0 ) + if(cursx > 0) { mon_hide_curs(); cursx--; @@ -3647,7 +4112,7 @@ static SDL_bool mon_console_keydown( SDL_Event *ev, struct machine *oric, SDL_bo break; case SDLK_RIGHT: - if( cursx < ilen ) + if(cursx < ilen) { mon_hide_curs(); cursx++; @@ -3658,13 +4123,13 @@ static SDL_bool mon_console_keydown( SDL_Event *ev, struct machine *oric, SDL_bo break; case SDLK_BACKSPACE: - if( cursx > 0 ) + if(cursx > 0) { mon_hide_curs(); - for( i=cursx-1; ikey.keysym ) ) + switch(SDL_COMPAT_GetKeysymUnicode(ev->key.keysym)) { default: - if( ( SDL_COMPAT_GetKeysymUnicode( ev->key.keysym ) > 31 ) && ( SDL_COMPAT_GetKeysymUnicode( ev->key.keysym ) < 127 ) ) + if((SDL_COMPAT_GetKeysymUnicode(ev->key.keysym) > 31) && (SDL_COMPAT_GetKeysymUnicode(ev->key.keysym) < 127)) { - if( ilen >= MAX_ASM_INPUT ) break; + if(ilen >= MAX_ASM_INPUT) break; mon_hide_curs(); - for( i=ilen+1; i>cursx; i-- ) + for(i=ilen+1; i>cursx; i--) ibuf[i] = ibuf[i-1]; - ibuf[cursx] = SDL_COMPAT_TranslateUnicode( ev->key.keysym ); + ibuf[cursx] = SDL_COMPAT_TranslateUnicode(ev->key.keysym); cursx++; ilen++; mon_write_ibuf_asm(); @@ -3719,16 +4184,16 @@ static SDL_bool mon_console_keydown( SDL_Event *ev, struct machine *oric, SDL_bo return done; } - switch( ev->key.keysym.sym ) + switch(ev->key.keysym.sym) { case SDLK_UP: - if( histp >= (histu-1) ) break; + if(histp >= (histu-1)) break; mon_hide_curs(); - strcpy( ibuf, &history[++histp][0] ); - ilen = (int)strlen( ibuf ); + strcpy(ibuf, &history[++histp][0]); + ilen = (int)strlen(ibuf); mon_set_curs_to_end(); mon_set_iloff(); - tzstrpos( tz[TZ_MONITOR], 2, 19, " " ); + tzstrpos(tz[TZ_MONITOR], 2, 19, " "); mon_write_ibuf(); mon_show_curs(); *needrender = SDL_TRUE; @@ -3736,26 +4201,28 @@ static SDL_bool mon_console_keydown( SDL_Event *ev, struct machine *oric, SDL_bo case SDLK_DOWN: mon_hide_curs(); - if( histp <= 0 ) + if(histp <= 0) { histp = -1; ibuf[0] = 0; ilen = 0; iloff = 0; cursx = 0; - } else { - strcpy( ibuf, &history[--histp][0] ); + } + else + { + strcpy(ibuf, &history[--histp][0]); mon_set_curs_to_end(); mon_set_iloff(); } - tzstrpos( tz[TZ_MONITOR], 2, 19, " " ); + tzstrpos(tz[TZ_MONITOR], 2, 19, " "); mon_write_ibuf(); mon_show_curs(); *needrender = SDL_TRUE; break; case SDLK_LEFT: - if( cursx > 0 ) + if(cursx > 0) { mon_hide_curs(); cursx--; @@ -3767,7 +4234,7 @@ static SDL_bool mon_console_keydown( SDL_Event *ev, struct machine *oric, SDL_bo break; case SDLK_RIGHT: - if( cursx < ilen ) + if(cursx < ilen) { mon_hide_curs(); cursx++; @@ -3782,13 +4249,13 @@ static SDL_bool mon_console_keydown( SDL_Event *ev, struct machine *oric, SDL_bo break; case SDLK_BACKSPACE: - if( cursx > 0 ) + if(cursx > 0) { mon_hide_curs(); - for( i=cursx-1; i 0 ) && ( strcmp( &history[0][0], ibuf ) == 0 ) ) + } + + else if(0 < ilen) + { + if(!((histu > 0) && (strcmp(&history[0][0], ibuf) == 0))) { - } else { - if( histu > 0 ) + if(histu > 0) { - for( i=histu; i>0; i-- ) - strcpy( &history[i][0], &history[i-1][0] ); - + for(i=histu; i>0; i--) + strcpy(&history[i][0], &history[i-1][0]); } - strcpy( &history[0][0], ibuf ); - if( histu < 10 ) histu++; + strcpy(&history[0][0], ibuf); + if(histu < 10) histu++; } } + histp = -1; - tzsetcol( tz[TZ_MONITOR], 2, 3 ); - done |= mon_cmd( ibuf, oric, needrender ); + tzsetcol(tz[TZ_MONITOR], 2, 3); + done |= mon_cmd(ibuf, oric, needrender); mon_start_input(); mon_show_curs(); *needrender = SDL_TRUE; break; } - switch( SDL_COMPAT_GetKeysymUnicode( ev->key.keysym ) ) + switch(SDL_COMPAT_GetKeysymUnicode(ev->key.keysym)) { default: - if( ( SDL_COMPAT_GetKeysymUnicode( ev->key.keysym ) > 31 ) && ( SDL_COMPAT_GetKeysymUnicode( ev->key.keysym ) < 127 ) ) + if((SDL_COMPAT_GetKeysymUnicode(ev->key.keysym) > 31) && (SDL_COMPAT_GetKeysymUnicode(ev->key.keysym) < 127)) { - if( ilen >= MAX_CONS_INPUT ) break; + if(ilen >= MAX_CONS_INPUT) break; mon_hide_curs(); - for( i=ilen+1; i>cursx; i-- ) + for(i=ilen+1; i>cursx; i--) ibuf[i] = ibuf[i-1]; - ibuf[cursx] = SDL_COMPAT_TranslateUnicode( ev->key.keysym ); + ibuf[cursx] = SDL_COMPAT_TranslateUnicode(ev->key.keysym); cursx++; ilen++; mon_set_iloff(); @@ -3859,7 +4340,7 @@ static SDL_bool mon_console_keydown( SDL_Event *ev, struct machine *oric, SDL_bo return done; } -static SDL_bool mon_mwatch_keydown( SDL_Event *ev, struct machine *oric, SDL_bool *needrender ) +static SDL_bool mon_mwatch_keydown(SDL_Event *ev, struct machine *oric, SDL_bool *needrender) { SDL_bool done; unsigned int v; @@ -3868,7 +4349,7 @@ static SDL_bool mon_mwatch_keydown( SDL_Event *ev, struct machine *oric, SDL_boo page = mw_split ? 8*8 : 8*18; done = SDL_FALSE; - switch( ev->key.keysym.sym ) + switch(ev->key.keysym.sym) { case SDLK_UP: mw_addr[mw_which] -= kshifted ? page : 8; @@ -3892,11 +4373,11 @@ static SDL_bool mon_mwatch_keydown( SDL_Event *ev, struct machine *oric, SDL_boo case SDLK_RETURN: case SDLK_KP_ENTER: - if( mw_mode != 1 ) break; + if(mw_mode != 1) break; mw_ibuf[5] = 0; mw_mode = 0; i = 0; - if( mon_getnum( oric, &v, mw_ibuf, &i, SDL_FALSE, SDL_FALSE, SDL_FALSE, SDL_FALSE ) ) + if(mon_getnum(oric, &v, mw_ibuf, &i, SDL_FALSE, SDL_FALSE, SDL_FALSE, SDL_FALSE)) mw_addr[mw_which] = v; *needrender = SDL_TRUE; break; @@ -3907,23 +4388,23 @@ static SDL_bool mon_mwatch_keydown( SDL_Event *ev, struct machine *oric, SDL_boo break; case SDLK_BACKSPACE: - if( mw_mode != 1 ) break; - if( mw_koffs <= 0 ) break; + if(mw_mode != 1) break; + if(mw_koffs <= 0) break; mw_ibuf[mw_koffs--] = 0; *needrender = SDL_TRUE; break; case SDLK_s: - if( mw_mode != 0 ) break; + if(mw_mode != 0) break; mw_split = !mw_split; - if( ( !mw_split ) && ( mw_which != 0 ) ) + if((!mw_split) && (mw_which != 0)) mw_which = 0; *needrender = SDL_TRUE; break; case SDLK_TAB: - if( !mw_split ) break; - if( mw_mode != 0 ) mw_mode = 0; + if(!mw_split) break; + if(mw_mode != 0) mw_mode = 0; mw_which ^= 1; *needrender = SDL_TRUE; break; @@ -3932,9 +4413,9 @@ static SDL_bool mon_mwatch_keydown( SDL_Event *ev, struct machine *oric, SDL_boo break; } - if( ishex( SDL_COMPAT_GetKeysymUnicode( ev->key.keysym ) ) ) + if(ishex(SDL_COMPAT_GetKeysymUnicode(ev->key.keysym))) { - if( mw_mode != 1 ) + if(mw_mode != 1) { mw_mode = 1; mw_ibuf[0] = '$'; @@ -3942,9 +4423,9 @@ static SDL_bool mon_mwatch_keydown( SDL_Event *ev, struct machine *oric, SDL_boo mw_koffs = 0; } - if( mw_koffs < 4 ) + if(mw_koffs < 4) { - mw_ibuf[++mw_koffs] = SDL_COMPAT_TranslateUnicode( ev->key.keysym ); + mw_ibuf[++mw_koffs] = SDL_COMPAT_TranslateUnicode(ev->key.keysym); mw_ibuf[mw_koffs+1] = 0; } @@ -3954,32 +4435,32 @@ static SDL_bool mon_mwatch_keydown( SDL_Event *ev, struct machine *oric, SDL_boo return done; } -static unsigned int steppy_step( struct machine *oric ) +static unsigned int steppy_step(struct machine *oric) { - m6502_set_icycles( &oric->cpu, SDL_FALSE, mon_bpmsg ); - tape_patches( oric ); - via_clock( &oric->via, oric->cpu.icycles ); - ay_ticktock( &oric->ay, oric->cpu.icycles ); - if((oric->drivetype == DRV_MICRODISC) || (oric->drivetype == DRV_JASMIN)) wd17xx_ticktock( &oric->wddisk, oric->cpu.icycles ); - if( oric->type == MACH_TELESTRAT ) + m6502_set_icycles(&oric->cpu, SDL_FALSE, mon_bpmsg); + tape_patches(oric); + via_clock(&oric->via, oric->cpu.icycles); + ay_ticktock(&oric->ay, oric->cpu.icycles); + if((oric->drivetype == DRV_MICRODISC) || (oric->drivetype == DRV_JASMIN)) wd17xx_ticktock(&oric->wddisk, oric->cpu.icycles); + if(oric->type == MACH_TELESTRAT) { - via_clock( &oric->tele_via, oric->cpu.icycles ); + via_clock(&oric->tele_via, oric->cpu.icycles); } - if( oric->aciabackend ) - acia_clock( &oric->tele_acia, oric->cpu.icycles ); + if(oric->aciabackend) + acia_clock(&oric->tele_acia, oric->cpu.icycles); oric->cpu.rastercycles -= oric->cpu.icycles; - m6502_inst( &oric->cpu ); + m6502_inst(&oric->cpu); - if( oric->cpu.rastercycles <= 0 ) + if(oric->cpu.rastercycles <= 0) { - ula_doraster( oric ); + ula_doraster(oric); oric->cpu.rastercycles += oric->cyclesperraster; } - if( mon_bpmsg[0] ) + if(mon_bpmsg[0]) { - mon_printf_above( mon_bpmsg ); + mon_printf_above(mon_bpmsg); mon_bpmsg[0] = 0; } @@ -3987,11 +4468,11 @@ static unsigned int steppy_step( struct machine *oric ) return oric->cpu.icycles; } -static SDL_bool clickzone( struct textzone *tz_, int *tx, int *ty, SDL_bool *dblclk ) +static SDL_bool clickzone(struct textzone *tz_, int* tx, int* ty, SDL_bool *dblclk) { int dx, dy; - if( !in_textzone( tz_, leftclick[0].x, leftclick[0].y ) ) + if(!in_textzone(tz_, leftclick[0].x, leftclick[0].y)) return SDL_FALSE; *tx = (leftclick[0].x - tz_->x) / 8; @@ -4000,31 +4481,34 @@ static SDL_bool clickzone( struct textzone *tz_, int *tx, int *ty, SDL_bool *dbl dx = (leftclick[1].x - tz_->x) / 8; dy = (leftclick[1].y - tz_->y) / 12; - if( ( (*tx) == dx ) && ( (*ty) == dy ) && ( (leftclick[0].time-leftclick[1].time) < 1000 ) ) + if(((*tx) == dx) && ((*ty) == dy) && ((leftclick[0].time-leftclick[1].time) < 1000)) { *dblclk = SDL_TRUE; // Reset double click timing after a successful double click leftclick[0].time = -1; - } else { + } + else + { *dblclk = SDL_FALSE; } return SDL_TRUE; } -SDL_bool mon_event( SDL_Event *ev, struct machine *oric, SDL_bool *needrender ) +SDL_bool mon_event(SDL_Event *ev, struct machine *oric, SDL_bool *needrender) { SDL_bool done; SDL_bool donkey; done = SDL_FALSE; donkey = SDL_FALSE; - switch( ev->type ) + switch(ev->type) { case SDL_COMPAT_ACTIVEEVENT: - if(SDL_COMPAT_IsAppFocused(ev)) { - *needrender = SDL_TRUE; + if(SDL_COMPAT_IsAppFocused(ev)) + { + *needrender = SDL_TRUE; } break; @@ -4038,15 +4522,15 @@ SDL_bool mon_event( SDL_Event *ev, struct machine *oric, SDL_bool *needrender ) leftclick[0].y = ev->button.y; leftclick[0].time = SDL_GetTicks(); - if( clickzone( tz[TZ_REGS], &tx, &ty, &dblclk ) ) + if(clickzone(tz[TZ_REGS], &tx, &ty, &dblclk)) { - mon_click_regs( oric, needrender, tx, ty, dblclk ); + mon_click_regs(oric, needrender, tx, ty, dblclk); } } break; case SDL_KEYUP: - switch( ev->key.keysym.sym ) + switch(ev->key.keysym.sym) { case SDLK_F9: oric->cpu.cycles = 0; @@ -4061,34 +4545,34 @@ SDL_bool mon_event( SDL_Event *ev, struct machine *oric, SDL_bool *needrender ) case SDLK_F1: refreshstatus = SDL_TRUE; *needrender = SDL_TRUE; - mon_store_state( oric ); - ula_set_dirty( oric ); - setemumode( oric, NULL, EM_MENU ); + mon_store_state(oric); + ula_set_dirty(oric); + setemumode(oric, NULL, EM_MENU); break; case SDLK_F2: // In case we're on a breakpoint - m6502_set_icycles( &oric->cpu, SDL_FALSE, mon_bpmsg ); - tape_patches( oric ); - via_clock( &oric->via, oric->cpu.icycles ); - ay_ticktock( &oric->ay, oric->cpu.icycles ); - if((oric->drivetype == DRV_MICRODISC) || (oric->drivetype == DRV_JASMIN)) wd17xx_ticktock( &oric->wddisk, oric->cpu.icycles ); - if( oric->type == MACH_TELESTRAT ) + m6502_set_icycles(&oric->cpu, SDL_FALSE, mon_bpmsg); + tape_patches(oric); + via_clock(&oric->via, oric->cpu.icycles); + ay_ticktock(&oric->ay, oric->cpu.icycles); + if((oric->drivetype == DRV_MICRODISC) || (oric->drivetype == DRV_JASMIN)) wd17xx_ticktock(&oric->wddisk, oric->cpu.icycles); + if(oric->type == MACH_TELESTRAT) { - via_clock( &oric->tele_via, oric->cpu.icycles ); + via_clock(&oric->tele_via, oric->cpu.icycles); } - if( oric->aciabackend ) - acia_clock( &oric->tele_acia, oric->cpu.icycles ); + if(oric->aciabackend) + acia_clock(&oric->tele_acia, oric->cpu.icycles); oric->cpu.rastercycles -= oric->cpu.icycles; - m6502_inst( &oric->cpu ); - if( oric->cpu.rastercycles <= 0 ) + m6502_inst(&oric->cpu); + if(oric->cpu.rastercycles <= 0) { - ula_doraster( oric ); + ula_doraster(oric); oric->cpu.rastercycles += oric->cyclesperraster; } *needrender = SDL_TRUE; - mon_store_state( oric ); - setemumode( oric, NULL, EM_RUNNING ); + mon_store_state(oric); + setemumode(oric, NULL, EM_RUNNING); break; case SDLK_F3: @@ -4098,9 +4582,11 @@ SDL_bool mon_event( SDL_Event *ev, struct machine *oric, SDL_bool *needrender ) case SDLK_F4: mshow = (mshow+1)%MSHOW_LAST; - if( ( mshow == MSHOW_VIA2 ) && ( oric->type != MACH_TELESTRAT ) ) + if((mshow == MSHOW_VIA2) && (oric->type != MACH_TELESTRAT)) + mshow = (mshow+1)%MSHOW_LAST; + if((oric->drivetype == DRV_NONE) && (mshow == MSHOW_DISK)) mshow = (mshow+1)%MSHOW_LAST; - if( ( oric->drivetype == DRV_NONE ) && ( mshow == MSHOW_DISK ) ) + if((oric->twilighteboard_activated == SDL_FALSE) && (mshow == MSHOW_TWIL)) mshow = (mshow+1)%MSHOW_LAST; *needrender = SDL_TRUE; break; @@ -4111,7 +4597,7 @@ SDL_bool mon_event( SDL_Event *ev, struct machine *oric, SDL_bool *needrender ) break; case SDL_KEYDOWN: - switch( ev->key.keysym.sym ) + switch(ev->key.keysym.sym) { case SDLK_LSHIFT: case SDLK_RSHIFT: @@ -4120,41 +4606,41 @@ SDL_bool mon_event( SDL_Event *ev, struct machine *oric, SDL_bool *needrender ) break; case SDLK_F10: - if( !kshifted ) + if(!kshifted) { - mon_store_state( oric ); - steppy_step( oric ); + mon_store_state(oric); + steppy_step(oric); *needrender = SDL_TRUE; donkey = SDL_TRUE; break; } case SDLK_F11: - if( mon_read( oric, oric->cpu.pc ) == 0x20 ) // JSR instruction? + if(mon_read(oric, oric->cpu.pc) == 0x20) // JSR instruction? { Uint16 newpc; unsigned int endticks; newpc = oric->cpu.pc+3; - mon_store_state( oric ); + mon_store_state(oric); endticks = SDL_GetTicks()+5000; // 5 seconds to comply - while( ( oric->cpu.pc != newpc ) && ( SDL_GetTicks() < endticks ) ) - steppy_step( oric ); + while((oric->cpu.pc != newpc) && (SDL_GetTicks() < endticks)) + steppy_step(oric); *needrender = SDL_TRUE; donkey = SDL_TRUE; break; } - mon_store_state( oric ); - steppy_step( oric ); + mon_store_state(oric); + steppy_step(oric); *needrender = SDL_TRUE; donkey = SDL_TRUE; break; case SDLK_F12: - switch( distab[mon_read( oric, oric->cpu.pc )].amode ) + switch(distab[mon_read(oric, oric->cpu.pc)].amode) { case AM_IMM: case AM_ZP: @@ -4186,16 +4672,16 @@ SDL_bool mon_event( SDL_Event *ev, struct machine *oric, SDL_bool *needrender ) break; } - if( !donkey ) + if(!donkey) { - switch( cshow ) + switch(cshow) { case CSHOW_CONSOLE: - done |= mon_console_keydown( ev, oric, needrender ); + done |= mon_console_keydown(ev, oric, needrender); break; case CSHOW_MWATCH: - done |= mon_mwatch_keydown( ev, oric, needrender ); + done |= mon_mwatch_keydown(ev, oric, needrender); break; } } @@ -4213,12 +4699,12 @@ void mon_traceinst(struct m6502 *cpu) { struct machine *oric = (struct machine *)cpu->userdata; - if (!list_start) + if(!list_start) { int i; list_start = &cputrace[0]; list_end = &cputrace[DEBUG_CPU_TRACE-1]; - for (i=0; inext; @@ -4248,38 +4734,38 @@ void mon_traceinst(struct m6502 *cpu) next->inst[1] = mon_read(oric, cpu->calcpc+1); next->inst[2] = mon_read(oric, cpu->calcpc+2); next->romdis = oric->romdis; - if( ( oric->drivetype == DRV_JASMIN ) && ( oric->jasmin.olay ) ) + if((oric->drivetype == DRV_JASMIN) && (oric->jasmin.olay)) next->romdis = SDL_FALSE; next = next->next; } -char *cputrace_print( struct machine *oric, struct cpu_trace_entry *cte ) +char* cputrace_print(struct machine *oric, struct cpu_trace_entry *cte) { unsigned short iaddr, addr; unsigned char op, a1, a2; int i; - char *tmpsname, *disptr; + char* tmpsname, *disptr; char sname[SNAME_LEN+1]; struct msym *csym; disptr = distmp; tmpsname = ""; - csym = mon_find_sym_by_addr( oric, cte->pc, &cte->romdis ); - if( csym ) + csym = mon_find_sym_by_addr(oric, cte->pc, &cte->romdis); + if(csym) { tmpsname = csym->name; - if( strlen( tmpsname ) > SNAME_LEN ) + if(strlen(tmpsname) > SNAME_LEN) { - sprintf( distmp, "%s\n", tmpsname ); + sprintf(distmp, "%s\n", tmpsname); disptr = &distmp[strlen(distmp)]; tmpsname = ""; } } - strcpy( sname, tmpsname ); - for( i=strlen(sname); iinst[0]; a1 = cte->inst[1]; a2 = cte->inst[2]; - switch( distab[op].amode ) + switch(distab[op].amode) { case AM_IMP: - sprintf( disptr, "%s %04X %02X %s", sname, iaddr, op, distab[op].name ); + sprintf(disptr, "%s %04X %02X %s", sname, iaddr, op, distab[op].name); break; case AM_IMM: - sprintf( disptr, "%s %04X %02X %02X %s #$%02X", sname, iaddr, op, a1, distab[op].name, a1 ); + sprintf(disptr, "%s %04X %02X %02X %s #$%02X", sname, iaddr, op, a1, distab[op].name, a1); break; case AM_ZP: case AM_ZPX: case AM_ZPY: - csym = mon_find_sym_by_addr( oric, a1, &cte->romdis ); - if( csym ) - sprintf( disptr, "%s %04X %02X %02X %s %s", sname, iaddr, op, a1, distab[op].name, csym->name ); + csym = mon_find_sym_by_addr(oric, a1, &cte->romdis); + if(csym) + sprintf(disptr, "%s %04X %02X %02X %s %s", sname, iaddr, op, a1, distab[op].name, csym->name); else - sprintf( disptr, "%s %04X %02X %02X %s $%02X", sname, iaddr, op, a1, distab[op].name, a1 ); - if( distab[op].amode == AM_ZP ) break; - strcat( disptr, distab[op].amode == AM_ZPX ? ",X" : ",Y" ); + sprintf(disptr, "%s %04X %02X %02X %s $%02X", sname, iaddr, op, a1, distab[op].name, a1); + if(distab[op].amode == AM_ZP) break; + strcat(disptr, distab[op].amode == AM_ZPX ? ",X" : ",Y"); break; case AM_ABS: case AM_ABX: case AM_ABY: - csym = mon_find_sym_by_addr( oric, (a2<<8)|a1, &cte->romdis ); - if( csym ) - sprintf( disptr, "%s %04X %02X %02X %02X %s %s", sname, iaddr, op, a1, a2, distab[op].name, csym->name ); + csym = mon_find_sym_by_addr(oric, (a2<<8)|a1, &cte->romdis); + if(csym) + sprintf(disptr, "%s %04X %02X %02X %02X %s %s", sname, iaddr, op, a1, a2, distab[op].name, csym->name); else - sprintf( disptr, "%s %04X %02X %02X %02X %s $%02X%02X", sname, iaddr, op, a1, a2, distab[op].name, a2, a1 ); - if( distab[op].amode == AM_ABS ) break; - strcat( disptr, distab[op].amode == AM_ABX ? ",X" : ",Y" ); + sprintf(disptr, "%s %04X %02X %02X %02X %s $%02X%02X", sname, iaddr, op, a1, a2, distab[op].name, a2, a1); + if(distab[op].amode == AM_ABS) break; + strcat(disptr, distab[op].amode == AM_ABX ? ",X" : ",Y"); break; case AM_ZIX: - csym = mon_find_sym_by_addr( oric, a1, &cte->romdis ); - if( csym ) - sprintf( disptr, "%s %04X %02X %02X %s (%s,X)", sname, iaddr, op, a1, distab[op].name, csym->name ); + csym = mon_find_sym_by_addr(oric, a1, &cte->romdis); + if(csym) + sprintf(disptr, "%s %04X %02X %02X %s (%s,X)", sname, iaddr, op, a1, distab[op].name, csym->name); else - sprintf( disptr, "%s %04X %02X %02X %s ($%02X,X)", sname, iaddr, op, a1, distab[op].name, a1 ); + sprintf(disptr, "%s %04X %02X %02X %s ($%02X,X)", sname, iaddr, op, a1, distab[op].name, a1); break; case AM_ZIY: - csym = mon_find_sym_by_addr( oric, a1, &cte->romdis ); - if( csym ) - sprintf( disptr, "%s %04X %02X %02X %s (%s),Y", sname, iaddr, op, a1, distab[op].name, csym->name ); + csym = mon_find_sym_by_addr(oric, a1, &cte->romdis); + if(csym) + sprintf(disptr, "%s %04X %02X %02X %s (%s),Y", sname, iaddr, op, a1, distab[op].name, csym->name); else - sprintf( disptr, "%s %04X %02X %02X %s ($%02X),Y", sname, iaddr, op, a1, distab[op].name, a1 ); + sprintf(disptr, "%s %04X %02X %02X %s ($%02X),Y", sname, iaddr, op, a1, distab[op].name, a1); break; case AM_REL: addr = ((cte->pc+2)+((signed char)a1))&0xffff; - csym = mon_find_sym_by_addr( oric, addr, &cte->romdis ); - if( csym ) - sprintf( disptr, "%s %04X %02X %02X %s %s", sname, iaddr, op, a1, distab[op].name, csym->name ); + csym = mon_find_sym_by_addr(oric, addr, &cte->romdis); + if(csym) + sprintf(disptr, "%s %04X %02X %02X %s %s", sname, iaddr, op, a1, distab[op].name, csym->name); else - sprintf( disptr, "%s %04X %02X %02X %s $%04X", sname, iaddr, op, a1, distab[op].name, addr ); + sprintf(disptr, "%s %04X %02X %02X %s $%04X", sname, iaddr, op, a1, distab[op].name, addr); break; case AM_IND: - csym = mon_find_sym_by_addr( oric, (a2<<8)|a1, &cte->romdis ); - if( csym ) - sprintf( disptr, "%s %04X %02X %02X %02X %s (%s)", sname, iaddr, op, a1, a2, distab[op].name, csym->name ); + csym = mon_find_sym_by_addr(oric, (a2<<8)|a1, &cte->romdis); + if(csym) + sprintf(disptr, "%s %04X %02X %02X %02X %s (%s)", sname, iaddr, op, a1, a2, distab[op].name, csym->name); else - sprintf( disptr, "%s %04X %02X %02X %02X %s ($%02X%02X)", sname, iaddr, op, a1, a2, distab[op].name, a2, a1 ); + sprintf(disptr, "%s %04X %02X %02X %02X %s ($%02X%02X)", sname, iaddr, op, a1, a2, distab[op].name, a2, a1); break; default: - strcpy( disptr, " WTF?" ); + strcpy(disptr, " WTF?"); break; } - for( i=strlen(disptr); i<60; i++ ) + for(i=strlen(disptr); i<60; i++) disptr[i] = 32; disptr[i] = 0; sprintf(&disptr[60], "%c%c-%c%c%c%c%c A=%02X X=%02X Y=%02X SP=%04X ROMDIS=%d", - (cte->flags&0x80) ? 'N' : '-', - (cte->flags&0x40) ? 'V' : '-', - (cte->flags&0x10) ? 'B' : '-', - (cte->flags&0x08) ? 'D' : '-', - (cte->flags&0x04) ? 'I' : '-', - (cte->flags&0x02) ? 'Z' : '-', - (cte->flags&0x01) ? 'C' : '-', - cte->a, - cte->x, - cte->y, - cte->sp+0x100, - cte->romdis); + (cte->flags&0x80) ? 'N' : '-', + (cte->flags&0x40) ? 'V' : '-', + (cte->flags&0x10) ? 'B' : '-', + (cte->flags&0x08) ? 'D' : '-', + (cte->flags&0x04) ? 'I' : '-', + (cte->flags&0x02) ? 'Z' : '-', + (cte->flags&0x01) ? 'C' : '-', + cte->a, + cte->x, + cte->y, + cte->sp+0x100, + cte->romdis); return distmp; } @@ -4384,10 +4870,12 @@ void dump_cputrace(struct machine *oric) { struct cpu_trace_entry *iter = list_start; - while (iter != next) + while(iter != next) { printf("%s\n", cputrace_print(oric, iter)); iter = iter->next; } } #endif + +#endif diff --git a/monitor.h b/monitor.h index 78c96297..5788ccd9 100644 --- a/monitor.h +++ b/monitor.h @@ -48,6 +48,8 @@ #define SYMF_TELEBANK7 (1< 0 struct cpu_trace_entry diff --git a/msgbox.h b/msgbox.h index e7ea6d3e..63000da5 100644 --- a/msgbox.h +++ b/msgbox.h @@ -26,7 +26,7 @@ enum MSGBOX_OK }; -SDL_bool init_msgbox( struct machine *oric ); -void shut_msgbox( struct machine *oric ); -SDL_bool msgbox( struct machine *oric, int type, char *msg ); +SDL_bool init_msgbox(struct machine *oric); +void shut_msgbox(struct machine *oric); +SDL_bool msgbox(struct machine *oric, int type, char* msg); diff --git a/msgbox_beos.cpp b/msgbox_beos.cpp index a6a8e392..b4852480 100644 --- a/msgbox_beos.cpp +++ b/msgbox_beos.cpp @@ -40,27 +40,27 @@ extern "C" { #include "msgbox.h" } -SDL_bool init_msgbox( struct machine *oric ) +SDL_bool init_msgbox(struct machine *oric) { return SDL_TRUE; } -void shut_msgbox( struct machine *oric ) +void shut_msgbox(struct machine *oric) { } -SDL_bool msgbox( struct machine *oric, int type, char *msg ) +SDL_bool msgbox(struct machine *oric, int type, char* msg) { - switch( type ) + switch(type) { case MSGBOX_YES_NO: return ((new BAlert("Oricutron Request", msg, "Yes", "No"))->Go() == 0) ? SDL_TRUE : SDL_FALSE; -// return (MessageBoxA( hwnd, msg, "Oriculator Request", MB_YESNO ) == IDYES); + // return (MessageBoxA( hwnd, msg, "Oriculator Request", MB_YESNO ) == IDYES); case MSGBOX_OK_CANCEL: return ((new BAlert("Oricutron Request", msg, "Ok", "Cancel"))->Go() == 0) ? SDL_TRUE : SDL_FALSE; -// return (MessageBoxA( hwnd, msg, "Oriculator Request", MB_OKCANCEL ) == IDOK); - + // return (MessageBoxA( hwnd, msg, "Oriculator Request", MB_OKCANCEL ) == IDOK); + case MSGBOX_OK: (new BAlert("Oricutron Request", msg, "Ok"))->Go(); return SDL_TRUE; diff --git a/msgbox_gtk.c b/msgbox_gtk.c index 2597fd0a..db9a2b80 100644 --- a/msgbox_gtk.c +++ b/msgbox_gtk.c @@ -40,19 +40,19 @@ #include "msgbox.h" extern SDL_bool fullscreen; -void togglefullscreen( struct machine *oric, struct osdmenuitem *mitem, int dummy ); +void togglefullscreen(struct machine *oric, struct osdmenuitem *mitem, int dummy); -SDL_bool init_msgbox( struct machine *oric ) +SDL_bool init_msgbox(struct machine *oric) { // We rely on init_filerequester to call gtk_init() return SDL_TRUE; } -void shut_msgbox( struct machine *oric ) +void shut_msgbox(struct machine *oric) { } -SDL_bool msgbox( struct machine *oric, int type, char *msg ) +SDL_bool msgbox(struct machine *oric, int type, char* msg) { GtkWidget *dialog = NULL; GtkButtonsType btns = GTK_BUTTONS_OK; @@ -61,10 +61,10 @@ SDL_bool msgbox( struct machine *oric, int type, char *msg ) gint res; SDL_bool was_fullscreen = fullscreen; - if (fullscreen) + if(fullscreen) togglefullscreen(oric, NULL, 0); - switch( type ) + switch(type) { case MSGBOX_YES_NO: btns = GTK_BUTTONS_YES_NO; @@ -80,15 +80,15 @@ SDL_bool msgbox( struct machine *oric, int type, char *msg ) } dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL, mtyp, btns, "%s", msg); - res = gtk_dialog_run(GTK_DIALOG (dialog)); - if ((res == GTK_RESPONSE_OK) || (res == GTK_RESPONSE_YES) || (res == GTK_RESPONSE_ACCEPT)) + res = gtk_dialog_run(GTK_DIALOG(dialog)); + if((res == GTK_RESPONSE_OK) || (res == GTK_RESPONSE_YES) || (res == GTK_RESPONSE_ACCEPT)) result = SDL_TRUE; - + gtk_widget_destroy(dialog); - while (gtk_events_pending()) + while(gtk_events_pending()) gtk_main_iteration(); - if (was_fullscreen) + if(was_fullscreen) togglefullscreen(oric, NULL, 0); return result; diff --git a/msgbox_os2.c b/msgbox_os2.c index 7d3a949c..9f880fea 100644 --- a/msgbox_os2.c +++ b/msgbox_os2.c @@ -25,28 +25,28 @@ #include "via.h" #include "msgbox.h" -SDL_bool init_msgbox( struct machine *oric ) +SDL_bool init_msgbox(struct machine *oric) { return SDL_TRUE; } -void shut_msgbox( struct machine *oric ) +void shut_msgbox(struct machine *oric) { } -SDL_bool msgbox( struct machine *oric, int type, char *msg ) +SDL_bool msgbox(struct machine *oric, int type, char* msg) { - char *btns = "OK|Cancel"; + char* btns = "OK|Cancel"; struct EasyStruct myES = - { + { sizeof(struct EasyStruct), - 0, - (UBYTE *) "Oricutron Request", - (UBYTE *) msg, - (UBYTE *) btns, + 0, + (UBYTE *) "Oricutron Request", + (UBYTE *) msg, + (UBYTE *) btns, }; - switch( type ) + switch(type) { case MSGBOX_YES_NO: strcpy(btns, "Yes|No"); diff --git a/msgbox_os4.c b/msgbox_os4.c index 17a21470..ca8e2587 100644 --- a/msgbox_os4.c +++ b/msgbox_os4.c @@ -49,54 +49,54 @@ struct Library *RequesterBase = NULL; struct IntuitionIFace *IIntuition = NULL; struct RequesterIFace *IRequester = NULL; -SDL_bool init_msgbox( struct machine *oric ) +SDL_bool init_msgbox(struct machine *oric) { - IntuitionBase = IExec->OpenLibrary( "intuition.library", 51 ); - if( !IntuitionBase ) + IntuitionBase = IExec->OpenLibrary("intuition.library", 51); + if(!IntuitionBase) { - printf( "Unable to open intuition.library v51+\n" ); + printf("Unable to open intuition.library v51+\n"); return SDL_FALSE; } - IIntuition = (struct IntuitionIFace *)IExec->GetInterface( IntuitionBase, "main", 1, NULL ); - if( !IIntuition ) + IIntuition = (struct IntuitionIFace *)IExec->GetInterface(IntuitionBase, "main", 1, NULL); + if(!IIntuition) { - printf( "Unable to obtain main interface for intuition.library\n" ); + printf("Unable to obtain main interface for intuition.library\n"); return SDL_FALSE; } - RequesterBase = IExec->OpenLibrary( "requester.class", 51 ); - if( !RequesterBase ) + RequesterBase = IExec->OpenLibrary("requester.class", 51); + if(!RequesterBase) { - printf( "Unable to open requester.class v51+\n" ); + printf("Unable to open requester.class v51+\n"); return SDL_FALSE; } - IRequester = (struct RequesterIFace *)IExec->GetInterface( RequesterBase, "main", 1, NULL ); - if( !IRequester ) + IRequester = (struct RequesterIFace *)IExec->GetInterface(RequesterBase, "main", 1, NULL); + if(!IRequester) { - printf( "Unable to obtain main interface for requester.library\n" ); + printf("Unable to obtain main interface for requester.library\n"); return SDL_FALSE; } return SDL_TRUE; } -void shut_msgbox( struct machine *oric ) +void shut_msgbox(struct machine *oric) { - if( IRequester ) IExec->DropInterface( (struct Interface *)IRequester ); - if( RequesterBase ) IExec->CloseLibrary( RequesterBase ); - if( IIntuition ) IExec->DropInterface( (struct Interface *)IIntuition ); - if( IntuitionBase ) IExec->CloseLibrary( IntuitionBase ); + if(IRequester) IExec->DropInterface((struct Interface *)IRequester); + if(RequesterBase) IExec->CloseLibrary(RequesterBase); + if(IIntuition) IExec->DropInterface((struct Interface *)IIntuition); + if(IntuitionBase) IExec->CloseLibrary(IntuitionBase); } -SDL_bool msgbox( struct machine *oric, int type, char *msg ) +SDL_bool msgbox(struct machine *oric, int type, char* msg) { Object *req_obj; int32 result, imgtype=REQIMAGE_INFO; STRPTR btns = "huh?!"; - switch( type ) + switch(type) { case MSGBOX_YES_NO: btns = "Yes|No"; @@ -107,26 +107,26 @@ SDL_bool msgbox( struct machine *oric, int type, char *msg ) btns = "OK|Cancel"; imgtype = REQIMAGE_QUESTION; break; - + case MSGBOX_OK: btns = "OK"; imgtype = REQIMAGE_INFO; break; } - req_obj = (Object *)IIntuition->NewObject( IRequester->REQUESTER_GetClass(), NULL, - REQ_TitleText, "Oricutron Request", - REQ_BodyText, msg, - REQ_GadgetText, btns, - REQ_Image, imgtype, - TAG_DONE ); + req_obj = (Object *)IIntuition->NewObject(IRequester->REQUESTER_GetClass(), NULL, + REQ_TitleText, "Oricutron Request", + REQ_BodyText, msg, + REQ_GadgetText, btns, + REQ_Image, imgtype, + TAG_DONE); - if( !req_obj ) return SDL_TRUE; // Oh well + if(!req_obj) return SDL_TRUE; // Oh well - result = IIntuition->IDoMethod( req_obj, RM_OPENREQ, NULL, NULL, NULL ); - IIntuition->DisposeObject( req_obj ); + result = IIntuition->IDoMethod(req_obj, RM_OPENREQ, NULL, NULL, NULL); + IIntuition->DisposeObject(req_obj); - if( type == MSGBOX_OK ) return SDL_TRUE; + if(type == MSGBOX_OK) return SDL_TRUE; return result ? SDL_TRUE : SDL_FALSE; } diff --git a/msgbox_sdl.c b/msgbox_sdl.c index 75308a39..1748c21e 100644 --- a/msgbox_sdl.c +++ b/msgbox_sdl.c @@ -41,10 +41,14 @@ #include "machine.h" #include "msgbox.h" +#ifdef WWW +#include +#endif + struct msgboxbut { int x, y; - char *str; + char* str; }; extern SDL_Surface *screen; @@ -53,84 +57,89 @@ static struct msgboxbut *btns; static int cbtn; static struct msgboxbut ynbuts[] = { { 2, 5, " YES " }, - { 50, 5, " NO " }, - { -1,-1, NULL } }; + { 50, 5, " NO " }, + { -1, -1, NULL } +}; static struct msgboxbut ocbuts[] = { { 2, 5, " OK " }, - { 50, 5, " CANCEL " }, - { -1,-1, NULL } }; + { 50, 5, " CANCEL " }, + { -1, -1, NULL } +}; static struct msgboxbut obuts[] = { { 26, 5, " OK " }, - { -1,-1, NULL } }; + { -1, -1, NULL } +}; -SDL_bool init_msgbox( struct machine *oric ) +SDL_bool init_msgbox(struct machine *oric) { - if( !alloc_textzone( oric, TZ_MSGBOX, 80, 120, 60, 8, "Oricutron Request" ) ) return SDL_FALSE; + if(!alloc_textzone(oric, TZ_MSGBOX, 80, 120, 60, 8, "Oricutron Request")) return SDL_FALSE; return SDL_TRUE; } -void shut_msgbox( struct machine *oric ) +void shut_msgbox(struct machine *oric) { - free_textzone( oric, TZ_MSGBOX ); + free_textzone(oric, TZ_MSGBOX); } // Render the messagebox -static void msgbox_render( struct machine *oric ) +static void msgbox_render(struct machine *oric) { int i; - for( i=0; btns[i].x!=-1; i++ ) + for(i=0; btns[i].x!=-1; i++) { - if( i==cbtn ) + if(i==cbtn) { tz[TZ_MSGBOX]->cfc = 1; tz[TZ_MSGBOX]->cbc = 2; - } else { + } + else + { tz[TZ_MSGBOX]->cfc = 2; tz[TZ_MSGBOX]->cbc = 5; } - tzstrpos( tz[TZ_MSGBOX], btns[i].x, btns[i].y, btns[i].str ); + tzstrpos(tz[TZ_MSGBOX], btns[i].x, btns[i].y, btns[i].str); } - oric->render_begin( oric ); + oric->render_begin(oric); - oric->render_video( oric, SDL_TRUE ); - oric->render_textzone( oric, TZ_MSGBOX ); + oric->render_video(oric, SDL_TRUE); + oric->render_textzone(oric, TZ_MSGBOX); - oric->render_end( oric ); + oric->render_end(oric); } -static int msgbox_checkover( int x, int y ) +static int msgbox_checkover(int x, int y) { int i; - for( i=0; btns[i].x!=-1; i++ ) + for(i=0; btns[i].x!=-1; i++) { - if( ( y == btns[i].y ) && - ( x >= btns[i].x ) && - ( x < (btns[i].x+strlen(btns[i].str)) ) ) + if((y == btns[i].y) && + (x >= btns[i].x) && + (x < (btns[i].x+strlen(btns[i].str)))) return i; } return -1; } -SDL_bool msgbox( struct machine *oric, int type, char *msg ) +SDL_bool msgbox(struct machine *oric, int type, char* msg) { int i, j, k, mx, my, presson; int lines[] = { 2*60, 3*60, 5*60 }; - char *msg2; + char* msg2; SDL_Event event; SDL_bool wasunicode; - wasunicode = SDL_COMPAT_EnableUNICODE( SDL_TRUE ); - SDL_COMPAT_EnableKeyRepeat( SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL ); + wasunicode = SDL_COMPAT_EnableUNICODE(SDL_TRUE); + SDL_COMPAT_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL); // Clear any old message - for( i=1; i<59; i++ ) + for(i=1; i<59; i++) { - for( j=0; j<3; j++ ) + for(j=0; j<3; j++) { tz[TZ_MSGBOX]->fc[lines[j]+i] = 2; tz[TZ_MSGBOX]->bc[lines[j]+i] = 3; @@ -138,21 +147,21 @@ SDL_bool msgbox( struct machine *oric, int type, char *msg ) } } - for( i=0; msg[i]; i++ ) if( (msg[i]=='\r')||(msg[i]=='\n') ) break; + for(i=0; msg[i]; i++) if((msg[i]=='\r')||(msg[i]=='\n')) break; - for( j=0, k=30-i/2; jtx[lines[0]+k] = msg[j]; - while( (msg[i]=='\r')||(msg[i]=='\n') ) i++; - if( msg[i] ) + while((msg[i]=='\r')||(msg[i]=='\n')) i++; + if(msg[i]) { msg2 = &msg[i]; - i = strlen( msg2 ); - for( j=0, k=30-i/2; jtx[lines[1]+k] = msg2[j]; } - switch( type ) + switch(type) { case MSGBOX_YES_NO: btns = ynbuts; @@ -170,68 +179,77 @@ SDL_bool msgbox( struct machine *oric, int type, char *msg ) break; } - msgbox_render( oric ); + msgbox_render(oric); presson = -1; - for( ;; ) + for(;;) { - if( !SDL_WaitEvent( &event ) ) +#ifdef WWW + if(!SDL_PollEvent(&event)) + { + emscripten_sleep(10); + continue; + } +#else + if(!SDL_WaitEvent(&event)) break; +#endif - switch( event.type ) + switch(event.type) { case SDL_COMPAT_ACTIVEEVENT: - if(SDL_COMPAT_IsAppFocused( &event ) ) { - msgbox_render( oric ); + if(SDL_COMPAT_IsAppFocused(&event)) + { + msgbox_render(oric); } break; case SDL_MOUSEMOTION: - if( presson != -1 ) break; + if(presson != -1) break; mx = (event.motion.x - tz[TZ_MSGBOX]->x)/8; my = (event.motion.y - tz[TZ_MSGBOX]->y)/12; - i = msgbox_checkover( mx, my ); - if( i == -1 ) break; - if( i != cbtn ) + i = msgbox_checkover(mx, my); + if(i == -1) break; + if(i != cbtn) { cbtn = i; - msgbox_render( oric ); + msgbox_render(oric); } break; case SDL_MOUSEBUTTONDOWN: - if( event.button.button == SDL_BUTTON_LEFT ) + if(event.button.button == SDL_BUTTON_LEFT) { mx = (event.motion.x - tz[TZ_MSGBOX]->x)/8; my = (event.motion.y - tz[TZ_MSGBOX]->y)/12; - i = msgbox_checkover( mx, my ); - if( i == -1 ) break; + i = msgbox_checkover(mx, my); + if(i == -1) break; cbtn = i; presson = i; - msgbox_render( oric ); + msgbox_render(oric); } break; case SDL_MOUSEBUTTONUP: - if( event.button.button == SDL_BUTTON_LEFT ) + if(event.button.button == SDL_BUTTON_LEFT) { - if( presson == -1 ) break; + if(presson == -1) break; mx = (event.motion.x - tz[TZ_MSGBOX]->x)/8; my = (event.motion.y - tz[TZ_MSGBOX]->y)/12; - i = msgbox_checkover( mx, my ); - if( i == presson ) + i = msgbox_checkover(mx, my); + if(i == presson) { - switch( type ) + switch(type) { case MSGBOX_YES_NO: case MSGBOX_OK_CANCEL: - SDL_COMPAT_EnableUNICODE( wasunicode ); - SDL_COMPAT_EnableKeyRepeat( wasunicode ? SDL_DEFAULT_REPEAT_DELAY : 0, wasunicode ? SDL_DEFAULT_REPEAT_INTERVAL : 0 ); + SDL_COMPAT_EnableUNICODE(wasunicode); + SDL_COMPAT_EnableKeyRepeat(wasunicode ? SDL_DEFAULT_REPEAT_DELAY : 0, wasunicode ? SDL_DEFAULT_REPEAT_INTERVAL : 0); return (presson==0); default: - SDL_COMPAT_EnableUNICODE( wasunicode ); - SDL_COMPAT_EnableKeyRepeat( wasunicode ? SDL_DEFAULT_REPEAT_DELAY : 0, wasunicode ? SDL_DEFAULT_REPEAT_INTERVAL : 0 ); + SDL_COMPAT_EnableUNICODE(wasunicode); + SDL_COMPAT_EnableKeyRepeat(wasunicode ? SDL_DEFAULT_REPEAT_DELAY : 0, wasunicode ? SDL_DEFAULT_REPEAT_INTERVAL : 0); return SDL_TRUE; } break; @@ -242,38 +260,38 @@ SDL_bool msgbox( struct machine *oric, int type, char *msg ) break; case SDL_KEYDOWN: - switch( event.key.keysym.sym ) + switch(event.key.keysym.sym) { case SDLK_TAB: case SDLK_RIGHT: cbtn = cbtn+1; - if( btns[cbtn].x == -1 ) cbtn = 0; - msgbox_render( oric ); + if(btns[cbtn].x == -1) cbtn = 0; + msgbox_render(oric); break; case SDLK_LEFT: cbtn--; - if( cbtn < 0 ) + if(cbtn < 0) { - for( cbtn=0; btns[cbtn].x!=-1; cbtn++ ) ; + for(cbtn=0; btns[cbtn].x!=-1; cbtn++) ; cbtn--; } - msgbox_render( oric ); + msgbox_render(oric); break; case SDLK_RETURN: case SDLK_KP_ENTER: - switch( type ) + switch(type) { case MSGBOX_YES_NO: case MSGBOX_OK_CANCEL: - SDL_COMPAT_EnableUNICODE( wasunicode ); - SDL_COMPAT_EnableKeyRepeat( wasunicode ? SDL_DEFAULT_REPEAT_DELAY : 0, wasunicode ? SDL_DEFAULT_REPEAT_INTERVAL : 0 ); + SDL_COMPAT_EnableUNICODE(wasunicode); + SDL_COMPAT_EnableKeyRepeat(wasunicode ? SDL_DEFAULT_REPEAT_DELAY : 0, wasunicode ? SDL_DEFAULT_REPEAT_INTERVAL : 0); return (cbtn==0); default: - SDL_COMPAT_EnableUNICODE( wasunicode ); - SDL_COMPAT_EnableKeyRepeat( wasunicode ? SDL_DEFAULT_REPEAT_DELAY : 0, wasunicode ? SDL_DEFAULT_REPEAT_INTERVAL : 0 ); + SDL_COMPAT_EnableUNICODE(wasunicode); + SDL_COMPAT_EnableKeyRepeat(wasunicode ? SDL_DEFAULT_REPEAT_DELAY : 0, wasunicode ? SDL_DEFAULT_REPEAT_INTERVAL : 0); return SDL_TRUE; } break; @@ -285,7 +303,7 @@ SDL_bool msgbox( struct machine *oric, int type, char *msg ) } } - SDL_COMPAT_EnableUNICODE( wasunicode ); - SDL_COMPAT_EnableKeyRepeat( wasunicode ? SDL_DEFAULT_REPEAT_DELAY : 0, wasunicode ? SDL_DEFAULT_REPEAT_INTERVAL : 0 ); + SDL_COMPAT_EnableUNICODE(wasunicode); + SDL_COMPAT_EnableKeyRepeat(wasunicode ? SDL_DEFAULT_REPEAT_DELAY : 0, wasunicode ? SDL_DEFAULT_REPEAT_INTERVAL : 0); return SDL_FALSE; } diff --git a/msgbox_win32.c b/msgbox_win32.c index 9c0dae78..685fabd5 100644 --- a/msgbox_win32.c +++ b/msgbox_win32.c @@ -38,38 +38,38 @@ #include "machine.h" #include "msgbox.h" -SDL_bool init_msgbox( struct machine *oric ) +SDL_bool init_msgbox(struct machine *oric) { return SDL_TRUE; } -void shut_msgbox( struct machine *oric ) +void shut_msgbox(struct machine *oric) { } -SDL_bool msgbox( struct machine *oric, int type, char *msg ) +SDL_bool msgbox(struct machine *oric, int type, char* msg) { SDL_SysWMinfo wmi; HWND hwnd; hwnd = NULL; SDL_VERSION(&wmi.version); - if(SDL_COMPAT_GetWMInfo( &wmi ) ) + if(SDL_COMPAT_GetWMInfo(&wmi)) #if SDL_MAJOR_VERSION == 1 hwnd = (HWND)wmi.window; #else hwnd = (HWND)wmi.info.win.window; #endif - switch( type ) + switch(type) { case MSGBOX_YES_NO: - return (MessageBoxA( hwnd, msg, "Oricutron Request", MB_YESNO ) == IDYES); + return (MessageBoxA(hwnd, msg, "Oricutron Request", MB_YESNO) == IDYES); case MSGBOX_OK_CANCEL: - return (MessageBoxA( hwnd, msg, "Oricutron Request", MB_OKCANCEL ) == IDOK); - + return (MessageBoxA(hwnd, msg, "Oricutron Request", MB_OKCANCEL) == IDOK); + case MSGBOX_OK: - MessageBoxA( hwnd, msg, "Oricutron Request", MB_OK ); + MessageBoxA(hwnd, msg, "Oricutron Request", MB_OK); } return SDL_TRUE; diff --git a/msvc/Oricutron.rc b/msvc/Oricutron.rc new file mode 100644 index 00000000..1f35c63a --- /dev/null +++ b/msvc/Oricutron.rc @@ -0,0 +1,51 @@ +#include +# define ORICUTRON_VERSION_MAJOR 1 +# define ORICUTRON_VERSION_MINOR 2 +# define ORICUTRON_VERSION_PATCH 0 +# define ORICUTRON_VERSION_NUMBER "1.2.0\0" +# define ORICUTRON_COPYRIGHT "Oricutron 1.2.0 (c)2015 Peter Gordon (pete@gordon.plus)\0" +# define ORICUTRON_APPNAME "Oricutron\0" +# define ORICUTRON_EXE "Oricutron.exe\0" +# define ORICUTRON_COMPANYNAME "pete-gordon/oricutron\0" +# define ORICUTRON_LINK "https://github.com/pete-gordon/oricutron/\0" + +101 ICON "..\winicon.ico" + +#ifdef GCC_WINDRES +VS_VERSION_INFO VERSIONINFO +#else +VS_VERSION_INFO VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE +#endif + FILEVERSION ORICUTRON_VERSION_MAJOR,ORICUTRON_VERSION_MINOR,ORICUTRON_VERSION_PATCH,0 + PRODUCTVERSION ORICUTRON_VERSION_MAJOR,ORICUTRON_VERSION_MINOR,ORICUTRON_VERSION_PATCH,0 + FILEFLAGSMASK VS_FFI_FILEFLAGSMASK +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS VOS_NT_WINDOWS32 + FILETYPE VFT_APP + FILESUBTYPE VFT2_UNKNOWN +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904E4" + //language ID = U.S. English, char set = Windows, Multilingual + BEGIN + VALUE "CompanyName", ORICUTRON_COMPANYNAME + VALUE "FileDescription", ORICUTRON_EXE + VALUE "FileVersion", ORICUTRON_VERSION_NUMBER + VALUE "InternalName", ORICUTRON_EXE + VALUE "LegalCopyright", ORICUTRON_COPYRIGHT + VALUE "OriginalFilename", ORICUTRON_EXE + VALUE "ProductName", ORICUTRON_APPNAME + VALUE "ProductVersion", ORICUTRON_VERSION_NUMBER + VALUE "Comments", ORICUTRON_LINK + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0409, 1252 + END +END diff --git a/msvc/VS2017/Oricutron.sln b/msvc/VS2017/Oricutron.sln index 40760682..706636cc 100644 --- a/msvc/VS2017/Oricutron.sln +++ b/msvc/VS2017/Oricutron.sln @@ -1,4 +1,4 @@ - + Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 VisualStudioVersion = 15.0.27428.1 diff --git a/msvc/VS2017/Oricutron.vcxproj b/msvc/VS2017/Oricutron.vcxproj index 1f8535f9..dea6e3d6 100644 --- a/msvc/VS2017/Oricutron.vcxproj +++ b/msvc/VS2017/Oricutron.vcxproj @@ -1,4 +1,4 @@ - + @@ -79,7 +79,7 @@ if "$(Configuration.Contains('Release'))"=="True" ( if "$(Platform)"=="x64" ( co Disabled true ..\vcpkg\installed\x64-windows\include\SDL2\ - SDL_MAIN_HANDLED=1;__OPENGL_AVAILABLE__;_MBCS;WIN32;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;__CBCOPY__;__CBPASTE__;APP_NAME_FULL="Oricutron 1.2";APP_YEAR="2015";VERSION_COPYRIGHTS="Oricutron 1.2.0 (c)2015 Peter Gordon (pete@petergordon.org.uk)";%(PreprocessorDefinitions) + SDL_MAIN_HANDLED=1;__OPENGL_AVAILABLE__;_MBCS;WIN32;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;__CBCOPY__;__CBPASTE__;APP_NAME_FULL="Oricutron 1.2";APP_YEAR="2015";VERSION_COPYRIGHTS="Oricutron 1.2.0 (c)2015 Peter Gordon (pete@gordon.plus)";%(PreprocessorDefinitions) /we4013 /we4115 %(AdditionalOptions) @@ -101,7 +101,7 @@ if "$(Configuration.Contains('Release'))"=="True" ( if "$(Platform)"=="x64" ( co true true ..\vcpkg\installed\x64-windows\include\SDL2\ - SDL_MAIN_HANDLED=1;__OPENGL_AVAILABLE__;_MBCS;WIN32;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;__CBCOPY__;__CBPASTE__;APP_NAME_FULL="Oricutron 1.2";APP_YEAR="2015";VERSION_COPYRIGHTS="Oricutron 1.2.0 (c)2015 Peter Gordon (pete@petergordon.org.uk)";%(PreprocessorDefinitions) + SDL_MAIN_HANDLED=1;__OPENGL_AVAILABLE__;_MBCS;WIN32;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;__CBCOPY__;__CBPASTE__;APP_NAME_FULL="Oricutron 1.2";APP_YEAR="2015";VERSION_COPYRIGHTS="Oricutron 1.2.0 (c)2015 Peter Gordon (pete@gordon.plus)";%(PreprocessorDefinitions) AnySuitable Speed true diff --git a/msvc/VS2017/Oricutron.vcxproj.filters b/msvc/VS2017/Oricutron.vcxproj.filters index ea61e66c..e5118e12 100644 --- a/msvc/VS2017/Oricutron.vcxproj.filters +++ b/msvc/VS2017/Oricutron.vcxproj.filters @@ -1,4 +1,4 @@ - + diff --git a/msvc/VS2019/Oricutron.sln b/msvc/VS2019/Oricutron.sln index 538efe11..5c937bc0 100644 --- a/msvc/VS2019/Oricutron.sln +++ b/msvc/VS2019/Oricutron.sln @@ -1,4 +1,4 @@ - + Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 VisualStudioVersion = 16.0.29411.138 diff --git a/msvc/VS2019/Oricutron.vcxproj b/msvc/VS2019/Oricutron.vcxproj index b2e004ac..28f2be00 100644 --- a/msvc/VS2019/Oricutron.vcxproj +++ b/msvc/VS2019/Oricutron.vcxproj @@ -1,4 +1,4 @@ - + @@ -101,7 +101,7 @@ if "$(Configuration.Contains('Release'))"=="True" ( copy "..\vcpkg\installed\x64 Disabled true .;..\vcpkg\installed\x64-windows\include\SDL2\ - SDL_MAIN_HANDLED=1;__OPENGL_AVAILABLE__;_MBCS;WIN32;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;__CBCOPY__;__CBPASTE__;APP_NAME_FULL="Oricutron 1.2";APP_YEAR="2015";VERSION_COPYRIGHTS="Oricutron 1.2.0 (c)2015 Peter Gordon (pete@petergordon.org.uk)";%(PreprocessorDefinitions) + SDL_MAIN_HANDLED=1;__OPENGL_AVAILABLE__;_MBCS;WIN32;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;__CBCOPY__;__CBPASTE__;APP_NAME_FULL="Oricutron 1.2";APP_YEAR="2015";VERSION_COPYRIGHTS="Oricutron 1.2.0 (c)2015 Peter Gordon (pete@gordon.plus)";%(PreprocessorDefinitions) /we4013 /we4115 /wd4100 /wd4244 /wd4152 /wd4706 /wd4018 /wd4267 /wd4389 /wd4245 %(AdditionalOptions) @@ -121,7 +121,7 @@ if "$(Configuration.Contains('Release'))"=="True" ( copy "..\vcpkg\installed\x64 Disabled true .;..\vcpkg\installed\x64-windows\include\ - SDL_LIB=1;SDL_MAIN_HANDLED=1;__OPENGL_AVAILABLE__;_MBCS;WIN32;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;__CBCOPY__;__CBPASTE__;APP_NAME_FULL="Oricutron 1.2";APP_YEAR="2015";VERSION_COPYRIGHTS="Oricutron 1.2.0 (c)2015 Peter Gordon (pete@petergordon.org.uk)";%(PreprocessorDefinitions) + SDL_LIB=1;SDL_MAIN_HANDLED=1;__OPENGL_AVAILABLE__;_MBCS;WIN32;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;__CBCOPY__;__CBPASTE__;APP_NAME_FULL="Oricutron 1.2";APP_YEAR="2015";VERSION_COPYRIGHTS="Oricutron 1.2.0 (c)2015 Peter Gordon (pete@gordon.plus)";%(PreprocessorDefinitions) /we4013 /we4115 /wd4100 /wd4244 /wd4152 /wd4706 /wd4018 /wd4267 /wd4389 /wd4245 %(AdditionalOptions) @@ -143,7 +143,7 @@ if "$(Configuration.Contains('Release'))"=="True" ( copy "..\vcpkg\installed\x64 true true .;..\vcpkg\installed\x64-windows\include\SDL2\ - SDL_MAIN_HANDLED=1;__OPENGL_AVAILABLE__;_MBCS;WIN32;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;__CBCOPY__;__CBPASTE__;APP_NAME_FULL="Oricutron 1.2";APP_YEAR="2015";VERSION_COPYRIGHTS="Oricutron 1.2.0 (c)2015 Peter Gordon (pete@petergordon.org.uk)";%(PreprocessorDefinitions) + SDL_MAIN_HANDLED=1;__OPENGL_AVAILABLE__;_MBCS;WIN32;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;__CBCOPY__;__CBPASTE__;APP_NAME_FULL="Oricutron 1.2";APP_YEAR="2015";VERSION_COPYRIGHTS="Oricutron 1.2.0 (c)2015 Peter Gordon (pete@gordon.plus)";%(PreprocessorDefinitions) AnySuitable Speed true @@ -171,7 +171,7 @@ if "$(Configuration.Contains('Release'))"=="True" ( copy "..\vcpkg\installed\x64 true true .;..\vcpkg\installed\x64-windows\include\ - SDL_LIB=1;SDL_MAIN_HANDLED=1;__OPENGL_AVAILABLE__;_MBCS;WIN32;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;__CBCOPY__;__CBPASTE__;APP_NAME_FULL="Oricutron 1.2";APP_YEAR="2015";VERSION_COPYRIGHTS="Oricutron 1.2.0 (c)2015 Peter Gordon (pete@petergordon.org.uk)";%(PreprocessorDefinitions) + SDL_LIB=1;SDL_MAIN_HANDLED=1;__OPENGL_AVAILABLE__;_MBCS;WIN32;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;__CBCOPY__;__CBPASTE__;APP_NAME_FULL="Oricutron 1.2";APP_YEAR="2015";VERSION_COPYRIGHTS="Oricutron 1.2.0 (c)2015 Peter Gordon (pete@gordon.plus)";%(PreprocessorDefinitions) AnySuitable Speed true @@ -279,6 +279,7 @@ if "$(Configuration.Contains('Release'))"=="True" ( copy "..\vcpkg\installed\x64 + @@ -316,6 +317,7 @@ if "$(Configuration.Contains('Release'))"=="True" ( copy "..\vcpkg\installed\x64 + @@ -372,4 +374,4 @@ if "$(Configuration.Contains('Release'))"=="True" ( copy "..\vcpkg\installed\x64 - \ No newline at end of file + diff --git a/msvc/VS2019/Oricutron.vcxproj.filters b/msvc/VS2019/Oricutron.vcxproj.filters index 9d9e7621..7a880e2a 100644 --- a/msvc/VS2019/Oricutron.vcxproj.filters +++ b/msvc/VS2019/Oricutron.vcxproj.filters @@ -1,4 +1,4 @@ - + @@ -49,6 +49,12 @@ {8438c688-6a7e-49a1-bd13-fa16128c58ec} + + {7a330041-d032-4884-903e-eb6f613ed87e} + + + {b01b5e24-c6cf-49fb-8e17-a4eae6400688} + @@ -84,12 +90,6 @@ Source Files - - Source Files - - - Source Files - Source Files @@ -174,6 +174,15 @@ Source Files\acia + + Source Files\plugins + + + Source Files\plugins + + + Source Files\plugins + @@ -206,12 +215,6 @@ Header Files - - Header Files - - - Header Files - Header Files @@ -263,6 +266,15 @@ Header Files\msvc + + Header Files\plugins + + + Header Files\plugins + + + Header Files\plugins + diff --git a/msvc/dirent.h b/msvc/dirent.h index f7a46daf..b65a0eff 100644 --- a/msvc/dirent.h +++ b/msvc/dirent.h @@ -219,99 +219,103 @@ extern "C" { /* Wide-character version */ -struct _wdirent { - /* Always zero */ - long d_ino; +struct _wdirent +{ + /* Always zero */ + long d_ino; - /* File position within stream */ - long d_off; + /* File position within stream */ + long d_off; - /* Structure size */ - unsigned short d_reclen; + /* Structure size */ + unsigned short d_reclen; - /* Length of name without \0 */ - size_t d_namlen; + /* Length of name without \0 */ + size_t d_namlen; - /* File type */ - int d_type; + /* File type */ + int d_type; - /* File name */ - wchar_t d_name[PATH_MAX+1]; + /* File name */ + wchar_t d_name[PATH_MAX+1]; }; typedef struct _wdirent _wdirent; -struct _WDIR { - /* Current directory entry */ - struct _wdirent ent; +struct _WDIR +{ + /* Current directory entry */ + struct _wdirent ent; - /* Private file data */ - WIN32_FIND_DATAW data; + /* Private file data */ + WIN32_FIND_DATAW data; - /* True if data is valid */ - int cached; + /* True if data is valid */ + int cached; - /* Win32 search handle */ - HANDLE handle; + /* Win32 search handle */ + HANDLE handle; - /* Initial directory name */ - wchar_t *patt; + /* Initial directory name */ + wchar_t* patt; }; typedef struct _WDIR _WDIR; /* Multi-byte character version */ -struct dirent { - /* Always zero */ - long d_ino; +struct dirent +{ + /* Always zero */ + long d_ino; - /* File position within stream */ - long d_off; + /* File position within stream */ + long d_off; - /* Structure size */ - unsigned short d_reclen; + /* Structure size */ + unsigned short d_reclen; - /* Length of name without \0 */ - size_t d_namlen; + /* Length of name without \0 */ + size_t d_namlen; - /* File type */ - int d_type; + /* File type */ + int d_type; - /* File name */ - char d_name[PATH_MAX+1]; + /* File name */ + char d_name[PATH_MAX+1]; }; typedef struct dirent dirent; -struct DIR { - struct dirent ent; - struct _WDIR *wdirp; +struct DIR +{ + struct dirent ent; + struct _WDIR *wdirp; }; typedef struct DIR DIR; /* Dirent functions */ -static DIR *opendir (const char *dirname); -static _WDIR *_wopendir (const wchar_t *dirname); +static DIR *opendir(const char* dirname); +static _WDIR *_wopendir(const wchar_t* dirname); -static struct dirent *readdir (DIR *dirp); -static struct _wdirent *_wreaddir (_WDIR *dirp); +static struct dirent *readdir(DIR *dirp); +static struct _wdirent *_wreaddir(_WDIR *dirp); static int readdir_r( - DIR *dirp, struct dirent *entry, struct dirent **result); + DIR *dirp, struct dirent *entry, struct dirent **result); static int _wreaddir_r( - _WDIR *dirp, struct _wdirent *entry, struct _wdirent **result); + _WDIR *dirp, struct _wdirent *entry, struct _wdirent **result); -static int closedir (DIR *dirp); -static int _wclosedir (_WDIR *dirp); +static int closedir(DIR *dirp); +static int _wclosedir(_WDIR *dirp); -static void rewinddir (DIR* dirp); -static void _wrewinddir (_WDIR* dirp); +static void rewinddir(DIR* dirp); +static void _wrewinddir(_WDIR* dirp); -static int scandir (const char *dirname, struct dirent ***namelist, - int (*filter)(const struct dirent*), - int (*compare)(const struct dirent**, const struct dirent**)); +static int scandir(const char* dirname, struct dirent ***namelist, + int (*filter)(const struct dirent*), + int (*compare)(const struct dirent**, const struct dirent**)); -static int alphasort (const struct dirent **a, const struct dirent **b); +static int alphasort(const struct dirent **a, const struct dirent **b); -static int versionsort (const struct dirent **a, const struct dirent **b); +static int versionsort(const struct dirent **a, const struct dirent **b); /* For compatibility with Symbian */ @@ -324,24 +328,24 @@ static int versionsort (const struct dirent **a, const struct dirent **b); /* Internal utility functions */ -static WIN32_FIND_DATAW *dirent_first (_WDIR *dirp); -static WIN32_FIND_DATAW *dirent_next (_WDIR *dirp); +static WIN32_FIND_DATAW *dirent_first(_WDIR *dirp); +static WIN32_FIND_DATAW *dirent_next(_WDIR *dirp); static int dirent_mbstowcs_s( - size_t *pReturnValue, - wchar_t *wcstr, - size_t sizeInWords, - const char *mbstr, - size_t count); + size_t* pReturnValue, + wchar_t* wcstr, + size_t sizeInWords, + const char* mbstr, + size_t count); static int dirent_wcstombs_s( - size_t *pReturnValue, - char *mbstr, - size_t sizeInBytes, - const wchar_t *wcstr, - size_t count); + size_t* pReturnValue, + char* mbstr, + size_t sizeInBytes, + const wchar_t* wcstr, + size_t count); -static void dirent_set_errno (int error); +static void dirent_set_errno(int error); /* @@ -351,97 +355,104 @@ static void dirent_set_errno (int error); */ static _WDIR* _wopendir( - const wchar_t *dirname) + const wchar_t* dirname) { - _WDIR *dirp; - DWORD n; - wchar_t *p; - - /* Must have directory name */ - if (dirname == NULL || dirname[0] == '\0') { - dirent_set_errno (ENOENT); - return NULL; - } - - /* Allocate new _WDIR structure */ - dirp = (_WDIR*) malloc (sizeof (struct _WDIR)); - if (!dirp) { - return NULL; - } - - /* Reset _WDIR structure */ - dirp->handle = INVALID_HANDLE_VALUE; - dirp->patt = NULL; - dirp->cached = 0; + _WDIR *dirp; + DWORD n; + wchar_t* p; + + /* Must have directory name */ + if(dirname == NULL || dirname[0] == '\0') + { + dirent_set_errno(ENOENT); + return NULL; + } - /* - * Compute the length of full path plus zero terminator - * - * Note that on WinRT there's no way to convert relative paths - * into absolute paths, so just assume it is an absolute path. - */ + /* Allocate new _WDIR structure */ + dirp = (_WDIR*) malloc(sizeof(struct _WDIR)); + if(!dirp) + { + return NULL; + } + + /* Reset _WDIR structure */ + dirp->handle = INVALID_HANDLE_VALUE; + dirp->patt = NULL; + dirp->cached = 0; + + /* + * Compute the length of full path plus zero terminator + * + * Note that on WinRT there's no way to convert relative paths + * into absolute paths, so just assume it is an absolute path. + */ #if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) - /* Desktop */ - n = GetFullPathNameW (dirname, 0, NULL, NULL); + /* Desktop */ + n = GetFullPathNameW(dirname, 0, NULL, NULL); #else - /* WinRT */ - n = wcslen (dirname); + /* WinRT */ + n = wcslen(dirname); #endif - /* Allocate room for absolute directory name and search pattern */ - dirp->patt = (wchar_t*) malloc (sizeof (wchar_t) * n + 16); - if (dirp->patt == NULL) { - goto exit_closedir; - } - - /* - * Convert relative directory name to an absolute one. This - * allows rewinddir() to function correctly even when current - * working directory is changed between opendir() and rewinddir(). - * - * Note that on WinRT there's no way to convert relative paths - * into absolute paths, so just assume it is an absolute path. - */ + /* Allocate room for absolute directory name and search pattern */ + dirp->patt = (wchar_t*) malloc(sizeof(wchar_t) * n + 16); + if(dirp->patt == NULL) + { + goto exit_closedir; + } + + /* + * Convert relative directory name to an absolute one. This + * allows rewinddir() to function correctly even when current + * working directory is changed between opendir() and rewinddir(). + * + * Note that on WinRT there's no way to convert relative paths + * into absolute paths, so just assume it is an absolute path. + */ #if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) - /* Desktop */ - n = GetFullPathNameW (dirname, n, dirp->patt, NULL); - if (n <= 0) { - goto exit_closedir; - } + /* Desktop */ + n = GetFullPathNameW(dirname, n, dirp->patt, NULL); + if(n <= 0) + { + goto exit_closedir; + } #else - /* WinRT */ - wcsncpy_s (dirp->patt, n+1, dirname, n); + /* WinRT */ + wcsncpy_s(dirp->patt, n+1, dirname, n); #endif - /* Append search pattern \* to the directory name */ - p = dirp->patt + n; - switch (p[-1]) { + /* Append search pattern \* to the directory name */ + p = dirp->patt + n; + switch(p[-1]) + { case '\\': case '/': case ':': - /* Directory ends in path separator, e.g. c:\temp\ */ - /*NOP*/; - break; + /* Directory ends in path separator, e.g. c:\temp\ */ + /*NOP*/ + ; + break; default: - /* Directory name doesn't end in path separator */ - *p++ = '\\'; - } - *p++ = '*'; - *p = '\0'; - - /* Open directory stream and retrieve the first entry */ - if (!dirent_first (dirp)) { - goto exit_closedir; - } - - /* Success */ - return dirp; - - /* Failure */ + /* Directory name doesn't end in path separator */ + *p++ = '\\'; + } + *p++ = '*'; + *p = '\0'; + + /* Open directory stream and retrieve the first entry */ + if(!dirent_first(dirp)) + { + goto exit_closedir; + } + + /* Success */ + return dirp; + + /* Failure */ exit_closedir: - _wclosedir (dirp); - return NULL; + _wclosedir(dirp); + return NULL; } /* @@ -452,18 +463,18 @@ _wopendir( */ static struct _wdirent* _wreaddir( - _WDIR *dirp) + _WDIR *dirp) { - struct _wdirent *entry; + struct _wdirent *entry; - /* - * Read directory entry to buffer. We can safely ignore the return value - * as entry will be set to NULL in case of error. - */ - (void) _wreaddir_r (dirp, &dirp->ent, &entry); + /* + * Read directory entry to buffer. We can safely ignore the return value + * as entry will be set to NULL in case of error. + */ + (void) _wreaddir_r(dirp, &dirp->ent, &entry); - /* Return pointer to statically allocated directory entry */ - return entry; + /* Return pointer to statically allocated directory entry */ + return entry; } /* @@ -474,59 +485,68 @@ _wreaddir( */ static int _wreaddir_r( - _WDIR *dirp, - struct _wdirent *entry, - struct _wdirent **result) + _WDIR *dirp, + struct _wdirent *entry, + struct _wdirent **result) { - WIN32_FIND_DATAW *datap; - - /* Read next directory entry */ - datap = dirent_next (dirp); - if (datap) { - size_t n; - DWORD attr; - - /* - * Copy file name as wide-character string. If the file name is too - * long to fit in to the destination buffer, then truncate file name - * to PATH_MAX characters and zero-terminate the buffer. - */ - n = 0; - while (n < PATH_MAX && datap->cFileName[n] != 0) { - entry->d_name[n] = datap->cFileName[n]; - n++; - } - entry->d_name[n] = 0; - - /* Length of file name excluding zero terminator */ - entry->d_namlen = n; - - /* File type */ - attr = datap->dwFileAttributes; - if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) { - entry->d_type = DT_CHR; - } else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) { - entry->d_type = DT_DIR; - } else { - entry->d_type = DT_REG; - } - - /* Reset dummy fields */ - entry->d_ino = 0; - entry->d_off = 0; - entry->d_reclen = sizeof (struct _wdirent); + WIN32_FIND_DATAW *datap; - /* Set result address */ - *result = entry; + /* Read next directory entry */ + datap = dirent_next(dirp); + if(datap) + { + size_t n; + DWORD attr; - } else { + /* + * Copy file name as wide-character string. If the file name is too + * long to fit in to the destination buffer, then truncate file name + * to PATH_MAX characters and zero-terminate the buffer. + */ + n = 0; + while(n < PATH_MAX && datap->cFileName[n] != 0) + { + entry->d_name[n] = datap->cFileName[n]; + n++; + } + entry->d_name[n] = 0; - /* Return NULL to indicate end of directory */ - *result = NULL; + /* Length of file name excluding zero terminator */ + entry->d_namlen = n; + /* File type */ + attr = datap->dwFileAttributes; + if((attr & FILE_ATTRIBUTE_DEVICE) != 0) + { + entry->d_type = DT_CHR; + } + else if((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) + { + entry->d_type = DT_DIR; } + else + { + entry->d_type = DT_REG; + } + + /* Reset dummy fields */ + entry->d_ino = 0; + entry->d_off = 0; + entry->d_reclen = sizeof(struct _wdirent); + + /* Set result address */ + *result = entry; + + } + else + { - return /*OK*/0; + /* Return NULL to indicate end of directory */ + *result = NULL; + + } + + return /*OK*/0; } /* @@ -536,31 +556,35 @@ _wreaddir_r( */ static int _wclosedir( - _WDIR *dirp) + _WDIR *dirp) { - int ok; - if (dirp) { + int ok; + if(dirp) + { - /* Release search handle */ - if (dirp->handle != INVALID_HANDLE_VALUE) { - FindClose (dirp->handle); - } + /* Release search handle */ + if(dirp->handle != INVALID_HANDLE_VALUE) + { + FindClose(dirp->handle); + } - /* Release search pattern */ - free (dirp->patt); + /* Release search pattern */ + free(dirp->patt); - /* Release directory structure */ - free (dirp); - ok = /*success*/0; + /* Release directory structure */ + free(dirp); + ok = /*success*/0; - } else { + } + else + { - /* Invalid directory stream */ - dirent_set_errno (EBADF); - ok = /*failure*/-1; + /* Invalid directory stream */ + dirent_set_errno(EBADF); + ok = /*failure*/-1; - } - return ok; + } + return ok; } /* @@ -569,64 +593,70 @@ _wclosedir( */ static void _wrewinddir( - _WDIR* dirp) + _WDIR* dirp) { - if (dirp) { - /* Release existing search handle */ - if (dirp->handle != INVALID_HANDLE_VALUE) { - FindClose (dirp->handle); - } - - /* Open new search handle */ - dirent_first (dirp); + if(dirp) + { + /* Release existing search handle */ + if(dirp->handle != INVALID_HANDLE_VALUE) + { + FindClose(dirp->handle); } + + /* Open new search handle */ + dirent_first(dirp); + } } /* Get first directory entry (internal) */ static WIN32_FIND_DATAW* dirent_first( - _WDIR *dirp) + _WDIR *dirp) { - WIN32_FIND_DATAW *datap; - DWORD error; - - /* Open directory and retrieve the first entry */ - dirp->handle = FindFirstFileExW( - dirp->patt, FindExInfoStandard, &dirp->data, - FindExSearchNameMatch, NULL, 0); - if (dirp->handle != INVALID_HANDLE_VALUE) { - - /* a directory entry is now waiting in memory */ - datap = &dirp->data; - dirp->cached = 1; - - } else { - - /* Failed to open directory: no directory entry in memory */ - dirp->cached = 0; - datap = NULL; - - /* Set error code */ - error = GetLastError (); - switch (error) { - case ERROR_ACCESS_DENIED: - /* No read access to directory */ - dirent_set_errno (EACCES); - break; - - case ERROR_DIRECTORY: - /* Directory name is invalid */ - dirent_set_errno (ENOTDIR); - break; - - case ERROR_PATH_NOT_FOUND: - default: - /* Cannot find the file */ - dirent_set_errno (ENOENT); - } + WIN32_FIND_DATAW *datap; + DWORD error; + + /* Open directory and retrieve the first entry */ + dirp->handle = FindFirstFileExW( + dirp->patt, FindExInfoStandard, &dirp->data, + FindExSearchNameMatch, NULL, 0); + if(dirp->handle != INVALID_HANDLE_VALUE) + { + + /* a directory entry is now waiting in memory */ + datap = &dirp->data; + dirp->cached = 1; + + } + else + { + + /* Failed to open directory: no directory entry in memory */ + dirp->cached = 0; + datap = NULL; + + /* Set error code */ + error = GetLastError(); + switch(error) + { + case ERROR_ACCESS_DENIED: + /* No read access to directory */ + dirent_set_errno(EACCES); + break; + case ERROR_DIRECTORY: + /* Directory name is invalid */ + dirent_set_errno(ENOTDIR); + break; + + case ERROR_PATH_NOT_FOUND: + default: + /* Cannot find the file */ + dirent_set_errno(ENOENT); } - return datap; + + } + return datap; } /* @@ -636,38 +666,46 @@ dirent_first( */ static WIN32_FIND_DATAW* dirent_next( - _WDIR *dirp) + _WDIR *dirp) { - WIN32_FIND_DATAW *p; - - /* Get next directory entry */ - if (dirp->cached != 0) { - - /* A valid directory entry already in memory */ - p = &dirp->data; - dirp->cached = 0; - - } else if (dirp->handle != INVALID_HANDLE_VALUE) { - - /* Get the next directory entry from stream */ - if (FindNextFileW (dirp->handle, &dirp->data) != FALSE) { - /* Got a file */ - p = &dirp->data; - } else { - /* The very last entry has been processed or an error occurred */ - FindClose (dirp->handle); - dirp->handle = INVALID_HANDLE_VALUE; - p = NULL; - } + WIN32_FIND_DATAW *p; - } else { + /* Get next directory entry */ + if(dirp->cached != 0) + { - /* End of directory stream reached */ - p = NULL; + /* A valid directory entry already in memory */ + p = &dirp->data; + dirp->cached = 0; + } + else if(dirp->handle != INVALID_HANDLE_VALUE) + { + + /* Get the next directory entry from stream */ + if(FindNextFileW(dirp->handle, &dirp->data) != FALSE) + { + /* Got a file */ + p = &dirp->data; + } + else + { + /* The very last entry has been processed or an error occurred */ + FindClose(dirp->handle); + dirp->handle = INVALID_HANDLE_VALUE; + p = NULL; } - return p; + } + else + { + + /* End of directory stream reached */ + p = NULL; + + } + + return p; } /* @@ -675,55 +713,59 @@ dirent_next( */ static DIR* opendir( - const char *dirname) + const char* dirname) { - struct DIR *dirp; + struct DIR *dirp; - /* Must have directory name */ - if (dirname == NULL || dirname[0] == '\0') { - dirent_set_errno (ENOENT); - return NULL; - } + /* Must have directory name */ + if(dirname == NULL || dirname[0] == '\0') + { + dirent_set_errno(ENOENT); + return NULL; + } - /* Allocate memory for DIR structure */ - dirp = (DIR*) malloc (sizeof (struct DIR)); - if (!dirp) { - return NULL; - } - { - int error; - wchar_t wname[PATH_MAX + 1]; - size_t n; - - /* Convert directory name to wide-character string */ - error = dirent_mbstowcs_s( - &n, wname, PATH_MAX + 1, dirname, PATH_MAX + 1); - if (error) { - /* - * Cannot convert file name to wide-character string. This - * occurs if the string contains invalid multi-byte sequences or - * the output buffer is too small to contain the resulting - * string. - */ - goto exit_free; - } + /* Allocate memory for DIR structure */ + dirp = (DIR*) malloc(sizeof(struct DIR)); + if(!dirp) + { + return NULL; + } + { + int error; + wchar_t wname[PATH_MAX + 1]; + size_t n; + /* Convert directory name to wide-character string */ + error = dirent_mbstowcs_s( + &n, wname, PATH_MAX + 1, dirname, PATH_MAX + 1); + if(error) + { + /* + * Cannot convert file name to wide-character string. This + * occurs if the string contains invalid multi-byte sequences or + * the output buffer is too small to contain the resulting + * string. + */ + goto exit_free; + } - /* Open directory stream using wide-character name */ - dirp->wdirp = _wopendir (wname); - if (!dirp->wdirp) { - goto exit_free; - } + /* Open directory stream using wide-character name */ + dirp->wdirp = _wopendir(wname); + if(!dirp->wdirp) + { + goto exit_free; } - /* Success */ - return dirp; + } + + /* Success */ + return dirp; - /* Failure */ + /* Failure */ exit_free: - free (dirp); - return NULL; + free(dirp); + return NULL; } /* @@ -731,18 +773,18 @@ opendir( */ static struct dirent* readdir( - DIR *dirp) + DIR *dirp) { - struct dirent *entry; + struct dirent *entry; - /* - * Read directory entry to buffer. We can safely ignore the return value - * as entry will be set to NULL in case of error. - */ - (void) readdir_r (dirp, &dirp->ent, &entry); + /* + * Read directory entry to buffer. We can safely ignore the return value + * as entry will be set to NULL in case of error. + */ + (void) readdir_r(dirp, &dirp->ent, &entry); - /* Return pointer to statically allocated directory entry */ - return entry; + /* Return pointer to statically allocated directory entry */ + return entry; } /* @@ -753,88 +795,100 @@ readdir( */ static int readdir_r( - DIR *dirp, - struct dirent *entry, - struct dirent **result) + DIR *dirp, + struct dirent *entry, + struct dirent **result) { - WIN32_FIND_DATAW *datap; - - /* Read next directory entry */ - datap = dirent_next (dirp->wdirp); - if (datap) { - size_t n; - int error; - - /* Attempt to convert file name to multi-byte string */ - error = dirent_wcstombs_s( - &n, entry->d_name, PATH_MAX + 1, datap->cFileName, PATH_MAX + 1); - - /* - * If the file name cannot be represented by a multi-byte string, - * then attempt to use old 8+3 file name. This allows traditional - * Unix-code to access some file names despite of unicode - * characters, although file names may seem unfamiliar to the user. - * - * Be ware that the code below cannot come up with a short file - * name unless the file system provides one. At least - * VirtualBox shared folders fail to do this. - */ - if (error && datap->cAlternateFileName[0] != '\0') { - error = dirent_wcstombs_s( + WIN32_FIND_DATAW *datap; + + /* Read next directory entry */ + datap = dirent_next(dirp->wdirp); + if(datap) + { + size_t n; + int error; + + /* Attempt to convert file name to multi-byte string */ + error = dirent_wcstombs_s( + &n, entry->d_name, PATH_MAX + 1, datap->cFileName, PATH_MAX + 1); + + /* + * If the file name cannot be represented by a multi-byte string, + * then attempt to use old 8+3 file name. This allows traditional + * Unix-code to access some file names despite of unicode + * characters, although file names may seem unfamiliar to the user. + * + * Be ware that the code below cannot come up with a short file + * name unless the file system provides one. At least + * VirtualBox shared folders fail to do this. + */ + if(error && datap->cAlternateFileName[0] != '\0') + { + error = dirent_wcstombs_s( &n, entry->d_name, PATH_MAX + 1, datap->cAlternateFileName, PATH_MAX + 1); - } + } - if (!error) { - DWORD attr; - - /* Length of file name excluding zero terminator */ - entry->d_namlen = n - 1; - - /* File attributes */ - attr = datap->dwFileAttributes; - if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) { - entry->d_type = DT_CHR; - } else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) { - entry->d_type = DT_DIR; - } else { - entry->d_type = DT_REG; - } - - /* Reset dummy fields */ - entry->d_ino = 0; - entry->d_off = 0; - entry->d_reclen = sizeof (struct dirent); - - } else { - - /* - * Cannot convert file name to multi-byte string so construct - * an erroneous directory entry and return that. Note that - * we cannot return NULL as that would stop the processing - * of directory entries completely. - */ - entry->d_name[0] = '?'; - entry->d_name[1] = '\0'; - entry->d_namlen = 1; - entry->d_type = DT_UNKNOWN; - entry->d_ino = 0; - entry->d_off = -1; - entry->d_reclen = 0; + if(!error) + { + DWORD attr; + + /* Length of file name excluding zero terminator */ + entry->d_namlen = n - 1; + + /* File attributes */ + attr = datap->dwFileAttributes; + if((attr & FILE_ATTRIBUTE_DEVICE) != 0) + { + entry->d_type = DT_CHR; + } + else if((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) + { + entry->d_type = DT_DIR; + } + else + { + entry->d_type = DT_REG; + } + + /* Reset dummy fields */ + entry->d_ino = 0; + entry->d_off = 0; + entry->d_reclen = sizeof(struct dirent); - } + } + else + { - /* Return pointer to directory entry */ - *result = entry; + /* + * Cannot convert file name to multi-byte string so construct + * an erroneous directory entry and return that. Note that + * we cannot return NULL as that would stop the processing + * of directory entries completely. + */ + entry->d_name[0] = '?'; + entry->d_name[1] = '\0'; + entry->d_namlen = 1; + entry->d_type = DT_UNKNOWN; + entry->d_ino = 0; + entry->d_off = -1; + entry->d_reclen = 0; - } else { + } - /* No more directory entries */ - *result = NULL; + /* Return pointer to directory entry */ + *result = entry; - } + } + else + { + + /* No more directory entries */ + *result = NULL; + + } - return /*OK*/0; + return /*OK*/0; } /* @@ -842,26 +896,29 @@ readdir_r( */ static int closedir( - DIR *dirp) + DIR *dirp) { - int ok; - if (dirp) { + int ok; + if(dirp) + { - /* Close wide-character directory stream */ - ok = _wclosedir (dirp->wdirp); - dirp->wdirp = NULL; + /* Close wide-character directory stream */ + ok = _wclosedir(dirp->wdirp); + dirp->wdirp = NULL; - /* Release multi-byte character version */ - free (dirp); + /* Release multi-byte character version */ + free(dirp); - } else { + } + else + { - /* Invalid directory stream */ - dirent_set_errno (EBADF); - ok = /*failure*/-1; + /* Invalid directory stream */ + dirent_set_errno(EBADF); + ok = /*failure*/-1; - } - return ok; + } + return ok; } /* @@ -869,10 +926,10 @@ closedir( */ static void rewinddir( - DIR* dirp) + DIR* dirp) { - /* Rewind wide-character string directory stream */ - _wrewinddir (dirp->wdirp); + /* Rewind wide-character string directory stream */ + _wrewinddir(dirp->wdirp); } /* @@ -880,275 +937,314 @@ rewinddir( */ static int scandir( - const char *dirname, - struct dirent ***namelist, - int (*filter)(const struct dirent*), - int (*compare)(const struct dirent**, const struct dirent**)) + const char* dirname, + struct dirent ***namelist, + int (*filter)(const struct dirent*), + int (*compare)(const struct dirent**, const struct dirent**)) { - struct dirent **files = NULL; - size_t size = 0; - size_t allocated = 0; - const size_t init_size = 1; - DIR *dir = NULL; - struct dirent *entry; - struct dirent *tmp = NULL; - size_t i; - int result = 0; - - /* Open directory stream */ - dir = opendir (dirname); - if (dir) { - - /* Read directory entries to memory */ - while (1) { - - /* Enlarge pointer table to make room for another pointer */ - if (size >= allocated) { - void *p; - size_t num_entries; - - /* Compute number of entries in the enlarged pointer table */ - if (size < init_size) { - /* Allocate initial pointer table */ - num_entries = init_size; - } else { - /* Double the size */ - num_entries = size * 2; - } - - /* Allocate first pointer table or enlarge existing table */ - p = realloc (files, sizeof (void*) * num_entries); - if (p != NULL) { - /* Got the memory */ - files = (dirent**) p; - allocated = num_entries; - } else { - /* Out of memory */ - result = -1; - break; - } - - } - - /* Allocate room for temporary directory entry */ - if (tmp == NULL) { - tmp = (struct dirent*) malloc (sizeof (struct dirent)); - if (tmp == NULL) { - /* Cannot allocate temporary directory entry */ - result = -1; - break; - } - } - - /* Read directory entry to temporary area */ - if (readdir_r (dir, tmp, &entry) == /*OK*/0) { - - /* Did we get an entry? */ - if (entry != NULL) { - int pass; - - /* Determine whether to include the entry in result */ - if (filter) { - /* Let the filter function decide */ - pass = filter (tmp); - } else { - /* No filter function, include everything */ - pass = 1; - } - - if (pass) { - /* Store the temporary entry to pointer table */ - files[size++] = tmp; - tmp = NULL; - - /* Keep up with the number of files */ - result++; - } - - } else { - - /* - * End of directory stream reached => sort entries and - * exit. - */ - qsort (files, size, sizeof (void*), - (int (*) (const void*, const void*)) compare); - break; - - } - - } else { - /* Error reading directory entry */ - result = /*Error*/ -1; - break; - } + struct dirent **files = NULL; + size_t size = 0; + size_t allocated = 0; + const size_t init_size = 1; + DIR *dir = NULL; + struct dirent *entry; + struct dirent *tmp = NULL; + size_t i; + int result = 0; + + /* Open directory stream */ + dir = opendir(dirname); + if(dir) + { + + /* Read directory entries to memory */ + while(1) + { + /* Enlarge pointer table to make room for another pointer */ + if(size >= allocated) + { + void* p; + size_t num_entries; + + /* Compute number of entries in the enlarged pointer table */ + if(size < init_size) + { + /* Allocate initial pointer table */ + num_entries = init_size; + } + else + { + /* Double the size */ + num_entries = size * 2; } - } else { - /* Cannot open directory */ - result = /*Error*/ -1; - } + /* Allocate first pointer table or enlarge existing table */ + p = realloc(files, sizeof(void*) * num_entries); + if(p != NULL) + { + /* Got the memory */ + files = (dirent**) p; + allocated = num_entries; + } + else + { + /* Out of memory */ + result = -1; + break; + } - /* Release temporary directory entry */ - free (tmp); + } + + /* Allocate room for temporary directory entry */ + if(tmp == NULL) + { + tmp = (struct dirent*) malloc(sizeof(struct dirent)); + if(tmp == NULL) + { + /* Cannot allocate temporary directory entry */ + result = -1; + break; + } + } + + /* Read directory entry to temporary area */ + if(readdir_r(dir, tmp, &entry) == /*OK*/0) + { + + /* Did we get an entry? */ + if(entry != NULL) + { + int pass; + + /* Determine whether to include the entry in result */ + if(filter) + { + /* Let the filter function decide */ + pass = filter(tmp); + } + else + { + /* No filter function, include everything */ + pass = 1; + } + + if(pass) + { + /* Store the temporary entry to pointer table */ + files[size++] = tmp; + tmp = NULL; + + /* Keep up with the number of files */ + result++; + } - /* Release allocated memory on error */ - if (result < 0) { - for (i = 0; i < size; i++) { - free (files[i]); } - free (files); - files = NULL; - } + else + { + + /* + * End of directory stream reached => sort entries and + * exit. + */ + qsort(files, size, sizeof(void*), + (int (*)(const void*, const void*)) compare); + break; + + } + + } + else + { + /* Error reading directory entry */ + result = /*Error*/ -1; + break; + } - /* Close directory stream */ - if (dir) { - closedir (dir); } - /* Pass pointer table to caller */ - if (namelist) { - *namelist = files; + } + else + { + /* Cannot open directory */ + result = /*Error*/ -1; + } + + /* Release temporary directory entry */ + free(tmp); + + /* Release allocated memory on error */ + if(result < 0) + { + for(i = 0; i < size; i++) + { + free(files[i]); } - return result; + free(files); + files = NULL; + } + + /* Close directory stream */ + if(dir) + { + closedir(dir); + } + + /* Pass pointer table to caller */ + if(namelist) + { + *namelist = files; + } + return result; } /* Alphabetical sorting */ static int alphasort( - const struct dirent **a, const struct dirent **b) + const struct dirent **a, const struct dirent **b) { - return strcoll ((*a)->d_name, (*b)->d_name); + return strcoll((*a)->d_name, (*b)->d_name); } /* Sort versions */ static int versionsort( - const struct dirent **a, const struct dirent **b) + const struct dirent **a, const struct dirent **b) { - /* FIXME: implement strverscmp and use that */ - return alphasort (a, b); + /* FIXME: implement strverscmp and use that */ + return alphasort(a, b); } /* Convert multi-byte string to wide character string */ static int dirent_mbstowcs_s( - size_t *pReturnValue, - wchar_t *wcstr, - size_t sizeInWords, - const char *mbstr, - size_t count) + size_t* pReturnValue, + wchar_t* wcstr, + size_t sizeInWords, + const char* mbstr, + size_t count) { - int error; + int error; #if defined(_MSC_VER) && _MSC_VER >= 1400 - /* Microsoft Visual Studio 2005 or later */ - error = mbstowcs_s (pReturnValue, wcstr, sizeInWords, mbstr, count); + /* Microsoft Visual Studio 2005 or later */ + error = mbstowcs_s(pReturnValue, wcstr, sizeInWords, mbstr, count); #else - /* Older Visual Studio or non-Microsoft compiler */ - size_t n; + /* Older Visual Studio or non-Microsoft compiler */ + size_t n; - /* Convert to wide-character string (or count characters) */ - n = mbstowcs (wcstr, mbstr, sizeInWords); - if (!wcstr || n < count) { + /* Convert to wide-character string (or count characters) */ + n = mbstowcs(wcstr, mbstr, sizeInWords); + if(!wcstr || n < count) + { - /* Zero-terminate output buffer */ - if (wcstr && sizeInWords) { - if (n >= sizeInWords) { - n = sizeInWords - 1; - } - wcstr[n] = 0; - } + /* Zero-terminate output buffer */ + if(wcstr && sizeInWords) + { + if(n >= sizeInWords) + { + n = sizeInWords - 1; + } + wcstr[n] = 0; + } - /* Length of resulting multi-byte string WITH zero terminator */ - if (pReturnValue) { - *pReturnValue = n + 1; - } + /* Length of resulting multi-byte string WITH zero terminator */ + if(pReturnValue) + { + *pReturnValue = n + 1; + } - /* Success */ - error = 0; + /* Success */ + error = 0; - } else { + } + else + { - /* Could not convert string */ - error = 1; + /* Could not convert string */ + error = 1; - } + } #endif - return error; + return error; } /* Convert wide-character string to multi-byte string */ static int dirent_wcstombs_s( - size_t *pReturnValue, - char *mbstr, - size_t sizeInBytes, /* max size of mbstr */ - const wchar_t *wcstr, - size_t count) + size_t* pReturnValue, + char* mbstr, + size_t sizeInBytes, /* max size of mbstr */ + const wchar_t* wcstr, + size_t count) { - int error; + int error; #if defined(_MSC_VER) && _MSC_VER >= 1400 - /* Microsoft Visual Studio 2005 or later */ - error = wcstombs_s (pReturnValue, mbstr, sizeInBytes, wcstr, count); + /* Microsoft Visual Studio 2005 or later */ + error = wcstombs_s(pReturnValue, mbstr, sizeInBytes, wcstr, count); #else - /* Older Visual Studio or non-Microsoft compiler */ - size_t n; + /* Older Visual Studio or non-Microsoft compiler */ + size_t n; - /* Convert to multi-byte string (or count the number of bytes needed) */ - n = wcstombs (mbstr, wcstr, sizeInBytes); - if (!mbstr || n < count) { + /* Convert to multi-byte string (or count the number of bytes needed) */ + n = wcstombs(mbstr, wcstr, sizeInBytes); + if(!mbstr || n < count) + { - /* Zero-terminate output buffer */ - if (mbstr && sizeInBytes) { - if (n >= sizeInBytes) { - n = sizeInBytes - 1; - } - mbstr[n] = '\0'; - } + /* Zero-terminate output buffer */ + if(mbstr && sizeInBytes) + { + if(n >= sizeInBytes) + { + n = sizeInBytes - 1; + } + mbstr[n] = '\0'; + } - /* Length of resulting multi-bytes string WITH zero-terminator */ - if (pReturnValue) { - *pReturnValue = n + 1; - } + /* Length of resulting multi-bytes string WITH zero-terminator */ + if(pReturnValue) + { + *pReturnValue = n + 1; + } - /* Success */ - error = 0; + /* Success */ + error = 0; - } else { + } + else + { - /* Cannot convert string */ - error = 1; + /* Cannot convert string */ + error = 1; - } + } #endif - return error; + return error; } /* Set errno variable */ static void dirent_set_errno( - int error) + int error) { #if defined(_MSC_VER) && _MSC_VER >= 1400 - /* Microsoft Visual Studio 2005 and later */ - _set_errno (error); + /* Microsoft Visual Studio 2005 and later */ + _set_errno(error); #else - /* Non-Microsoft compiler or older Microsoft compiler */ - errno = error; + /* Non-Microsoft compiler or older Microsoft compiler */ + errno = error; #endif } diff --git a/oricutron.cfg b/oricutron.cfg index 6626c8bb..8b977e2d 100644 --- a/oricutron.cfg +++ b/oricutron.cfg @@ -34,6 +34,9 @@ ; Filename of the Microdisc ROM ;mdiscrom = 'roms/microdis' +; Filename of the Byte Drive 500 ROM +;bd500rom = 'roms/bd500' + ; Filename of the Jasmin ROM ;jasminrom = 'roms/jasmin' @@ -48,7 +51,7 @@ machine = atmos ; ---------------------------------- -; Type of disk controller (none, microdisc, jasmin, pravetz) +; Type of disk controller (none, microdisc, jasmin, bd500, pravetz) disktype = none ; Write back all changes to disk images (if turned off, you have to press @@ -59,8 +62,8 @@ diskautosave = yes ; Start with this disk in drive 0 (backslash is an escape char to insert ; quotes, so double backslash is required to insert a backslash. You can use -; forward slash as a path seperator, even on windows. -;diskimage = 'disks/barbitoric.dsk' +; forward slash as a path separator, even on windows. +;diskimage = 'assets/disks/aigledor.dsk' ; ---------------------------------- @@ -80,7 +83,7 @@ pravdiskautoboot = yes ; ---------------------------------- ; Start with this tape inserted -;tapeimage = 'tapes/cyclotron.tap' +;tapeimage = 'assets/tapes/Cyclotron.tap' ; ---------------------------------- @@ -92,8 +95,23 @@ debug = no ; ---------------------------------- +; Specifies how ROMDIS disables ROM chip(s) +; related to BD500/BDDOS +; rom16 = yes - 64k mode (Default) +; rom16 = no - 56k mode +;rom16 = yes + +; Support BD500/DOS70 +; dos70 = no (default) +;dos70 = no + +; ---------------------------------- + +; Initial status bar mode (none, nofps, full) +;statusbarmode = nofps + ; Render mode (soft, opengl) -rendermode = soft +rendermode = opengl ; Show scanlines? (yes/no) scanlines = no @@ -135,9 +153,17 @@ lightpen = no ;printenable = yes ; Filter printed symbols in 'printer_out.txt' -; select 'no' for raw binay mode +; select 'no' for raw binary mode ;printfilter = yes +; Enable audio DC adjustment +; default enabled +;dcadjust = yes + +; Enable sound loopback +; default disabled +;soundloopon = no + ; ACIA emulation back-end name: ; 'none' - no serial present ; 'loopback' - for testing - all TX data is returned to RX @@ -189,10 +215,14 @@ kbjoy2_fire2 = 'N' kbjoy2_fire3 = 'LALT' ; Visual keyboard -;show_keyboard = yes -;sticky_mod_keys = yes +show_keyboard = yes +sticky_mod_keys = yes ;autoload_keyboard_mapping = 'keymap/my_keymap.kma' +; Disable menu color scheme +;disable_menuscheme = no + ; ch376 chip emulation. This chip can read a usbkey. For more information : http://orix.oric.org ; only available in telestrat mode ch376 = no +twilighte_board = no diff --git a/oricutron.desktop b/oricutron.desktop index 9cd89b5b..da2c978d 100644 --- a/oricutron.desktop +++ b/oricutron.desktop @@ -10,4 +10,4 @@ Exec=oricutron %U MimeType=application/x-oric-rom;application/x-oric-tape;application/x-oric-disk Icon=oricutron Categories=Emulator;Utility; -Keywords=ORIC,Oric1,Atmos +Keywords=ORIC,Oric1,Atmos,Pravetz-8D diff --git a/plugins/ch376/ch376.c b/plugins/ch376/ch376.c index d735c562..1220e804 100644 --- a/plugins/ch376/ch376.c +++ b/plugins/ch376/ch376.c @@ -18,8 +18,10 @@ 05.10.2017 - Assinie: Added support for CMD_DIR_CREATE and CMD_FILE_ERASE (Linux only) 21.08.2017 - Jede : Added support for CMD_DIR_CREATE and CMD_FILE_ERASE (WIN32 only) 22.07.2017 - OffseT : Added support for CMD_DIR_CREATE and CMD_FILE_ERASE (Added related Amiga system APIs only) - - */ + 01.02.2021 - Assinie: Fix time struct (Linux Only) + 02.04.2022 - Assinie: Added support for CMD_READ_VAR32 (FILE_SIZE and CURRENT_OFFSET only) (Linux Only) + 10.03.2023 - Assinie: Fix bug : . and .. was reading as right entry. Now, it's skipped +*/ /* /// "Portable includes" */ @@ -51,8 +53,14 @@ extern struct Library *SysBase; #include #include #include +#ifdef __ANDROID__ +#include +#define statvfs statfs +#else #include +#endif #include +#include #else #error "FixMe!" @@ -71,7 +79,7 @@ extern struct Library *SysBase; #define CH376_CMD_NONE 0x00 #define CH376_CMD_GET_IC_VER 0x01 #define CH376_CMD_CHECK_EXIST 0x06 -#define CH376_CMD_GET_FILE_SIZE 0x0c +#define CH376_CMD_READ_VAR32 0x0c #define CH376_CMD_SET_USB_MODE 0x15 #define CH376_CMD_GET_STATUS 0x22 #define CH376_CMD_RD_USB_DATA0 0x27 @@ -97,13 +105,17 @@ extern struct Library *SysBase; #define CH376_ARG_SET_USB_MODE_SD_HOST 0x03 #define CH376_ARG_SET_USB_MODE_USB_HOST 0x06 +// VAR32 offsets +#define CH376_VAR_FILE_SIZE 0x68 +#define CH376_VAR_CURRENT_OFFSET 0x6c + // Status & errors #define CH376_ERR_OPEN_DIR 0x41 #define CH376_ERR_MISS_FILE 0x42 #define CH376_ERR_FOUND_NAME 0x43 -#define CH376_RET_SUCCESS 0x51 -#define CH376_RET_ABORT 0x5f +#define CH376_RET_SUCCESS 0x51 +#define CH376_RET_ABORT 0x5f #define CH376_INT_SUCCESS 0x14 #define CH376_INT_DISK_READ 0x1d @@ -113,7 +125,7 @@ extern struct Library *SysBase; /* /// "CH376 data structures" */ -#define CMD_DATA_REQ_SIZE 0xff +#define CMD_DATA_REQ_SIZE 0xff // Attributes #define DIR_ATTR_READ_ONLY 0x01 @@ -132,53 +144,53 @@ extern struct Library *SysBase; // Important: All values in all structures are stored in little-endian (either in 16 or 32 bit) struct FatDirInfo { - char DIR_Name[11]; - CH376_U8 DIR_Attr; - CH376_U8 DIR_NTRes; - CH376_U8 DIR_CrtTimeTenth; - CH376_U8 DIR_CrtTime[2]; - CH376_U8 DIR_CrtDate[2]; - CH376_U8 DIR_LstAccDate[2]; - CH376_U8 DIR_FstClusHI[2]; - CH376_U8 DIR_WrtTime[2]; - CH376_U8 DIR_WrtDate[2]; - CH376_U8 DIR_FstClusLO[2]; - CH376_U8 DIR_FileSize[4]; + char DIR_Name[11]; + CH376_U8 DIR_Attr; + CH376_U8 DIR_NTRes; + CH376_U8 DIR_CrtTimeTenth; + CH376_U8 DIR_CrtTime[2]; + CH376_U8 DIR_CrtDate[2]; + CH376_U8 DIR_LstAccDate[2]; + CH376_U8 DIR_FstClusHI[2]; + CH376_U8 DIR_WrtTime[2]; + CH376_U8 DIR_WrtDate[2]; + CH376_U8 DIR_FstClusLO[2]; + CH376_U8 DIR_FileSize[4]; }; struct MountInfo { - CH376_U8 MOUNT_DeviceType; - CH376_U8 MOUNT_RemovableMedia; - CH376_U8 MOUNT_Versions; - CH376_U8 MOUNT_DataFormatAndEtc; - CH376_U8 MOUNT_AdditionalLength; - CH376_U8 MOUNT_Reserved1; - CH376_U8 MOUNT_Reserved2; - CH376_U8 MOUNT_MiscFlag; - char MOUNT_VendorIdStr[8]; - char MOUNT_ProductIdStr[16]; - char MOUNT_ProductRevStr[4]; + CH376_U8 MOUNT_DeviceType; + CH376_U8 MOUNT_RemovableMedia; + CH376_U8 MOUNT_Versions; + CH376_U8 MOUNT_DataFormatAndEtc; + CH376_U8 MOUNT_AdditionalLength; + CH376_U8 MOUNT_Reserved1; + CH376_U8 MOUNT_Reserved2; + CH376_U8 MOUNT_MiscFlag; + char MOUNT_VendorIdStr[8]; + char MOUNT_ProductIdStr[16]; + char MOUNT_ProductRevStr[4]; }; struct DiskQuery { - CH376_U8 DISK_TotalSector[4]; - CH376_U8 DISK_FreeSector[4]; - CH376_U8 DISK_DiskFat; + CH376_U8 DISK_TotalSector[4]; + CH376_U8 DISK_FreeSector[4]; + CH376_U8 DISK_DiskFat; }; union CommandData { - char CMD_FileName[14]; // [W/O] CH376_CMD_SET_FILE_NAME - struct MountInfo CMD_MountInfo; // [R/O] CH376_CMD_DISK_MOUNT - struct FatDirInfo CMD_FatDirInfo; // [R/O] CH376_CMD_FILE_OPEN, CH376_CMD_FILE_ENUM_GO - struct DiskQuery CMD_DiskQuery; // [R/O] CH376_CMD_DISK_QUERY, CH376_CMD_DISK_CAPACITY - CH376_U8 CMD_FileSeek[4]; // [R/W] CH376_CMD_BYTE_LOCATE - CH376_U8 CMD_FileReadWrite[2]; // [W/O] CH376_CMD_BYTE_READ, CH376_CMD_BYTE_WRITE - CH376_U8 CMD_IOBuffer[255]; // [R/W] CH376_CMD_BYTE_READ, CH376_CMD_BYTE_RD_GO, CH376_CMD_BYTE_WRITE, CH376_CMD_BYTE_WR_GO - CH376_U8 CMD_CheckByte; // [R/W] CH376_CMD_CHECK_EXIST - CH376_U8 CMD_FileSize[4]; // [R/W] CH376_CMD_GET_FILE_SIZE, CH376_CMD_SET_FILE_SIZE + char CMD_FileName[14]; // [W/O] CH376_CMD_SET_FILE_NAME + struct MountInfo CMD_MountInfo; // [R/O] CH376_CMD_DISK_MOUNT + struct FatDirInfo CMD_FatDirInfo; // [R/O] CH376_CMD_FILE_OPEN, CH376_CMD_FILE_ENUM_GO + struct DiskQuery CMD_DiskQuery; // [R/O] CH376_CMD_DISK_QUERY, CH376_CMD_DISK_CAPACITY + CH376_U8 CMD_FileSeek[4]; // [R/W] CH376_CMD_BYTE_LOCATE + CH376_U8 CMD_FileReadWrite[2]; // [W/O] CH376_CMD_BYTE_READ, CH376_CMD_BYTE_WRITE + CH376_U8 CMD_IOBuffer[255]; // [R/W] CH376_CMD_BYTE_READ, CH376_CMD_BYTE_RD_GO, CH376_CMD_BYTE_WRITE, CH376_CMD_BYTE_WR_GO + CH376_U8 CMD_CheckByte; // [R/W] CH376_CMD_CHECK_EXIST + CH376_U8 CMD_VAR32[4]; // [R/W] CH376_CMD_GET_FILE_SIZE, CH376_CMD_SET_FILE_SIZE }; #pragma pack() @@ -189,61 +201,61 @@ union CommandData struct ch376 { - CH376_CONTEXT context; + CH376_CONTEXT context; - CH376_U8 command; - CH376_U8 command_status; + CH376_U8 command; + CH376_U8 command_status; - CH376_U8 interface_status; - CH376_U8 usb_mode; + CH376_U8 interface_status; + CH376_U8 usb_mode; - union CommandData cmd_data; - CH376_U8 nb_bytes_in_cmd_data; - CH376_U8 pos_rw_in_cmd_data; + union CommandData cmd_data; + CH376_U8 nb_bytes_in_cmd_data; + CH376_U8 pos_rw_in_cmd_data; - CH376_U16 bytes_to_read_write; + CH376_U16 bytes_to_read_write; - CH376_LOCK root_dir_lock; - CH376_LOCK current_dir_lock; - CH376_FILE current_file; - CH376_DIR current_directory_browsing; + CH376_LOCK root_dir_lock; + CH376_LOCK current_dir_lock; + CH376_FILE current_file; + CH376_DIR current_directory_browsing; - CH376_BOOL current_file_is_directory; - char dir_pattern[14]; + CH376_BOOL current_file_is_directory; + char dir_pattern[14]; - char *sdcard_drive_path; - char *usb_drive_path; + char* sdcard_drive_path; + char* usb_drive_path; }; /* /// */ /* /// "CH376 private prototypes" */ -static char *clone_string(const char *string); +static char* clone_string(const char* string); static void clear_structure(struct ch376 *ch376); static void cancel_all_io(struct ch376 *ch376); static int normalize_char(char c); -static const char * normalize_file_name(const char *file_name, char *normalized_file_name); -static const char * trim_file_name(const char *file_name, char *trimmed_file_name); +static const char* normalize_file_name(const char* file_name, char* normalized_file_name); +static const char* trim_file_name(const char* file_name, char* trimmed_file_name); static void file_read_chunk(struct ch376 *ch376); static void file_write_chunk(struct ch376 *ch376); -static CH376_BOOL pattern_match(const char *pattern, const char *str); -static const char * normalize_pattern(const char *pattern, char *normalized_pattern); +static CH376_BOOL pattern_match(const char* pattern, const char* str); +static const char* normalize_pattern(const char* pattern, char* normalized_pattern); /* /// */ /* /// "Portable operating system-dependent prototypes" */ // Allocate "size" byte of memory -static void * system_alloc_mem(int size); +static void* system_alloc_mem(int size); // Free memory previously allocated with system_alloc_mem // It is safe to call it with NULL -static void system_free_mem(void *ptr); +static void system_free_mem(void* ptr); // Initialize the operating system dependent context // User data may be used if external data is required for such initialization -static CH376_BOOL system_init_context(CH376_CONTEXT *context, UNUSED void *user_data); +static CH376_BOOL system_init_context(CH376_CONTEXT *context, UNUSED void* user_data); // Release the operating system dependent context previously initialized by system_init_context static void system_clean_context(CH376_CONTEXT *context); @@ -253,9 +265,9 @@ static CH376_BOOL system_get_disk_info(CH376_CONTEXT *context, CH376_LOCK root_l // Try to lock the directory from the provided lock location and return an associated lock // Return 0 if a directory could not be locked (not a directory or not existing) -static CH376_LOCK system_obtain_directory_lock(CH376_CONTEXT *context, const char *dir_path, CH376_LOCK root_lock); +static CH376_LOCK system_obtain_directory_lock(CH376_CONTEXT *context, const char* dir_path, CH376_LOCK root_lock); -// Release a lock previouly obtained from system_obtain_directory_lock +// Release a lock previously obtained from system_obtain_directory_lock // It is safe to call it with a 0 static void system_release_directory_lock(CH376_CONTEXT *context, CH376_LOCK dir_lock); @@ -263,15 +275,15 @@ static void system_release_directory_lock(CH376_CONTEXT *context, CH376_LOCK dir static CH376_LOCK system_clone_directory_lock(CH376_CONTEXT *context, CH376_LOCK dir_lock); // Create a new directory -static CH376_LOCK system_create_directory(CH376_CONTEXT *context, const char *dir_path, CH376_LOCK root_lock); +static CH376_LOCK system_create_directory(CH376_CONTEXT *context, const char* dir_path, CH376_LOCK root_lock); // Return a file handle corresponding to the given file located in the provited directory lock // Return 0 if the file could not be found -static CH376_FILE system_file_open_existing(CH376_CONTEXT *context, const char *file_name, CH376_LOCK root_lock); +static CH376_FILE system_file_open_existing(CH376_CONTEXT *context, const char* file_name, CH376_LOCK root_lock); // Create a file in the provited directory lock and return its file handle // Return 0 if the file could not be created -static CH376_FILE system_file_open_new(CH376_CONTEXT *context, const char *file_name, CH376_LOCK root_lock); +static CH376_FILE system_file_open_new(CH376_CONTEXT *context, const char* file_name, CH376_LOCK root_lock); // Close a file opened with system_file_open_existing or system_file_open_new static void system_file_close(CH376_CONTEXT *context, CH376_FILE file); @@ -280,13 +292,13 @@ static void system_file_close(CH376_CONTEXT *context, CH376_FILE file); static CH376_S32 system_file_seek(CH376_CONTEXT *context, CH376_FILE file, int pos); // Read a part of a file -static CH376_S32 system_file_read(CH376_CONTEXT *context, CH376_FILE file, void *buffer, CH376_S32 size); +static CH376_S32 system_file_read(CH376_CONTEXT *context, CH376_FILE file, void* buffer, CH376_S32 size); // Write some data into a file -static CH376_S32 system_file_write(CH376_CONTEXT *context, CH376_FILE file, void *buffer, CH376_S32 size); +static CH376_S32 system_file_write(CH376_CONTEXT *context, CH376_FILE file, void* buffer, CH376_S32 size); // Delete a file -static CH376_BOOL system_file_delete(CH376_CONTEXT *context, const char *file_name, CH376_LOCK root_lock); +static CH376_BOOL system_file_delete(CH376_CONTEXT *context, const char* file_name, CH376_LOCK root_lock); // Delete a directory static CH376_BOOL system_directory_delete(CH376_CONTEXT *context, CH376_LOCK root_lock); @@ -296,7 +308,7 @@ static CH376_BOOL system_directory_delete(CH376_CONTEXT *context, CH376_LOCK roo static CH376_DIR system_start_examine_directory(CH376_CONTEXT *context, CH376_LOCK dir_lock); // Get the next entry from a directory on which a examine session was started using system_start_examine_directory -static CH376_BOOL system_go_examine_directory(CH376_CONTEXT *context, CH376_LOCK dir_lock, CH376_DIR fib, struct FatDirInfo *dir_info, char *pattern); +static CH376_BOOL system_go_examine_directory(CH376_CONTEXT *context, CH376_LOCK dir_lock, CH376_DIR fib, struct FatDirInfo *dir_info, char* pattern); // Finish a directory examine session (release all related resources) static void system_finish_examine_directory(CH376_CONTEXT *context, CH376_DIR fib); @@ -304,6 +316,9 @@ static void system_finish_examine_directory(CH376_CONTEXT *context, CH376_DIR fi // Get the size of the current file static CH376_S32 system_get_file_size(CH376_CONTEXT *context, CH376_FILE file); +// Get the offset position of the current file +static CH376_S32 system_get_file_offset(CH376_CONTEXT *context, CH376_FILE file); + /* /// */ #if defined(__MORPHOS__) || defined (__AMIGA__) || defined (__AROS__) @@ -317,17 +332,17 @@ static CH376_S32 system_get_file_size(CH376_CONTEXT *context, CH376_FILE file); #define dbg_printf(...) #endif -static void * system_alloc_mem(int size) +static void* system_alloc_mem(int size) { - return AllocVec(size, MEMF_ANY); + return AllocVec(size, MEMF_ANY); } -static void system_free_mem(void *ptr) +static void system_free_mem(void* ptr) { - FreeVec(ptr); + FreeVec(ptr); } -static CH376_BOOL system_init_context(CH376_CONTEXT *context, UNUSED void *user_data) +static CH376_BOOL system_init_context(CH376_CONTEXT *context, UNUSED void* user_data) { context->DOSBase = OpenLibrary(DOSNAME, 0L); return (context->DOSBase != NULL); @@ -341,328 +356,342 @@ static void system_clean_context(CH376_CONTEXT *context) static CH376_BOOL system_get_disk_info(CH376_CONTEXT *context, CH376_LOCK root_lock, struct DiskQuery *disk_info) { - struct Library *DOSBase = context->DOSBase; - BOOL got_info = CH376_FALSE; + struct Library *DOSBase = context->DOSBase; + BOOL got_info = CH376_FALSE; - if(disk_info) - { - struct InfoData *info = system_alloc_mem(sizeof(struct InfoData)); + if(disk_info) + { + struct InfoData *info = system_alloc_mem(sizeof(struct InfoData)); - if(info) - { - if(Info(root_lock, info) == DOSTRUE) - { - QUAD total_sector = (info->id_NumBlocks * info->id_BytesPerBlock) / 512; - QUAD free_sector = ((info->id_NumBlocks - info->id_NumBlocksUsed) * info->id_BytesPerBlock) / 512; + if(info) + { + if(Info(root_lock, info) == DOSTRUE) + { + QUAD total_sector = (info->id_NumBlocks * info->id_BytesPerBlock) / 512; + QUAD free_sector = ((info->id_NumBlocks - info->id_NumBlocksUsed) * info->id_BytesPerBlock) / 512; - disk_info->DISK_TotalSector[0] = (total_sector & 0x000000ff) >> 0; - disk_info->DISK_TotalSector[1] = (total_sector & 0x0000ff00) >> 8; - disk_info->DISK_TotalSector[2] = (total_sector & 0x00ff0000) >> 16; - disk_info->DISK_TotalSector[3] = (total_sector & 0xff000000) >> 24; + disk_info->DISK_TotalSector[0] = (total_sector & 0x000000ff) >> 0; + disk_info->DISK_TotalSector[1] = (total_sector & 0x0000ff00) >> 8; + disk_info->DISK_TotalSector[2] = (total_sector & 0x00ff0000) >> 16; + disk_info->DISK_TotalSector[3] = (total_sector & 0xff000000) >> 24; - disk_info->DISK_FreeSector[0] = (free_sector & 0x000000ff) >> 0; - disk_info->DISK_FreeSector[1] = (free_sector & 0x0000ff00) >> 8; - disk_info->DISK_FreeSector[2] = (free_sector & 0x00ff0000) >> 16; - disk_info->DISK_FreeSector[3] = (free_sector & 0xff000000) >> 24; + disk_info->DISK_FreeSector[0] = (free_sector & 0x000000ff) >> 0; + disk_info->DISK_FreeSector[1] = (free_sector & 0x0000ff00) >> 8; + disk_info->DISK_FreeSector[2] = (free_sector & 0x00ff0000) >> 16; + disk_info->DISK_FreeSector[3] = (free_sector & 0xff000000) >> 24; - disk_info->DISK_DiskFat = 0x0c; // FAT32? + disk_info->DISK_DiskFat = 0x0c; // FAT32? - got_info = TRUE; - } - system_free_mem(info); - } + got_info = TRUE; + } + system_free_mem(info); } + } - return got_info; + return got_info; } -static CH376_LOCK system_obtain_directory_lock(CH376_CONTEXT *context, const char *dir_path, CH376_LOCK root_lock) +static CH376_LOCK system_obtain_directory_lock(CH376_CONTEXT *context, const char* dir_path, CH376_LOCK root_lock) { - struct Library *DOSBase = context->DOSBase; - BPTR lock; - BPTR old_lock = (BPTR)0; + struct Library *DOSBase = context->DOSBase; + BPTR lock; + BPTR old_lock = (BPTR)0; - dbg_printf("system_obtain_directory_lock: %s\n", dir_path); - - if(root_lock) - { - old_lock = CurrentDir(root_lock); - } + dbg_printf("system_obtain_directory_lock: %s\n", dir_path); - lock = Lock(dir_path, SHARED_LOCK); + if(root_lock) + { + old_lock = CurrentDir(root_lock); + } - if(lock != (BPTR)0) - { - struct FileInfoBlock *fib = AllocDosObject(DOS_FIB, NULL); + lock = Lock(dir_path, SHARED_LOCK); - if(fib) - { - if(Examine(lock, fib) == DOSFALSE || fib->fib_DirEntryType < 0) - { - UnLock(lock); - lock = (BPTR)0; - } - FreeDosObject(DOS_FIB, fib); - } - } + if(lock != (BPTR)0) + { + struct FileInfoBlock *fib = AllocDosObject(DOS_FIB, NULL); - if(old_lock) + if(fib) { - CurrentDir(old_lock); + if(Examine(lock, fib) == DOSFALSE || fib->fib_DirEntryType < 0) + { + UnLock(lock); + lock = (BPTR)0; + } + FreeDosObject(DOS_FIB, fib); } + } + + if(old_lock) + { + CurrentDir(old_lock); + } - return lock; + return lock; } static void system_release_directory_lock(CH376_CONTEXT *context, CH376_LOCK dir_lock) { - struct Library *DOSBase = context->DOSBase; - UnLock(dir_lock); + struct Library *DOSBase = context->DOSBase; + UnLock(dir_lock); } static CH376_LOCK system_clone_directory_lock(CH376_CONTEXT *context, CH376_LOCK dir_lock) { - struct Library *DOSBase = context->DOSBase; - return DupLock(dir_lock); + struct Library *DOSBase = context->DOSBase; + return DupLock(dir_lock); } -static CH376_LOCK system_create_directory(CH376_CONTEXT *context, const char *dir_path, CH376_LOCK root_lock) +static CH376_LOCK system_create_directory(CH376_CONTEXT *context, const char* dir_path, CH376_LOCK root_lock) { - struct Library *DOSBase = context->DOSBase; - BPTR lock; - BPTR old_lock = (BPTR)0; + struct Library *DOSBase = context->DOSBase; + BPTR lock; + BPTR old_lock = (BPTR)0; - dbg_printf("system_create_directory: %s\n", dir_path); + dbg_printf("system_create_directory: %s\n", dir_path); - if(root_lock) - { - old_lock = CurrentDir(root_lock); - } + if(root_lock) + { + old_lock = CurrentDir(root_lock); + } - lock = CreateDir(dir_path); + lock = CreateDir(dir_path); - if(old_lock) - { - CurrentDir(old_lock); - } + if(old_lock) + { + CurrentDir(old_lock); + } - return lock; + return lock; } static BPTR file_open(CH376_CONTEXT *context, CONST_STRPTR file_name, BPTR root_lock, LONG mode) { - struct Library *DOSBase = context->DOSBase; - BPTR old_lock = (BPTR)0; - BPTR file; + struct Library *DOSBase = context->DOSBase; + BPTR old_lock = (BPTR)0; + BPTR file; - if(root_lock) - { - old_lock = CurrentDir(root_lock); - } + if(root_lock) + { + old_lock = CurrentDir(root_lock); + } - file = Open(file_name, mode); + file = Open(file_name, mode); - if(old_lock) - { - CurrentDir(old_lock); - } + if(old_lock) + { + CurrentDir(old_lock); + } - return file; + return file; } -static CH376_FILE system_file_open_existing(CH376_CONTEXT *context, const char *file_name, CH376_LOCK root_lock) +static CH376_FILE system_file_open_existing(CH376_CONTEXT *context, const char* file_name, CH376_LOCK root_lock) { - return file_open(context, file_name, root_lock, MODE_OLDFILE); + return file_open(context, file_name, root_lock, MODE_OLDFILE); } -static CH376_FILE system_file_open_new(CH376_CONTEXT *context, const char *file_name, CH376_LOCK root_lock) +static CH376_FILE system_file_open_new(CH376_CONTEXT *context, const char* file_name, CH376_LOCK root_lock) { - return file_open(context, file_name, root_lock, MODE_NEWFILE); + return file_open(context, file_name, root_lock, MODE_NEWFILE); } static void system_file_close(CH376_CONTEXT *context, CH376_FILE file) { - struct Library *DOSBase = context->DOSBase; - Close(file); + struct Library *DOSBase = context->DOSBase; + Close(file); } static CH376_S32 system_file_seek(CH376_CONTEXT *context, CH376_FILE file, int pos) { - struct Library *DOSBase = context->DOSBase; + struct Library *DOSBase = context->DOSBase; - dbg_printf("system_file_seek trying to seek to position %d\n", pos); + dbg_printf("system_file_seek trying to seek to position %d\n", pos); - if(file) - return Seek(file, pos, OFFSET_BEGINNING); - else - return -1; + if(file) + return Seek(file, pos, OFFSET_BEGINNING); + else + return -1; } -static CH376_S32 system_file_read(CH376_CONTEXT *context, CH376_FILE file, void *buffer, CH376_S32 size) +static CH376_S32 system_file_read(CH376_CONTEXT *context, CH376_FILE file, void* buffer, CH376_S32 size) { - struct Library *DOSBase = context->DOSBase; + struct Library *DOSBase = context->DOSBase; - dbg_printf("system_file_read trying to read %d bytes\n", size); + dbg_printf("system_file_read trying to read %d bytes\n", size); - if(file) - return Read(file, buffer, size); - else - return -1; + if(file) + return Read(file, buffer, size); + else + return -1; } -static CH376_S32 system_file_write(CH376_CONTEXT *context, CH376_FILE file, void *buffer, CH376_S32 size) +static CH376_S32 system_file_write(CH376_CONTEXT *context, CH376_FILE file, void* buffer, CH376_S32 size) { - struct Library *DOSBase = context->DOSBase; + struct Library *DOSBase = context->DOSBase; - dbg_printf("system_file_write trying to write %d bytes\n", size); + dbg_printf("system_file_write trying to write %d bytes\n", size); - if(file) - return Write(file, buffer, size); - else - return -1; + if(file) + return Write(file, buffer, size); + else + return -1; } -static CH376_BOOL system_file_delete(CH376_CONTEXT *context, const char *file_name, CH376_LOCK root_lock) +static CH376_BOOL system_file_delete(CH376_CONTEXT *context, const char* file_name, CH376_LOCK root_lock) { - struct Library *DOSBase = context->DOSBase; - BPTR old_lock = (BPTR)0; - LONG err; + struct Library *DOSBase = context->DOSBase; + BPTR old_lock = (BPTR)0; + LONG err; - if(root_lock) - { - old_lock = CurrentDir(root_lock); - } + if(root_lock) + { + old_lock = CurrentDir(root_lock); + } - err = DeleteFile(file_name); + err = DeleteFile(file_name); - if(old_lock) - { - CurrentDir(old_lock); - } + if(old_lock) + { + CurrentDir(old_lock); + } - return (err != 0); + return (err != 0); } static CH376_BOOL system_directory_delete(CH376_CONTEXT *context, CH376_LOCK root_lock) { - // FIXME - struct Library *DOSBase = context->DOSBase; + // FIXME + struct Library *DOSBase = context->DOSBase; - dbg_printf("system_directory_delete: %s\n", root_lock); + dbg_printf("system_directory_delete: %s\n", root_lock); - if(root_lock) - return (DeleteFile(root_lock) != 0); + if(root_lock) + return (DeleteFile(root_lock) != 0); - return CH376_FALSE; + return CH376_FALSE; } static CH376_DIR system_start_examine_directory(CH376_CONTEXT *context, CH376_LOCK dir_lock) { - struct Library *DOSBase = context->DOSBase; - struct FileInfoBlock *fib = AllocDosObject(DOS_FIB, NULL); + struct Library *DOSBase = context->DOSBase; + struct FileInfoBlock *fib = AllocDosObject(DOS_FIB, NULL); - if(fib) + if(fib) + { + if(Examine(dir_lock, fib) == DOSFALSE) { - if(Examine(dir_lock, fib) == DOSFALSE) - { - FreeDosObject(DOS_FIB, fib); - fib = NULL; - } + FreeDosObject(DOS_FIB, fib); + fib = NULL; + } + } + + return fib; +} + +static CH376_BOOL system_go_examine_directory(CH376_CONTEXT *context, CH376_LOCK dir_lock, CH376_DIR fib, struct FatDirInfo *dir_info, char* pattern) +{ + struct Library *DOSBase = context->DOSBase; + BOOL is_done = FALSE; + + if(fib) while(!is_done && ExNext(dir_lock, fib) == DOSTRUE) + { + if(normalize_file_name(fib->fib_FileName, dir_info->DIR_Name) && pattern_match(pattern, dir_info->DIR_Name)) + { + dir_info->DIR_Attr = 0; + + if(fib->fib_DirEntryType > 0) + dir_info->DIR_Attr |= DIR_ATTR_DIRECTORY; + if((fib->fib_Protection & FIBF_WRITE) != 0) + dir_info->DIR_Attr |= DIR_ATTR_READ_ONLY; + if((fib->fib_Protection & FIBF_ARCHIVE) == 0) + dir_info->DIR_Attr |= DIR_ATTR_ARCHIVE; + //if(fib->fib_Protection & FIBF_DELETE) + //if(fib->fib_Protection & FIBF_EXECUTE) + //if(fib->fib_Protection & FIBF_READ) + //if(fib->fib_Protection & FIBF_PURE) + //if(fib->fib_Protection & FIBF_SCRIPT) + dbg_printf("system_go_examine_directory defined file attributes: %d\n", dir_info->DIR_Attr); + + dir_info->DIR_NTRes = 0; + dir_info->DIR_CrtTimeTenth = 0; + dir_info->DIR_CrtTime[0] = 0; + dir_info->DIR_CrtTime[1] = 0; + dir_info->DIR_CrtDate[0] = 0; + dir_info->DIR_CrtDate[1] = 0; + dir_info->DIR_LstAccDate[0] = 0; + dir_info->DIR_LstAccDate[1] = 0; + dir_info->DIR_FstClusHI[0] = 0; + dir_info->DIR_FstClusHI[1] = 0; + dir_info->DIR_WrtTime[0] = 0; + dir_info->DIR_WrtTime[1] = 0; + dir_info->DIR_WrtDate[0] = 0; + dir_info->DIR_WrtDate[1] = 0; + dir_info->DIR_FstClusLO[0] = 0; + dir_info->DIR_FstClusLO[1] = 0; + dir_info->DIR_FileSize[0] = (fib->fib_Size & 0x000000ff) >> 0; + dir_info->DIR_FileSize[1] = (fib->fib_Size & 0x0000ff00) >> 8; + dir_info->DIR_FileSize[2] = (fib->fib_Size & 0x00ff0000) >> 16; + dir_info->DIR_FileSize[3] = (fib->fib_Size & 0xff000000) >> 24; + + is_done = TRUE; + } } - return fib; + return is_done; } -static CH376_BOOL system_go_examine_directory(CH376_CONTEXT *context, CH376_LOCK dir_lock, CH376_DIR fib, struct FatDirInfo *dir_info, char *pattern) +static void system_finish_examine_directory(CH376_CONTEXT *context, CH376_DIR fib) { - struct Library *DOSBase = context->DOSBase; - BOOL is_done = FALSE; - - if(fib) while(!is_done && ExNext(dir_lock, fib) == DOSTRUE) - { - if(normalize_file_name(fib->fib_FileName, dir_info->DIR_Name) && pattern_match(pattern, dir_info->DIR_Name)) - { - dir_info->DIR_Attr = 0; - - if(fib->fib_DirEntryType > 0) - dir_info->DIR_Attr |= DIR_ATTR_DIRECTORY; - if((fib->fib_Protection & FIBF_WRITE) != 0) - dir_info->DIR_Attr |= DIR_ATTR_READ_ONLY; - if((fib->fib_Protection & FIBF_ARCHIVE) == 0) - dir_info->DIR_Attr |= DIR_ATTR_ARCHIVE; - //if(fib->fib_Protection & FIBF_DELETE) - //if(fib->fib_Protection & FIBF_EXECUTE) - //if(fib->fib_Protection & FIBF_READ) - //if(fib->fib_Protection & FIBF_PURE) - //if(fib->fib_Protection & FIBF_SCRIPT) - dbg_printf("system_go_examine_directory defined file attributes: %d\n", dir_info->DIR_Attr); - - dir_info->DIR_NTRes = 0; - dir_info->DIR_CrtTimeTenth = 0; - dir_info->DIR_CrtTime[0] = 0; - dir_info->DIR_CrtTime[1] = 0; - dir_info->DIR_CrtDate[0] = 0; - dir_info->DIR_CrtDate[1] = 0; - dir_info->DIR_LstAccDate[0] = 0; - dir_info->DIR_LstAccDate[1] = 0; - dir_info->DIR_FstClusHI[0] = 0; - dir_info->DIR_FstClusHI[1] = 0; - dir_info->DIR_WrtTime[0] = 0; - dir_info->DIR_WrtTime[1] = 0; - dir_info->DIR_WrtDate[0] = 0; - dir_info->DIR_WrtDate[1] = 0; - dir_info->DIR_FstClusLO[0] = 0; - dir_info->DIR_FstClusLO[1] = 0; - dir_info->DIR_FileSize[0] = (fib->fib_Size & 0x000000ff) >> 0; - dir_info->DIR_FileSize[1] = (fib->fib_Size & 0x0000ff00) >> 8; - dir_info->DIR_FileSize[2] = (fib->fib_Size & 0x00ff0000) >> 16; - dir_info->DIR_FileSize[3] = (fib->fib_Size & 0xff000000) >> 24; - - is_done = TRUE; - } - } + struct Library *DOSBase = context->DOSBase; - return is_done; + if(fib) + { + FreeDosObject(DOS_FIB, fib); + } } -static void system_finish_examine_directory(CH376_CONTEXT *context, CH376_DIR fib) +static CH376_S32 system_get_file_size(CH376_CONTEXT *context, CH376_FILE file) { - struct Library *DOSBase = context->DOSBase; + struct Library *DOSBase = context->DOSBase; + struct FileInfoBlock *fib = AllocDosObject(DOS_FIB, NULL); + CH376_S32 file_size = 0xffffffff; - if(fib) + if(fib) + { + if(file) + { + if(ExamineFH(file, &fib)) + { + file_size = fib->fib_Size; + } + else + { + dbg_printf("system_get_file_size: error\n"); + } + } + else { - FreeDosObject(DOS_FIB, fib); + dbg_printf("system_get_file_size: no file handle\n"); } + + FreeDosObject(DOS_FIB, fib); + } + + return file_size; } -static CH376_S32 system_get_file_size(CH376_CONTEXT *context, CH376_FILE file) +static CH376_S32 system_get_file_offset(CH376_CONTEXT *context, CH376_FILE file) { - struct Library *DOSBase = context->DOSBase; - struct FileInfoBlock *fib = AllocDosObject(DOS_FIB, NULL); - CH376_S32 file_size = 0xffffffff; + CH376_S32 file_offset = 0xffffffff; - if (fib) - { - if (file) - { - if ( ExamineFH(file, &fib) ) - { - file_size = fib->fib_Size; - } - else - { - dbg_printf("system_get_file_size: error\n"); - } - } - else - { - dbg_printf("system_get_file_size: no file handle\n"); - } - - FreeDosObject(DOS_FIB, fib); - } + if(file) + { + dbg_printf("system_get_file_offset: unsupported error\n"); + } + else + dbg_printf("system_get_file_offset: no file handle\n"); - return file_size; + return file_offset; } /* /// */ @@ -674,346 +703,360 @@ static CH376_S32 system_get_file_size(CH376_CONTEXT *context, CH376_FILE file) #ifdef DEBUG_CH376 static void dbg_printf(LPCTSTR str, ...) { - TCHAR buffer[256]; + TCHAR buffer[256]; - va_list args; - va_start(args, str); - _vsnprintf_s(buffer, sizeof(buffer) - 1, sizeof(buffer) - 1, str, args); - OutputDebugString(buffer); - va_end(args); + va_list args; + va_start(args, str); + _vsnprintf_s(buffer, sizeof(buffer) - 1, sizeof(buffer) - 1, str, args); + OutputDebugString(buffer); + va_end(args); } #else #define dbg_printf(...) #endif -static void * system_alloc_mem(int size) +static void* system_alloc_mem(int size) { - return GlobalAlloc(GMEM_FIXED, size); + return GlobalAlloc(GMEM_FIXED, size); } -static void system_free_mem(void *ptr) +static void system_free_mem(void* ptr) { - GlobalFree(ptr); + GlobalFree(ptr); } -static CH376_BOOL system_init_context(CH376_CONTEXT *context, UNUSED void *user_data) +static CH376_BOOL system_init_context(CH376_CONTEXT *context, UNUSED void* user_data) { - // Nothing to do? - return CH376_TRUE; + // Nothing to do? + return CH376_TRUE; }; static void system_clean_context(CH376_CONTEXT *context) { - // Nothing to do? + // Nothing to do? } static CH376_BOOL system_get_disk_info(CH376_CONTEXT *context, CH376_LOCK root_lock, struct DiskQuery *disk_info) { - BOOL got_info = FALSE; - char volume[4]; - DWORD sectors_per_cluster; - DWORD bytes_per_sector; - DWORD number_of_free_clusters; - DWORD total_number_of_clusters; + BOOL got_info = FALSE; + char volume[4]; + DWORD sectors_per_cluster; + DWORD bytes_per_sector; + DWORD number_of_free_clusters; + DWORD total_number_of_clusters; - //@iss volume[0] = (char)(PathGetDriveNumber(root_lock->path) + 'A'); - volume[0] = ((char*)root_lock->path)[0] & 0xdf; - volume[1] = ':'; - volume[2] = '\\'; - volume[3] = '\0'; + //@iss volume[0] = (char)(PathGetDriveNumber(root_lock->path) + 'A'); + volume[0] = ((char*)root_lock->path)[0] & 0xdf; + volume[1] = ':'; + volume[2] = '\\'; + volume[3] = '\0'; - if(GetDiskFreeSpace(volume, §ors_per_cluster, &bytes_per_sector, &number_of_free_clusters, &total_number_of_clusters)) - { - INT64 total_sector = (total_number_of_clusters * sectors_per_cluster * bytes_per_sector) / 512; - INT64 free_sector = (number_of_free_clusters * sectors_per_cluster * bytes_per_sector) / 512; + if(GetDiskFreeSpace(volume, §ors_per_cluster, &bytes_per_sector, &number_of_free_clusters, &total_number_of_clusters)) + { + INT64 total_sector = (total_number_of_clusters * sectors_per_cluster * bytes_per_sector) / 512; + INT64 free_sector = (number_of_free_clusters * sectors_per_cluster * bytes_per_sector) / 512; - disk_info->DISK_TotalSector[0] = (INT8)((total_sector & 0x000000ff) >> 0); - disk_info->DISK_TotalSector[1] = (INT8)((total_sector & 0x0000ff00) >> 8); - disk_info->DISK_TotalSector[2] = (INT8)((total_sector & 0x00ff0000) >> 16); - disk_info->DISK_TotalSector[3] = (INT8)((total_sector & 0xff000000) >> 24); + disk_info->DISK_TotalSector[0] = (INT8)((total_sector & 0x000000ff) >> 0); + disk_info->DISK_TotalSector[1] = (INT8)((total_sector & 0x0000ff00) >> 8); + disk_info->DISK_TotalSector[2] = (INT8)((total_sector & 0x00ff0000) >> 16); + disk_info->DISK_TotalSector[3] = (INT8)((total_sector & 0xff000000) >> 24); - disk_info->DISK_FreeSector[0] = (INT8)((free_sector & 0x000000ff) >> 0); - disk_info->DISK_FreeSector[1] = (INT8)((free_sector & 0x0000ff00) >> 8); - disk_info->DISK_FreeSector[2] = (INT8)((free_sector & 0x00ff0000) >> 16); - disk_info->DISK_FreeSector[3] = (INT8)((free_sector & 0xff000000) >> 24); + disk_info->DISK_FreeSector[0] = (INT8)((free_sector & 0x000000ff) >> 0); + disk_info->DISK_FreeSector[1] = (INT8)((free_sector & 0x0000ff00) >> 8); + disk_info->DISK_FreeSector[2] = (INT8)((free_sector & 0x00ff0000) >> 16); + disk_info->DISK_FreeSector[3] = (INT8)((free_sector & 0xff000000) >> 24); - disk_info->DISK_DiskFat = 0x0c; // FAT32? + disk_info->DISK_DiskFat = 0x0c; // FAT32? - got_info = TRUE; - } - return got_info; + got_info = TRUE; + } + return got_info; } -static CH376_LOCK system_obtain_directory_lock(CH376_CONTEXT *context, const char *dir_path, CH376_LOCK root_lock) +static CH376_LOCK system_obtain_directory_lock(CH376_CONTEXT *context, const char* dir_path, CH376_LOCK root_lock) { - CH376_LOCK lock = NULL; - TCHAR old_dir[MAX_PATH]; - struct stat s; + CH376_LOCK lock = NULL; + TCHAR old_dir[MAX_PATH]; + struct stat s; - if(root_lock) - { - GetCurrentDirectory(sizeof(old_dir), old_dir); - SetCurrentDirectory(root_lock->path); - }; + if(root_lock) + { + GetCurrentDirectory(sizeof(old_dir), old_dir); + SetCurrentDirectory(root_lock->path); + }; - //@iss PathIsDirectory(dir_path) - if(stat(dir_path,&s) == 0 && s.st_mode & S_IFDIR) - { - lock = (CH376_LOCK)system_alloc_mem(sizeof(struct _CH376_LOCK )); - GetFullPathName(dir_path, MAX_PATH, lock->path, NULL); - lock->handle = INVALID_HANDLE_VALUE; - } + //@iss PathIsDirectory(dir_path) + if(stat(dir_path, &s) == 0 && s.st_mode & S_IFDIR) + { + lock = (CH376_LOCK)system_alloc_mem(sizeof(struct _CH376_LOCK)); + GetFullPathName(dir_path, MAX_PATH, lock->path, NULL); + lock->handle = INVALID_HANDLE_VALUE; + } - if(root_lock) - { - SetCurrentDirectory(old_dir); - }; + if(root_lock) + { + SetCurrentDirectory(old_dir); + }; - return lock; + return lock; } static void system_release_directory_lock(CH376_CONTEXT *context, CH376_LOCK dir_lock) { - if(dir_lock != (CH376_LOCK)0) - { - system_free_mem(dir_lock); - } + if(dir_lock != (CH376_LOCK)0) + { + system_free_mem(dir_lock); + } } static CH376_LOCK system_clone_directory_lock(CH376_CONTEXT *context, CH376_LOCK dir_lock) { - CH376_LOCK dup_lock = (CH376_LOCK)system_alloc_mem(sizeof(struct _CH376_LOCK)); + CH376_LOCK dup_lock = (CH376_LOCK)system_alloc_mem(sizeof(struct _CH376_LOCK)); - CopyMemory(dup_lock, dir_lock, sizeof(struct _CH376_LOCK)); + CopyMemory(dup_lock, dir_lock, sizeof(struct _CH376_LOCK)); - return dup_lock; + return dup_lock; } -static HANDLE file_open(CH376_CONTEXT *context, const char *file_name, PCHAR root_path, DWORD creation_disposition) +static HANDLE file_open(CH376_CONTEXT *context, const char* file_name, PCHAR root_path, DWORD creation_disposition) { - TCHAR old_dir[MAX_PATH]; - HANDLE file; + TCHAR old_dir[MAX_PATH]; + HANDLE file; - if(root_path) - { - GetCurrentDirectory(sizeof(old_dir), old_dir); - SetCurrentDirectory(root_path); - } + if(root_path) + { + GetCurrentDirectory(sizeof(old_dir), old_dir); + SetCurrentDirectory(root_path); + } - file = CreateFile(file_name, GENERIC_READ | GENERIC_WRITE, 0, NULL, creation_disposition, FILE_ATTRIBUTE_NORMAL, NULL); + file = CreateFile(file_name, GENERIC_READ | GENERIC_WRITE, 0, NULL, creation_disposition, FILE_ATTRIBUTE_NORMAL, NULL); - if(root_path) - { - SetCurrentDirectory(old_dir); - } + if(root_path) + { + SetCurrentDirectory(old_dir); + } - if(file != INVALID_HANDLE_VALUE) - return file; - else - return NULL; + if(file != INVALID_HANDLE_VALUE) + return file; + else + return NULL; } -static CH376_BOOL system_file_delete(CH376_CONTEXT *context, const char *file_name, CH376_LOCK root_lock) +static CH376_BOOL system_file_delete(CH376_CONTEXT *context, const char* file_name, CH376_LOCK root_lock) { - LONG err; - TCHAR old_dir[MAX_PATH]; + LONG err; + TCHAR old_dir[MAX_PATH]; - if (root_lock) - { - GetCurrentDirectory(sizeof(old_dir), old_dir); - SetCurrentDirectory(root_lock->path); - }; + if(root_lock) + { + GetCurrentDirectory(sizeof(old_dir), old_dir); + SetCurrentDirectory(root_lock->path); + }; - dbg_printf("system_file_delete: %s\n", file_name); + dbg_printf("system_file_delete: %s\n", file_name); - err = DeleteFile(file_name); + err = DeleteFile(file_name); - if (root_lock) - { - SetCurrentDirectory(old_dir); - }; + if(root_lock) + { + SetCurrentDirectory(old_dir); + }; - return (err != 0); + return (err != 0); } static CH376_BOOL system_directory_delete(CH376_CONTEXT *context, CH376_LOCK root_lock) { - dbg_printf("system_directory_delete: %s\n", root_lock); + dbg_printf("system_directory_delete: %s\n", root_lock); - if (root_lock) - return (RemoveDirectory((LPCSTR)root_lock) != 0); + if(root_lock) + return (RemoveDirectory((LPCSTR)root_lock) != 0); - return CH376_FALSE; + return CH376_FALSE; } -static CH376_LOCK system_create_directory(CH376_CONTEXT *context, const char *dir_path, CH376_LOCK root_lock) +static CH376_LOCK system_create_directory(CH376_CONTEXT *context, const char* dir_path, CH376_LOCK root_lock) { - TCHAR old_dir[MAX_PATH]; - CH376_LOCK lock = NULL; + TCHAR old_dir[MAX_PATH]; + CH376_LOCK lock = NULL; - if (root_lock) - { - GetCurrentDirectory(sizeof(old_dir), old_dir); - SetCurrentDirectory(root_lock->path); - }; + if(root_lock) + { + GetCurrentDirectory(sizeof(old_dir), old_dir); + SetCurrentDirectory(root_lock->path); + }; - dbg_printf("system_create_directory: %s\n", dir_path); + dbg_printf("system_create_directory: %s\n", dir_path); - if (CreateDirectory(dir_path, NULL)) - { - lock = (CH376_LOCK)system_alloc_mem(sizeof(struct _CH376_LOCK )); - SetCurrentDirectory(dir_path); - GetCurrentDirectory(sizeof(lock->path), lock->path); - lock->handle = INVALID_HANDLE_VALUE; - } + if(CreateDirectory(dir_path, NULL)) + { + lock = (CH376_LOCK)system_alloc_mem(sizeof(struct _CH376_LOCK)); + SetCurrentDirectory(dir_path); + GetCurrentDirectory(sizeof(lock->path), lock->path); + lock->handle = INVALID_HANDLE_VALUE; + } - if (root_lock) - { - SetCurrentDirectory(old_dir); - }; + if(root_lock) + { + SetCurrentDirectory(old_dir); + }; - return lock; + return lock; } -static CH376_FILE system_file_open_existing(CH376_CONTEXT *context, const char *file_name, CH376_LOCK root_lock) +static CH376_FILE system_file_open_existing(CH376_CONTEXT *context, const char* file_name, CH376_LOCK root_lock) { - return file_open(context, file_name, root_lock->path, OPEN_EXISTING); + return file_open(context, file_name, root_lock->path, OPEN_EXISTING); } -static CH376_FILE system_file_open_new(CH376_CONTEXT *context, const char *file_name, CH376_LOCK root_lock) +static CH376_FILE system_file_open_new(CH376_CONTEXT *context, const char* file_name, CH376_LOCK root_lock) { - return file_open(context, file_name, root_lock->path, CREATE_ALWAYS); + return file_open(context, file_name, root_lock->path, CREATE_ALWAYS); } static void system_file_close(CH376_CONTEXT *context, CH376_FILE file) { - if(file) CloseHandle(file); + if(file) CloseHandle(file); } static CH376_S32 system_file_seek(CH376_CONTEXT *context, CH376_FILE file, int pos) { - if(file != NULL) - return SetFilePointer(file, pos, NULL, FILE_BEGIN); - else - return -1; + if(file != NULL) + return SetFilePointer(file, pos, NULL, FILE_BEGIN); + else + return -1; } -static CH376_S32 system_file_read(CH376_CONTEXT *context, CH376_FILE file, void *buffer, CH376_S32 size) +static CH376_S32 system_file_read(CH376_CONTEXT *context, CH376_FILE file, void* buffer, CH376_S32 size) { - DWORD read_bytes; + DWORD read_bytes; - if(ReadFile(file, buffer, size, &read_bytes, NULL)) - return read_bytes; - else - return -1; + if(ReadFile(file, buffer, size, &read_bytes, NULL)) + return read_bytes; + else + return -1; } -static CH376_S32 system_file_write(CH376_CONTEXT *context, CH376_FILE file, void *buffer, CH376_S32 size) +static CH376_S32 system_file_write(CH376_CONTEXT *context, CH376_FILE file, void* buffer, CH376_S32 size) { - DWORD written_bytes; + DWORD written_bytes; - if(WriteFile(file, buffer, size, &written_bytes, NULL)) - return written_bytes; - else - return -1; + if(WriteFile(file, buffer, size, &written_bytes, NULL)) + return written_bytes; + else + return -1; } static CH376_DIR system_start_examine_directory(CH376_CONTEXT *context, CH376_LOCK dir_lock) { - LPWIN32_FIND_DATA find_file_data = (LPWIN32_FIND_DATA)system_alloc_mem(sizeof(WIN32_FIND_DATA)); - TCHAR szDir[MAX_PATH]; - StringCchCopy(szDir, MAX_PATH, dir_lock->path); - StringCchCat(szDir, MAX_PATH, TEXT("\\*")); + LPWIN32_FIND_DATA find_file_data = (LPWIN32_FIND_DATA)system_alloc_mem(sizeof(WIN32_FIND_DATA)); + TCHAR szDir[MAX_PATH]; + StringCchCopy(szDir, MAX_PATH, dir_lock->path); + StringCchCat(szDir, MAX_PATH, TEXT("\\*")); - dir_lock->handle = FindFirstFile(szDir, find_file_data); + dir_lock->handle = FindFirstFile(szDir, find_file_data); - if(dir_lock->handle == INVALID_HANDLE_VALUE) - { - system_free_mem(find_file_data); - find_file_data = NULL; - } + if(dir_lock->handle == INVALID_HANDLE_VALUE) + { + system_free_mem(find_file_data); + find_file_data = NULL; + } - return find_file_data; + return find_file_data; } -static CH376_BOOL system_go_examine_directory(CH376_CONTEXT *context, CH376_LOCK dir_lock, CH376_DIR fib, struct FatDirInfo *dir_info, char *pattern) +static CH376_BOOL system_go_examine_directory(CH376_CONTEXT *context, CH376_LOCK dir_lock, CH376_DIR fib, struct FatDirInfo *dir_info, char* pattern) { - BOOL is_done = FALSE; + BOOL is_done = FALSE; - if(dir_lock->handle != INVALID_HANDLE_VALUE) - { - while(!is_done && FindNextFile(dir_lock->handle, fib)) - { - if(normalize_file_name(fib->cFileName, dir_info->DIR_Name) && pattern_match(pattern, dir_info->DIR_Name)) - { - // Storing attributes :) - dir_info->DIR_Attr = (UINT8)fib->dwFileAttributes; - - dbg_printf("system_go_examine_directory defined file attributes: %d\n", dir_info->DIR_Attr); - - dir_info->DIR_NTRes = 0; - dir_info->DIR_CrtTimeTenth = 0; - dir_info->DIR_CrtTime[0] = 0; - dir_info->DIR_CrtTime[1] = 0; - dir_info->DIR_CrtDate[0] = 0; - dir_info->DIR_CrtDate[1] = 0; - dir_info->DIR_LstAccDate[0] = 0; - dir_info->DIR_LstAccDate[1] = 0; - dir_info->DIR_FstClusHI[0] = 0; - dir_info->DIR_FstClusHI[1] = 0; - dir_info->DIR_WrtTime[0] = 0; - dir_info->DIR_WrtTime[1] = 0; - dir_info->DIR_WrtDate[0] = 0; - dir_info->DIR_WrtDate[1] = 0; - dir_info->DIR_FstClusLO[0] = 0; - dir_info->DIR_FstClusLO[1] = 0; - dir_info->DIR_FileSize[0] = (UINT8)((fib->nFileSizeLow & 0x000000ff) >> 0); - dir_info->DIR_FileSize[1] = (UINT8)((fib->nFileSizeLow & 0x0000ff00) >> 8); - dir_info->DIR_FileSize[2] = (UINT8)((fib->nFileSizeLow & 0x00ff0000) >> 16); - dir_info->DIR_FileSize[3] = (UINT8)((fib->nFileSizeLow & 0xff000000) >> 24); - - is_done = TRUE; - } - } + if(dir_lock->handle != INVALID_HANDLE_VALUE) + { + while(!is_done && FindNextFile(dir_lock->handle, fib)) + { + if(normalize_file_name(fib->cFileName, dir_info->DIR_Name) && pattern_match(pattern, dir_info->DIR_Name)) + { + // Storing attributes :) + dir_info->DIR_Attr = (UINT8)fib->dwFileAttributes; + + dbg_printf("system_go_examine_directory defined file attributes: %d\n", dir_info->DIR_Attr); + + dir_info->DIR_NTRes = 0; + dir_info->DIR_CrtTimeTenth = 0; + dir_info->DIR_CrtTime[0] = 0; + dir_info->DIR_CrtTime[1] = 0; + dir_info->DIR_CrtDate[0] = 0; + dir_info->DIR_CrtDate[1] = 0; + dir_info->DIR_LstAccDate[0] = 0; + dir_info->DIR_LstAccDate[1] = 0; + dir_info->DIR_FstClusHI[0] = 0; + dir_info->DIR_FstClusHI[1] = 0; + dir_info->DIR_WrtTime[0] = 0; + dir_info->DIR_WrtTime[1] = 0; + dir_info->DIR_WrtDate[0] = 0; + dir_info->DIR_WrtDate[1] = 0; + dir_info->DIR_FstClusLO[0] = 0; + dir_info->DIR_FstClusLO[1] = 0; + dir_info->DIR_FileSize[0] = (UINT8)((fib->nFileSizeLow & 0x000000ff) >> 0); + dir_info->DIR_FileSize[1] = (UINT8)((fib->nFileSizeLow & 0x0000ff00) >> 8); + dir_info->DIR_FileSize[2] = (UINT8)((fib->nFileSizeLow & 0x00ff0000) >> 16); + dir_info->DIR_FileSize[3] = (UINT8)((fib->nFileSizeLow & 0xff000000) >> 24); + + is_done = TRUE; + } } + } - return is_done; + return is_done; } static void system_finish_examine_directory(CH376_CONTEXT *context, CH376_DIR fib) { - if(fib) - { - FindClose(fib); - system_free_mem(fib); - } + if(fib) + { + FindClose(fib); + system_free_mem(fib); + } } static CH376_S32 system_get_file_size(CH376_CONTEXT *context, CH376_FILE file) { - CH376_S32 file_size = 0xffffffff; - BY_HANDLE_FILE_INFORMATION file_stat; + CH376_S32 file_size = 0xffffffff; + BY_HANDLE_FILE_INFORMATION file_stat; - if (file) + if(file) + { + if(GetFileInformationByHandle(file, &file_stat)) { - if ( GetFileInformationByHandle(file, &file_stat) ) - { - // Only low DWORD - file_size = file_stat.nFileSizeLow; - } - else - { - dbg_printf("system_get_file_size: error\n"); - } + // Only low DWORD + file_size = file_stat.nFileSizeLow; } else - dbg_printf("system_get_file_size: no file handle\n"); + { + dbg_printf("system_get_file_size: error\n"); + } + } + else + dbg_printf("system_get_file_size: no file handle\n"); + + return file_size; +} + +static CH376_S32 system_get_file_offset(CH376_CONTEXT *context, CH376_FILE file) +{ + CH376_S32 file_offset = 0xffffffff; + + if(file) + { + dbg_printf("system_get_file_offset: unsupported error\n"); + } + else + dbg_printf("system_get_file_offset: no file handle\n"); - return file_size; + return file_offset; } /* /// */ @@ -1028,21 +1071,21 @@ static CH376_S32 system_get_file_size(CH376_CONTEXT *context, CH376_FILE file) #define dbg_printf(...) #endif -static void * system_alloc_mem(int size) +static void* system_alloc_mem(int size) { - return malloc(size); + return malloc(size); } -static void system_free_mem(void *ptr) +static void system_free_mem(void* ptr) { - if (ptr) - free(ptr); + if(ptr) + free(ptr); } -static CH376_BOOL system_init_context(CH376_CONTEXT *context, UNUSED void *user_data) +static CH376_BOOL system_init_context(CH376_CONTEXT *context, UNUSED void* user_data) { /* Nothing to do */ - return CH376_TRUE; + return CH376_TRUE; } static void system_clean_context(CH376_CONTEXT *context) @@ -1052,320 +1095,395 @@ static void system_clean_context(CH376_CONTEXT *context) static CH376_BOOL system_get_disk_info(CH376_CONTEXT *context, CH376_LOCK root_lock, struct DiskQuery *disk_info) { - CH376_BOOL got_info = CH376_FALSE; + CH376_BOOL got_info = CH376_FALSE; - if(disk_info) - { - struct statvfs stats; + if(disk_info) + { + struct statvfs stats; - if(statvfs(root_lock, &stats) == 0) - { - int64_t total_sector = (stats.f_blocks * stats.f_bsize) / 512; - int64_t free_sector = (stats.f_bfree * stats.f_bsize) / 512; + if(statvfs(root_lock, &stats) == 0) + { + int64_t total_sector = (stats.f_blocks * stats.f_bsize) / 512; + int64_t free_sector = (stats.f_bfree * stats.f_bsize) / 512; - disk_info->DISK_TotalSector[0] = (total_sector & 0x000000ff) >> 0; - disk_info->DISK_TotalSector[1] = (total_sector & 0x0000ff00) >> 8; - disk_info->DISK_TotalSector[2] = (total_sector & 0x00ff0000) >> 16; - disk_info->DISK_TotalSector[3] = (total_sector & 0xff000000) >> 24; + disk_info->DISK_TotalSector[0] = (total_sector & 0x000000ff) >> 0; + disk_info->DISK_TotalSector[1] = (total_sector & 0x0000ff00) >> 8; + disk_info->DISK_TotalSector[2] = (total_sector & 0x00ff0000) >> 16; + disk_info->DISK_TotalSector[3] = (total_sector & 0xff000000) >> 24; - disk_info->DISK_FreeSector[0] = (free_sector & 0x000000ff) >> 0; - disk_info->DISK_FreeSector[1] = (free_sector & 0x0000ff00) >> 8; - disk_info->DISK_FreeSector[2] = (free_sector & 0x00ff0000) >> 16; - disk_info->DISK_FreeSector[3] = (free_sector & 0xff000000) >> 24; + disk_info->DISK_FreeSector[0] = (free_sector & 0x000000ff) >> 0; + disk_info->DISK_FreeSector[1] = (free_sector & 0x0000ff00) >> 8; + disk_info->DISK_FreeSector[2] = (free_sector & 0x00ff0000) >> 16; + disk_info->DISK_FreeSector[3] = (free_sector & 0xff000000) >> 24; - disk_info->DISK_DiskFat = 0x0c; // FAT32? + disk_info->DISK_DiskFat = 0x0c; // FAT32? - got_info = CH376_TRUE; - } + got_info = CH376_TRUE; } + } - return got_info; + return got_info; } -static CH376_LOCK system_obtain_directory_lock(CH376_CONTEXT *context, const char *dir_path, CH376_LOCK root_lock) +static CH376_LOCK system_obtain_directory_lock(CH376_CONTEXT *context, const char* dir_path, CH376_LOCK root_lock) { - CH376_LOCK lock = NULL; - char *old_dir = NULL; - struct stat path_stat; + CH376_LOCK lock = NULL; + char* old_dir = NULL; + struct stat path_stat; - dbg_printf("system_obtain_directory_lock: %s\n", dir_path); + dbg_printf("system_obtain_directory_lock: %s\n", dir_path); - if(root_lock) - { - if((old_dir = getcwd(NULL, 0)) != NULL) - chdir(root_lock); - } + if(root_lock) + { + if((old_dir = getcwd(NULL, 0)) != NULL) + chdir(root_lock); + } - stat(dir_path, &path_stat); - if(S_ISDIR(path_stat.st_mode)) - { - lock = realpath(dir_path, NULL); - } + stat(dir_path, &path_stat); + if(S_ISDIR(path_stat.st_mode)) + { + lock = realpath(dir_path, NULL); + } - if(old_dir) + if(old_dir) + { + if(old_dir != NULL) { - if(old_dir != NULL) - { - chdir(old_dir); - system_free_mem(old_dir); - } + chdir(old_dir); + system_free_mem(old_dir); } + } - return lock; + return lock; } static void system_release_directory_lock(CH376_CONTEXT *context, CH376_LOCK dir_lock) { - if(dir_lock != (CH376_LOCK)0) - { - system_free_mem(dir_lock); - } + if(dir_lock != (CH376_LOCK)0) + { + system_free_mem(dir_lock); + } } static CH376_LOCK system_clone_directory_lock(CH376_CONTEXT *context, CH376_LOCK dir_lock) { - return strdup(dir_lock); + return strdup(dir_lock); } -static FILE * file_open(const char *file_name, CH376_LOCK root_lock, const char *mode) +static FILE * file_open(const char* file_name, CH376_LOCK root_lock, const char* mode) { - FILE *file; - char *old_dir = NULL; - // FIXME: unused variable - //struct stat path_stat; + FILE *file; + char* old_dir = NULL; + // FIXME: unused variable + //struct stat path_stat; - if(root_lock) - { - if((old_dir = getcwd(NULL, 0)) != NULL) - chdir(root_lock); - } + if(root_lock) + { + if((old_dir = getcwd(NULL, 0)) != NULL) + chdir(root_lock); + } - file = fopen(file_name, mode); + file = fopen(file_name, mode); - if(old_dir) - { - chdir(old_dir); - system_free_mem(old_dir); - } + if(old_dir) + { + chdir(old_dir); + system_free_mem(old_dir); + } - return file; + return file; } -static CH376_BOOL system_file_delete(CH376_CONTEXT *context, const char *file_name, CH376_LOCK root_lock) +static CH376_BOOL system_file_delete(CH376_CONTEXT *context, const char* file_name, CH376_LOCK root_lock) { - int err; - char *old_dir = NULL; + int err; + char* old_dir = NULL; - if(root_lock) - { - if((old_dir = getcwd(NULL, 0)) != NULL) - chdir(root_lock); - } + if(root_lock) + { + if((old_dir = getcwd(NULL, 0)) != NULL) + chdir(root_lock); + } - err = remove(file_name); + err = remove(file_name); - dbg_printf("system_file_delete: %s\n", file_name); + dbg_printf("system_file_delete: %s\n", file_name); - if(old_dir) + if(old_dir) + { + if(old_dir != NULL) { - if(old_dir != NULL) - { - chdir(old_dir); - system_free_mem(old_dir); - } + chdir(old_dir); + system_free_mem(old_dir); } + } - return (err == 0); + return (err == 0); } static CH376_BOOL system_directory_delete(CH376_CONTEXT *context, CH376_LOCK root_lock) { - dbg_printf("system_directory_delete: %s\n", root_lock); + dbg_printf("system_directory_delete: %s\n", root_lock); - if (root_lock) - return (rmdir(root_lock) == 0); - else - return CH376_FALSE; + if(root_lock) + return (rmdir(root_lock) == 0); + else + return CH376_FALSE; } -static CH376_LOCK system_create_directory(CH376_CONTEXT *context, const char *dir_path, CH376_LOCK root_lock) +static CH376_LOCK system_create_directory(CH376_CONTEXT *context, const char* dir_path, CH376_LOCK root_lock) { - CH376_LOCK lock = NULL; - char *old_dir = NULL; + CH376_LOCK lock = NULL; + char* old_dir = NULL; - if(root_lock) - { - if((old_dir = getcwd(NULL, 0)) != NULL) - chdir(root_lock); - } + if(root_lock) + { + if((old_dir = getcwd(NULL, 0)) != NULL) + chdir(root_lock); + } - dbg_printf("system_create_directory: %s\n", dir_path); + dbg_printf("system_create_directory: %s\n", dir_path); - if (!mkdir(dir_path, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)) - lock = realpath(dir_path, NULL); + if(!mkdir(dir_path, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)) + lock = realpath(dir_path, NULL); - if(old_dir) - { - chdir(old_dir); - system_free_mem(old_dir); - } + if(old_dir) + { + chdir(old_dir); + system_free_mem(old_dir); + } - return lock; + return lock; } -static CH376_FILE system_file_open_existing(CH376_CONTEXT *context, const char *file_name, CH376_LOCK root_lock) +static CH376_FILE system_file_open_existing(CH376_CONTEXT *context, const char* file_name, CH376_LOCK root_lock) { - FILE *fp; + FILE *fp; - fp = file_open(file_name, root_lock, "rb+"); + fp = file_open(file_name, root_lock, "rb+"); - return fp; + return fp; } -static CH376_FILE system_file_open_new(CH376_CONTEXT *context, const char *file_name, CH376_LOCK root_lock) +static CH376_FILE system_file_open_new(CH376_CONTEXT *context, const char* file_name, CH376_LOCK root_lock) { - return file_open(file_name, root_lock, "wb+"); + return file_open(file_name, root_lock, "wb+"); } static void system_file_close(CH376_CONTEXT *context, CH376_FILE file) { - if (file) fclose(file); + if(file) fclose(file); } static CH376_S32 system_file_seek(CH376_CONTEXT *context, CH376_FILE file, int pos) { - dbg_printf("system_file_seek trying to seek to position %d\n", pos); + dbg_printf("system_file_seek trying to seek to position %d\n", pos); - if(file) - if (!fseek(file, pos, SEEK_SET)) - return ftell(file); -// else - return -1; + if(file) + if(!fseek(file, pos, SEEK_SET)) + return ftell(file); + // else + return -1; } -static CH376_S32 system_file_read(CH376_CONTEXT *context, CH376_FILE file, void *buffer, CH376_S32 size) +static CH376_S32 system_file_read(CH376_CONTEXT *context, CH376_FILE file, void* buffer, CH376_S32 size) { - dbg_printf("system_file_read trying to read %d bytes\n", size); + dbg_printf("system_file_read trying to read %d bytes\n", size); - if(file) - return fread(buffer, 1, size, file); - else - return -1; + if(file) + return fread(buffer, 1, size, file); + else + return -1; } -static CH376_S32 system_file_write(CH376_CONTEXT *context, CH376_FILE file, void *buffer, CH376_S32 size) +static CH376_S32 system_file_write(CH376_CONTEXT *context, CH376_FILE file, void* buffer, CH376_S32 size) { - dbg_printf("system_file_write trying to write %d bytes\n", size); + dbg_printf("system_file_write trying to write %d bytes\n", size); - if(file) - return fwrite(buffer, 1, size, file); - else - return -1; + if(file) + return fwrite(buffer, 1, size, file); + else + return -1; } static CH376_DIR system_start_examine_directory(CH376_CONTEXT *context, CH376_LOCK dir_lock) { - CH376_DIR fib = system_alloc_mem(sizeof(struct _CH376_DIR)); + CH376_DIR fib = system_alloc_mem(sizeof(struct _CH376_DIR)); - if(fib) - { - fib->handle = opendir(dir_lock); - fib->entry = NULL; - } + if(fib) + { + fib->handle = opendir(dir_lock); + fib->entry = NULL; + } - return fib; + return fib; } -static CH376_BOOL system_go_examine_directory(CH376_CONTEXT *context, CH376_LOCK dir_lock, CH376_DIR fib, struct FatDirInfo *dir_info, char *pattern) +static CH376_BOOL system_go_examine_directory(CH376_CONTEXT *context, CH376_LOCK dir_lock, CH376_DIR fib, struct FatDirInfo *dir_info, char* pattern) { - CH376_BOOL is_done = CH376_FALSE; - struct stat file_stat; - char *old_dir = NULL; + CH376_BOOL is_done = CH376_FALSE; + struct stat file_stat; + struct tm *timeinfo; + CH376_U16 dos_cdate, dos_ctime; + CH376_U16 dos_adate; + CH376_U16 dos_mdate, dos_mtime; + char* old_dir = NULL; - if(dir_lock) - { - if((old_dir = getcwd(NULL, 0)) != NULL) - chdir(dir_lock); - } + if(dir_lock) + { + if((old_dir = getcwd(NULL, 0)) != NULL) + chdir(dir_lock); + } - if(fib) while(!is_done && (fib->entry = readdir(fib->handle))) + if(fib) while(!is_done && (fib->entry = readdir(fib->handle))) { - if(normalize_file_name(fib->entry->d_name, dir_info->DIR_Name) && pattern_match(pattern, dir_info->DIR_Name)) + if(normalize_file_name(fib->entry->d_name, dir_info->DIR_Name) && pattern_match(pattern, dir_info->DIR_Name)) + { + stat(fib->entry->d_name, &file_stat); + + dir_info->DIR_Attr = 0; + + if(S_ISDIR(file_stat.st_mode)) + dir_info->DIR_Attr |= DIR_ATTR_DIRECTORY; + if((file_stat.st_mode & S_IWUSR) == 0) { - stat(fib->entry->d_name, &file_stat); - - dir_info->DIR_Attr = 0; - - if(S_ISDIR(file_stat.st_mode)) - dir_info->DIR_Attr |= DIR_ATTR_DIRECTORY; - if((file_stat.st_mode & S_IRUSR) == 0) - dir_info->DIR_Attr |= DIR_ATTR_READ_ONLY; - - dbg_printf("system_go_examine_directory defined file attributes: %d\n", dir_info->DIR_Attr); - - dir_info->DIR_NTRes = 0; - dir_info->DIR_CrtTimeTenth = 0; - dir_info->DIR_CrtTime[0] = 0; - dir_info->DIR_CrtTime[1] = 0; - dir_info->DIR_CrtDate[0] = 0; - dir_info->DIR_CrtDate[1] = 0; - dir_info->DIR_LstAccDate[0] = 0; - dir_info->DIR_LstAccDate[1] = 0; - dir_info->DIR_FstClusHI[0] = 0; - dir_info->DIR_FstClusHI[1] = 0; - dir_info->DIR_WrtTime[0] = 0; - dir_info->DIR_WrtTime[1] = 0; - dir_info->DIR_WrtDate[0] = 0; - dir_info->DIR_WrtDate[1] = 0; - dir_info->DIR_FstClusLO[0] = 0; - dir_info->DIR_FstClusLO[1] = 0; - dir_info->DIR_FileSize[0] = (file_stat.st_size & 0x000000ff) >> 0; - dir_info->DIR_FileSize[1] = (file_stat.st_size & 0x0000ff00) >> 8; - dir_info->DIR_FileSize[2] = (file_stat.st_size & 0x00ff0000) >> 16; - dir_info->DIR_FileSize[3] = (file_stat.st_size & 0xff000000) >> 24; - - is_done = CH376_TRUE; + dir_info->DIR_Attr |= DIR_ATTR_READ_ONLY; + dbg_printf("--- READ ONLY ---"); } - } - if(old_dir) - { - chdir(old_dir); - system_free_mem(old_dir); + // FIXME: begin-of-implemented for Linux and Windows +#if defined(__linux__) || defined(WIN32) + + dbg_printf("system_go_examine_directory defined file attributes: %04o -> %02x\n", file_stat.st_mode, dir_info->DIR_Attr); + if(file_stat.st_ctim.tv_sec == 0) + { + dos_cdate = 0; + dos_ctime = 0; + } + else + { + timeinfo = localtime(&(file_stat.st_ctim.tv_sec)); + dos_cdate = DIR_MAKE_FILE_DATE((timeinfo->tm_year + 1900), (timeinfo->tm_mon + 1), timeinfo->tm_mday); + dos_ctime = DIR_MAKE_FILE_TIME(timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec); + dbg_printf("system_go_examine_directory defined file cdate/time: %s", asctime(timeinfo)); + } + + if(file_stat.st_atim.tv_sec == 0) + { + dos_adate = 0; + } + else + { + timeinfo = localtime(&(file_stat.st_atim.tv_sec)); + dos_adate = DIR_MAKE_FILE_DATE((timeinfo->tm_year + 1900), (timeinfo->tm_mon + 1), timeinfo->tm_mday); + dbg_printf("system_go_examine_directory defined file adate/time: %s", asctime(timeinfo)); + } + + if(file_stat.st_mtim.tv_sec == 0) + { + dos_mdate = 0; + dos_mtime = 0; + } + else + { + timeinfo = localtime(&(file_stat.st_mtim.tv_sec)); + dos_mdate = DIR_MAKE_FILE_DATE((timeinfo->tm_year + 1900), (timeinfo->tm_mon + 1), timeinfo->tm_mday); + dos_mtime = DIR_MAKE_FILE_TIME(timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec); + dbg_printf("system_go_examine_directory defined file mdate/time: %s", asctime(timeinfo)); + } +#else + // silence compiler warnings + timeinfo = 0; + dos_ctime = 0; + dos_cdate = 0; + dos_mtime = 0; + dos_mdate = 0; + dos_adate = 0; +#endif + // FIXME: end-of-implemented for Linux and Windows + + dir_info->DIR_NTRes = 0; + dir_info->DIR_CrtTimeTenth = 0; + dir_info->DIR_CrtTime[0] = (dos_ctime & 0x00ff); + dir_info->DIR_CrtTime[1] = (dos_ctime >> 8); + dir_info->DIR_CrtDate[0] = (dos_cdate & 0x00ff); + dir_info->DIR_CrtDate[1] = (dos_cdate >> 8); + dir_info->DIR_LstAccDate[0] = (dos_adate & 0x00ff); + dir_info->DIR_LstAccDate[1] = (dos_adate >> 8); + dir_info->DIR_FstClusHI[0] = 0; + dir_info->DIR_FstClusHI[1] = 0; + dir_info->DIR_WrtTime[0] = (dos_mtime & 0x00ff); + dir_info->DIR_WrtTime[1] = (dos_mtime >> 8); + dir_info->DIR_WrtDate[0] = (dos_mdate & 0x00ff); + dir_info->DIR_WrtDate[1] = (dos_mdate >> 8); + dir_info->DIR_FstClusLO[0] = 0; + dir_info->DIR_FstClusLO[1] = 0; + dir_info->DIR_FileSize[0] = (file_stat.st_size & 0x000000ff) >> 0; + dir_info->DIR_FileSize[1] = (file_stat.st_size & 0x0000ff00) >> 8; + dir_info->DIR_FileSize[2] = (file_stat.st_size & 0x00ff0000) >> 16; + dir_info->DIR_FileSize[3] = (file_stat.st_size & 0xff000000) >> 24; + + is_done = CH376_TRUE; + } } - return is_done; + if(old_dir) + { + chdir(old_dir); + system_free_mem(old_dir); + } + + return is_done; } static void system_finish_examine_directory(CH376_CONTEXT *context, CH376_DIR fib) { - if (fib) - { - closedir(fib->handle); - system_free_mem(fib); - } + if(fib) + { + closedir(fib->handle); + system_free_mem(fib); + } } static CH376_S32 system_get_file_size(CH376_CONTEXT *context, CH376_FILE file) { - CH376_S32 file_size = 0xffffffff; - struct stat file_stat; + CH376_S32 file_size = 0xffffffff; + struct stat file_stat; - if (file) + if(file) + { + if(!fstat(fileno(file), &file_stat)) { - if ( !fstat(fileno(file), &file_stat) ) - { - file_size = file_stat.st_size; - } - else - { - dbg_printf("system_get_file_size: error\n"); - } + file_size = file_stat.st_size; } else - dbg_printf("system_get_file_size: no file handle\n"); + { + dbg_printf("system_get_file_size: error\n"); + } + } + else + dbg_printf("system_get_file_size: no file handle\n"); + + return file_size; +} + +static CH376_S32 system_get_file_offset(CH376_CONTEXT *context, CH376_FILE file) +{ + CH376_S32 file_offset = 0xffffffff; - return file_size; + if(file) + { + file_offset = ftell(file); + + if(file_offset == -1) + { + dbg_printf("system_get_file_offset: error\n"); + } + } + else + dbg_printf("system_get_file_offset: no file handle\n"); + + return file_offset; } /* /// */ @@ -1376,324 +1494,333 @@ static CH376_S32 system_get_file_size(CH376_CONTEXT *context, CH376_FILE file) /* /// "CH376 private subroutines" */ -static char *clone_string(const char *string) +static char* clone_string(const char* string) { - int l; - char *s; - - for(l=0; string[l]!='\0'; l++); - - s = system_alloc_mem(l); - - for(l=0; string[l]!='\0'; l++) - s[l] = string[l]; + // int l; + // char *s; + // + // for(l=0; string[l]!='\0'; l++); + // + // s = system_alloc_mem(l); + // + // for(l=0; string[l]!='\0'; l++) + // s[l] = string[l]; + // + // s[l] = '\0'; - s[l] = '\0'; + // return s; - return s; + return strdup(string); } static void clear_structure(struct ch376 *ch376) { - ch376->command = CH376_CMD_NONE; - ch376->command_status = 0; - ch376->interface_status = 0; - ch376->nb_bytes_in_cmd_data = 0; - ch376->pos_rw_in_cmd_data = 0; - ch376->usb_mode = CH376_ARG_SET_USB_MODE_INVALID; - ch376->bytes_to_read_write = 0; - ch376->root_dir_lock = (CH376_LOCK)0; - ch376->current_dir_lock = (CH376_LOCK)0; - ch376->current_file = (CH376_FILE)0; - ch376->current_directory_browsing = (CH376_DIR)0; + ch376->command = CH376_CMD_NONE; + ch376->command_status = 0; + ch376->interface_status = 0; + ch376->nb_bytes_in_cmd_data = 0; + ch376->pos_rw_in_cmd_data = 0; + ch376->usb_mode = CH376_ARG_SET_USB_MODE_INVALID; + ch376->bytes_to_read_write = 0; + ch376->root_dir_lock = (CH376_LOCK)0; + ch376->current_dir_lock = (CH376_LOCK)0; + ch376->current_file = (CH376_FILE)0; + ch376->current_directory_browsing = (CH376_DIR)0; } static void cancel_all_io(struct ch376 *ch376) { - // Cancel data buffer read/write sessions - ch376->bytes_to_read_write = 0; + // Cancel data buffer read/write sessions + ch376->bytes_to_read_write = 0; - // End directory browing or file i/o sessions - system_finish_examine_directory(&ch376->context, ch376->current_directory_browsing); - ch376->current_directory_browsing = (CH376_DIR)0; - system_file_close(&ch376->context, ch376->current_file); - ch376->current_file = (CH376_FILE)0; + // End directory browsing or file i/o sessions + system_finish_examine_directory(&ch376->context, ch376->current_directory_browsing); + ch376->current_directory_browsing = (CH376_DIR)0; + system_file_close(&ch376->context, ch376->current_file); + ch376->current_file = (CH376_FILE)0; - // Release potential already obtained lock for root and current - system_release_directory_lock(&ch376->context, ch376->root_dir_lock); - ch376->root_dir_lock = (CH376_LOCK)0; - system_release_directory_lock(&ch376->context, ch376->current_dir_lock); - ch376->current_dir_lock = (CH376_LOCK)0; + // Release potential already obtained lock for root and current + system_release_directory_lock(&ch376->context, ch376->root_dir_lock); + ch376->root_dir_lock = (CH376_LOCK)0; + system_release_directory_lock(&ch376->context, ch376->current_dir_lock); + ch376->current_dir_lock = (CH376_LOCK)0; } // Normalize a char (capitalized and ASCII) // Return -1 if not possible static int normalize_char(char c) { - if(c > 127) - return -1; + if(c > 127) + return -1; - if(c >='a' && c <='z') - return c - ('a' - 'A'); + if(c >='a' && c <='z') + return c - ('a' - 'A'); - return c; + return c; } // Normalized a dos filename in 8.3 format // Return NULL if not possible -static const char * normalize_file_name(const char *file_name, char *normalized_file_name) +static const char* normalize_file_name(const char* file_name, char* normalized_file_name) { - int i = 0; - int j = 0; - int c; + int i = 0; + int j = 0; + int c; - dbg_printf("normalize_file_name: %s\n", file_name); + dbg_printf("normalize_file_name: %s\n", file_name); - while(file_name[i] != '\0' && file_name[i] != '.' && j < 8) - { - c = normalize_char(file_name[i++]); + // '.' or '..' + if(file_name[0] == '.') + { + if((file_name[1] == '\0') || (file_name[1] == '.' && file_name[2] == '\0')) + return NULL; + } - if(c == -1) - return NULL; - else - normalized_file_name[j++] = (char)c; - } + while(file_name[i] != '\0' && file_name[i] != '.' && j < 8) + { + c = normalize_char(file_name[i++]); - if(file_name[i] == '\0') - { - for(; j<8; j++) - { - normalized_file_name[j] = ' '; - } - } - else if(file_name[i] == '.') + if(c == -1) + return NULL; + else + normalized_file_name[j++] = (char)c; + } + + if(file_name[i] == '\0') + { + for(; j<8; j++) { - i++; - for(; j<8; j++) - { - normalized_file_name[j] = ' '; - } + normalized_file_name[j] = ' '; } - else + } + else if(file_name[i] == '.') + { + i++; + for(; j<8; j++) { - dbg_printf("normalize_file_name impossible: %s (%d=%c,%d=%c)\n", file_name, i, file_name[i], j, normalized_file_name[j]); - return NULL; + normalized_file_name[j] = ' '; } + } + else + { + dbg_printf("normalize_file_name impossible: %s (%d=%c,%d=%c)\n", file_name, i, file_name[i], j, normalized_file_name[j]); + return NULL; + } - while(file_name[i] != '\0' && file_name[i] != '.' && j < 11) - { - c = normalize_char(file_name[i++]); + while(file_name[i] != '\0' && file_name[i] != '.' && j < 11) + { + c = normalize_char(file_name[i++]); - if(c == -1) - return NULL; - else - normalized_file_name[j++] = (char)c; - } + if(c == -1) + return NULL; + else + normalized_file_name[j++] = (char)c; + } - if(file_name[i] != '\0') - { - dbg_printf("normalize_file_name impossible: %s (%d=%c,%d=%c)\n", file_name, i, file_name[i], j, normalized_file_name[j]); - return NULL; - } + if(file_name[i] != '\0') + { + dbg_printf("normalize_file_name impossible: %s (%d=%c,%d=%c)\n", file_name, i, file_name[i], j, normalized_file_name[j]); + return NULL; + } - dbg_printf("normalize_file_name done: %s (%d=&%02x,%d=&%02x)\n", file_name, i, file_name[i], j, normalized_file_name[j]); + dbg_printf("normalize_file_name done: %s (%d=&%02x,%d=&%02x)\n", file_name, i, file_name[i], j, normalized_file_name[j]); - for(; j<11; j++) - { - normalized_file_name[j] = ' '; - } + for(; j<11; j++) + { + normalized_file_name[j] = ' '; + } - normalized_file_name[j] = '\0'; + normalized_file_name[j] = '\0'; - return normalized_file_name; + return normalized_file_name; } // Convert normalized 8.3 filename into regular filename // (remove trailing spaces in name and extension, and clear extension trailing '.' if any) -static const char * trim_file_name(const char *file_name, char *trimmed_file_name) +static const char* trim_file_name(const char* file_name, char* trimmed_file_name) { - int i = 0; - int j = 0; + int i = 0; + int j = 0; - while(file_name[i] != ' ' && file_name[i] != '\0') - trimmed_file_name[j++] = file_name[i++]; + while(file_name[i] != ' ' && file_name[i] != '\0') + trimmed_file_name[j++] = file_name[i++]; - while(file_name[i] == ' ') - i++; + while(file_name[i] == ' ') + i++; - while(file_name[i] != ' ' && file_name[i] != '\0') - trimmed_file_name[j++] = file_name[i++]; + while(file_name[i] != ' ' && file_name[i] != '\0') + trimmed_file_name[j++] = file_name[i++]; - if(j > 0 && trimmed_file_name[j-1] == '.') - j--; + if(j > 0 && trimmed_file_name[j-1] == '.') + j--; - trimmed_file_name[j] = '\0'; + trimmed_file_name[j] = '\0'; - dbg_printf("trim_file_name from \"%s\" to \"%s\"\n", file_name, trimmed_file_name); + dbg_printf("trim_file_name from \"%s\" to \"%s\"\n", file_name, trimmed_file_name); - return trimmed_file_name; + return trimmed_file_name; } static void file_read_chunk(struct ch376 *ch376) { - CH376_S32 bytes_to_read_now; - CH376_S32 bytes_actually_read; - - if(ch376->bytes_to_read_write > sizeof(ch376->cmd_data.CMD_IOBuffer)) - bytes_to_read_now = sizeof(ch376->cmd_data.CMD_IOBuffer); - else - bytes_to_read_now = ch376->bytes_to_read_write; + CH376_S32 bytes_to_read_now; + CH376_S32 bytes_actually_read; - bytes_actually_read = system_file_read(&ch376->context, ch376->current_file, &ch376->cmd_data.CMD_IOBuffer, bytes_to_read_now); + if(ch376->bytes_to_read_write > sizeof(ch376->cmd_data.CMD_IOBuffer)) + bytes_to_read_now = sizeof(ch376->cmd_data.CMD_IOBuffer); + else + bytes_to_read_now = ch376->bytes_to_read_write; - if(bytes_actually_read >= 0) - { - ch376->bytes_to_read_write -= (CH376_U16)bytes_actually_read; + bytes_actually_read = system_file_read(&ch376->context, ch376->current_file, &ch376->cmd_data.CMD_IOBuffer, bytes_to_read_now); - ch376->nb_bytes_in_cmd_data = (CH376_U8)bytes_actually_read; - ch376->interface_status = 127; - // CH376 specification tells that the last buffer is returned with INT_SUCCESS - // but it is not the case (at least with revision 4). An empty buffer is always - // returned with INT_SUCCESS. As a consequence some routines do not read the last - // buffer when INT_SUCCESS is returned. It is not correct regarding CH376 - // specification, but to keep compatibility with these (wrong) routines, - // we also always return an empty buffer with INT_SUCCESS by checking - // bytes_actually_read == 0 instead of bytes_actually_read < bytes_to_read_now - if(bytes_to_read_now == 0 || bytes_actually_read == 0) - { - dbg_printf("[WRITE][DATA][CH376_CMD_BYTE_READ] all done: read operated with success (no more data)\n"); - ch376->command_status = CH376_INT_SUCCESS; - } - else - { - dbg_printf("[WRITE][DATA][CH376_CMD_BYTE_READ] all done: read operated with success (waiting data read for %d bytes out of %d)\n", ch376->nb_bytes_in_cmd_data, ch376->bytes_to_read_write); - ch376->command_status = CH376_INT_DISK_READ; - } + if(bytes_actually_read >= 0) + { + ch376->bytes_to_read_write -= (CH376_U16)bytes_actually_read; + + ch376->nb_bytes_in_cmd_data = (CH376_U8)bytes_actually_read; + ch376->interface_status = 127; + // CH376 specification tells that the last buffer is returned with INT_SUCCESS + // but it is not the case (at least with revision 4). An empty buffer is always + // returned with INT_SUCCESS. As a consequence some routines do not read the last + // buffer when INT_SUCCESS is returned. It is not correct regarding CH376 + // specification, but to keep compatibility with these (wrong) routines, + // we also always return an empty buffer with INT_SUCCESS by checking + // bytes_actually_read == 0 instead of bytes_actually_read < bytes_to_read_now + if(bytes_to_read_now == 0 || bytes_actually_read == 0) + { + dbg_printf("[WRITE][DATA][CH376_CMD_BYTE_READ] all done: read operated with success (no more data)\n"); + ch376->command_status = CH376_INT_SUCCESS; } else { - dbg_printf("[WRITE][DATA][CH376_CMD_BYTE_READ] aborted: read failure\n"); - - ch376->nb_bytes_in_cmd_data = 0; - ch376->interface_status = 0; - ch376->command_status = CH376_RET_ABORT; + dbg_printf("[WRITE][DATA][CH376_CMD_BYTE_READ] all done: read operated with success (waiting data read for %d bytes out of %d)\n", ch376->nb_bytes_in_cmd_data, ch376->bytes_to_read_write); + ch376->command_status = CH376_INT_DISK_READ; } + } + else + { + dbg_printf("[WRITE][DATA][CH376_CMD_BYTE_READ] aborted: read failure\n"); + + ch376->nb_bytes_in_cmd_data = 0; + ch376->interface_status = 0; + ch376->command_status = CH376_RET_ABORT; + } } static void file_write_chunk(struct ch376 *ch376) { - CH376_S32 bytes_to_write_now; - CH376_S32 bytes_actually_written; - - bytes_to_write_now = ch376->nb_bytes_in_cmd_data; + CH376_S32 bytes_to_write_now; + CH376_S32 bytes_actually_written; - bytes_actually_written = system_file_write(&ch376->context, ch376->current_file, &ch376->cmd_data.CMD_IOBuffer, bytes_to_write_now); + bytes_to_write_now = ch376->nb_bytes_in_cmd_data; - if(bytes_actually_written == bytes_to_write_now) - { - ch376->bytes_to_read_write -= (CH376_U16)bytes_actually_written; + bytes_actually_written = system_file_write(&ch376->context, ch376->current_file, &ch376->cmd_data.CMD_IOBuffer, bytes_to_write_now); - ch376->nb_bytes_in_cmd_data = 0; - ch376->interface_status = 127; - if(ch376->bytes_to_read_write == 0) - { - dbg_printf("[WRITE][DATA][CH376_CMD_BYTE_WRITE] all done: write operated with success (no more data)\n"); - ch376->command_status = CH376_INT_SUCCESS; - } - else - { - if(ch376->bytes_to_read_write > sizeof(ch376->cmd_data.CMD_IOBuffer)) - ch376->nb_bytes_in_cmd_data = sizeof(ch376->cmd_data.CMD_IOBuffer); - else - ch376->nb_bytes_in_cmd_data = (CH376_U8)ch376->bytes_to_read_write; + if(bytes_actually_written == bytes_to_write_now) + { + ch376->bytes_to_read_write -= (CH376_U16)bytes_actually_written; - dbg_printf("[WRITE][DATA][CH376_CMD_BYTE_WRITE] all done: write operated with success (waiting data write for %d bytes out of %d)\n", ch376->nb_bytes_in_cmd_data, ch376->bytes_to_read_write); - ch376->command_status = CH376_INT_DISK_WRITE; - } + ch376->nb_bytes_in_cmd_data = 0; + ch376->interface_status = 127; + if(ch376->bytes_to_read_write == 0) + { + dbg_printf("[WRITE][DATA][CH376_CMD_BYTE_WRITE] all done: write operated with success (no more data)\n"); + ch376->command_status = CH376_INT_SUCCESS; } else { - dbg_printf("[WRITE][DATA][CH376_CMD_BYTE_WRITE] aborted: write failure\n"); + if(ch376->bytes_to_read_write > sizeof(ch376->cmd_data.CMD_IOBuffer)) + ch376->nb_bytes_in_cmd_data = sizeof(ch376->cmd_data.CMD_IOBuffer); + else + ch376->nb_bytes_in_cmd_data = (CH376_U8)ch376->bytes_to_read_write; - ch376->nb_bytes_in_cmd_data = 0; - ch376->interface_status = 0; - ch376->command_status = CH376_RET_ABORT; + dbg_printf("[WRITE][DATA][CH376_CMD_BYTE_WRITE] all done: write operated with success (waiting data write for %d bytes out of %d)\n", ch376->nb_bytes_in_cmd_data, ch376->bytes_to_read_write); + ch376->command_status = CH376_INT_DISK_WRITE; } + } + else + { + dbg_printf("[WRITE][DATA][CH376_CMD_BYTE_WRITE] aborted: write failure\n"); + + ch376->nb_bytes_in_cmd_data = 0; + ch376->interface_status = 0; + ch376->command_status = CH376_RET_ABORT; + } } // Normalize file pattern (use normalize_file_name()) -static const char * normalize_pattern(const char *pattern, char *normalized_pattern) +static const char* normalize_pattern(const char* pattern, char* normalized_pattern) { - int i = -1; + int i = -1; - dbg_printf("normalize_pattern: '%s'\n", normalized_pattern); + dbg_printf("normalize_pattern: '%s'\n", normalized_pattern); - if (!strcmp(pattern, "*")) - { - dbg_printf("normalize_pattern: * -> *.*\n"); - normalize_file_name("*.*", normalized_pattern); - } - else if (!normalize_file_name(pattern, normalized_pattern)) - { - dbg_printf("normalize_pattern: error\n"); - normalized_pattern[0] = '\0'; // if used, pattern_match() will always return FALSE - return NULL; - } + if(!strcmp(pattern, "*")) + { + dbg_printf("normalize_pattern: * -> *.*\n"); + normalize_file_name("*.*", normalized_pattern); + } + else if(!normalize_file_name(pattern, normalized_pattern)) + { + dbg_printf("normalize_pattern: error\n"); + normalized_pattern[0] = '\0'; // if used, pattern_match() will always return FALSE + return NULL; + } - while (i<11) + while(i<11) + { + i++; + if(normalized_pattern[i] == '*') { - i++; - if (normalized_pattern[i] == '*') - { - // We can't use '?' as wildcard character because ch376 can't use '?' as meta character - // Unlike DOS: Here '*' means any character up to end of filename including extension part - while (i < 11) - normalized_pattern[i++]='*'; - } + // We can't use '?' as wildcard character because ch376 can't use '?' as meta character + // Unlike DOS: Here '*' means any character up to end of filename including extension part + while(i < 11) + normalized_pattern[i++]='*'; } + } - dbg_printf("normalize_pattern: '%s' (i=%d)\n", normalized_pattern, i); + dbg_printf("normalize_pattern: '%s' (i=%d)\n", normalized_pattern, i); - return normalized_pattern; + return normalized_pattern; } // Check file_name against pattern // file_name and pattern must be normalized before calling the function -static CH376_BOOL pattern_match(const char *pattern, const char * file_name) +static CH376_BOOL pattern_match(const char* pattern, const char* file_name) { - CH376_BOOL found = CH376_FALSE; - int i=0; + CH376_BOOL found = CH376_FALSE; + int i=0; - dbg_printf("pattern_match('%s', '%s') => ", pattern, file_name); + dbg_printf("pattern_match('%s', '%s') => ", pattern, file_name); - while(1) + while(1) + { + if(pattern[i] != '*') { - if (pattern[i] != '*') - { - if (pattern[i] != file_name[i]) - { - found = CH376_FALSE; - break; - } - if (pattern[i] == '\0') - { - found = CH376_TRUE; - break; - } - } - else - { - if (file_name[i] == '\0') - { - found = CH376_TRUE; - break; - } - } - i++; + if(pattern[i] != file_name[i]) + { + found = CH376_FALSE; + break; + } + if(pattern[i] == '\0') + { + found = CH376_TRUE; + break; + } + } + else + { + if(file_name[i] == '\0') + { + found = CH376_TRUE; + break; + } } + i++; + } - dbg_printf("i=%d, found=%d\n", i, found); - return found; + dbg_printf("i=%d, found=%d\n", i, found); + return found; } /* /// */ @@ -1702,8 +1829,8 @@ static CH376_BOOL pattern_match(const char *pattern, const char * file_name) CH376_U8 ch376_read_command_port(struct ch376 *ch376) { - dbg_printf("[READ][COMMAND] during command &%02x status &%02x\n", ch376->command, ch376->command_status); - return ch376->interface_status; + dbg_printf("[READ][COMMAND] during command &%02x status &%02x\n", ch376->command, ch376->command_status); + return ch376->interface_status; } /* /// */ @@ -1712,112 +1839,112 @@ CH376_U8 ch376_read_command_port(struct ch376 *ch376) CH376_U8 ch376_read_data_port(struct ch376 *ch376) { - CH376_U8 data_out = 0xff; // Hi-Z + CH376_U8 data_out = 0xff; // Hi-Z - dbg_printf(">> [READ][DATA] for during command &%02x status &%02x\n", ch376->command, ch376->command_status); + dbg_printf(">> [READ][DATA] for during command &%02x status &%02x\n", ch376->command, ch376->command_status); - switch(ch376->command) - { + switch(ch376->command) + { case CH376_CMD_CHECK_EXIST: - data_out = ch376->cmd_data.CMD_CheckByte; - dbg_printf("[READ][DATA][CH376_CMD_CHECK_EXIST] setting data port to &%02x\n", data_out); - break; - - case CH376_CMD_GET_FILE_SIZE: - if(ch376->nb_bytes_in_cmd_data) + data_out = ch376->cmd_data.CMD_CheckByte; + dbg_printf("[READ][DATA][CH376_CMD_CHECK_EXIST] setting data port to &%02x\n", data_out); + break; + + case CH376_CMD_READ_VAR32: + if(ch376->nb_bytes_in_cmd_data) + { + if(ch376->nb_bytes_in_cmd_data != ch376->pos_rw_in_cmd_data) { - if(ch376->nb_bytes_in_cmd_data != ch376->pos_rw_in_cmd_data) - { - data_out = ch376->cmd_data.CMD_FileSize[ch376->pos_rw_in_cmd_data]; + data_out = ch376->cmd_data.CMD_VAR32[ch376->pos_rw_in_cmd_data]; - dbg_printf("[READ][DATA][CH376_CMD_GET_FILE_SIZE] read &%02x from i/o buffer at position &%02x\n", data_out, ch376->pos_rw_in_cmd_data); + dbg_printf("[READ][DATA][CH376_CMD_READ_VAR32] read &%02x from i/o buffer at position &%02x\n", data_out, ch376->pos_rw_in_cmd_data); - if(++ch376->pos_rw_in_cmd_data == ch376->nb_bytes_in_cmd_data) - ch376->nb_bytes_in_cmd_data = 0; - } - } - else - { - data_out = 0; - dbg_printf("[READ][DATA][CH376_CMD_GET_FILE_SIZE] nothing to read from i/o buffer\n"); + if(++ch376->pos_rw_in_cmd_data == ch376->nb_bytes_in_cmd_data) + ch376->nb_bytes_in_cmd_data = 0; } + } + else + { + data_out = 0; + dbg_printf("[READ][DATA][CH376_CMD_READ_VAR32] nothing to read from i/o buffer\n"); + } - break; + break; case CH376_CMD_GET_IC_VER: - data_out = (0x40 | CH376_DATA_IC_VER) & 0x7f; - dbg_printf("[READ][DATA][CH376_CMD_GET_IC_VER] setting data port to &%02x\n", data_out); - break; + data_out = (0x40 | CH376_DATA_IC_VER) & 0x7f; + dbg_printf("[READ][DATA][CH376_CMD_GET_IC_VER] setting data port to &%02x\n", data_out); + break; case CH376_CMD_SET_USB_MODE: - if(ch376->usb_mode == CH376_ARG_SET_USB_MODE_INVALID) - { - data_out = CH376_RET_ABORT; - dbg_printf("[READ][DATA][CH376_SET_USB_MODE] aborted!\n"); - } - else - { - data_out = CH376_RET_SUCCESS; - dbg_printf("[READ][DATA][CH376_SET_USB_MODE] completed!\n"); - } - break; + if(ch376->usb_mode == CH376_ARG_SET_USB_MODE_INVALID) + { + data_out = CH376_RET_ABORT; + dbg_printf("[READ][DATA][CH376_SET_USB_MODE] aborted!\n"); + } + else + { + data_out = CH376_RET_SUCCESS; + dbg_printf("[READ][DATA][CH376_SET_USB_MODE] completed!\n"); + } + break; case CH376_CMD_GET_STATUS: - data_out = ch376->command_status; - dbg_printf("[READ][DATA][CH376_CMD_GET_STATUS] setting data port to &%02x\n", data_out); - break; + data_out = ch376->command_status; + dbg_printf("[READ][DATA][CH376_CMD_GET_STATUS] setting data port to &%02x\n", data_out); + break; case CH376_CMD_RD_USB_DATA0: - if(ch376->nb_bytes_in_cmd_data) + if(ch376->nb_bytes_in_cmd_data) + { + if(ch376->pos_rw_in_cmd_data == CMD_DATA_REQ_SIZE) { - if(ch376->pos_rw_in_cmd_data == CMD_DATA_REQ_SIZE) - { - data_out = ch376->nb_bytes_in_cmd_data; - ch376->pos_rw_in_cmd_data = 0; - dbg_printf("[READ][DATA][CH376_CMD_RD_USB_DATA0] read i/o buffer size: &%02x\n", data_out); - } - else if(ch376->nb_bytes_in_cmd_data != ch376->pos_rw_in_cmd_data) - { - data_out = ch376->cmd_data.CMD_IOBuffer[ch376->pos_rw_in_cmd_data]; - - dbg_printf("[READ][DATA][CH376_CMD_RD_USB_DATA0] read \"%c\" (&%02x) from i/o buffer at position &%02x\n", data_out, data_out, ch376->pos_rw_in_cmd_data); - - if(++ch376->pos_rw_in_cmd_data == ch376->nb_bytes_in_cmd_data) - ch376->nb_bytes_in_cmd_data = 0; - } + data_out = ch376->nb_bytes_in_cmd_data; + ch376->pos_rw_in_cmd_data = 0; + dbg_printf("[READ][DATA][CH376_CMD_RD_USB_DATA0] read i/o buffer size: &%02x\n", data_out); } - else + else if(ch376->nb_bytes_in_cmd_data != ch376->pos_rw_in_cmd_data) { - data_out = 0; - dbg_printf("[READ][DATA][CH376_CMD_RD_USB_DATA0] nothing to read from i/o buffer\n"); + data_out = ch376->cmd_data.CMD_IOBuffer[ch376->pos_rw_in_cmd_data]; + + dbg_printf("[READ][DATA][CH376_CMD_RD_USB_DATA0] read \"%c\" (&%02x) from i/o buffer at position &%02x\n", data_out, data_out, ch376->pos_rw_in_cmd_data); + + if(++ch376->pos_rw_in_cmd_data == ch376->nb_bytes_in_cmd_data) + ch376->nb_bytes_in_cmd_data = 0; } - break; + } + else + { + data_out = 0; + dbg_printf("[READ][DATA][CH376_CMD_RD_USB_DATA0] nothing to read from i/o buffer\n"); + } + break; case CH376_CMD_WR_REQ_DATA: - if(ch376->nb_bytes_in_cmd_data) + if(ch376->nb_bytes_in_cmd_data) + { + if(ch376->pos_rw_in_cmd_data == CMD_DATA_REQ_SIZE) { - if(ch376->pos_rw_in_cmd_data == CMD_DATA_REQ_SIZE) - { - data_out = ch376->nb_bytes_in_cmd_data; - ch376->pos_rw_in_cmd_data = 0; - dbg_printf("[READ][DATA][CH376_CMD_WR_REQ_DATA] read i/o buffer size: &%02x\n", data_out); - } - } - else - { - data_out = 0; - dbg_printf("[READ][DATA][CH376_CMD_WR_REQ_DATA] nothing to read from i/o buffer\n"); + data_out = ch376->nb_bytes_in_cmd_data; + ch376->pos_rw_in_cmd_data = 0; + dbg_printf("[READ][DATA][CH376_CMD_WR_REQ_DATA] read i/o buffer size: &%02x\n", data_out); } - break; + } + else + { + data_out = 0; + dbg_printf("[READ][DATA][CH376_CMD_WR_REQ_DATA] nothing to read from i/o buffer\n"); + } + break; // Emulate CH376 bug which returns the 1st byte in data buffer // when read is performed on an unexpected command default: - data_out = ch376->cmd_data.CMD_IOBuffer[0]; - break; - } + data_out = ch376->cmd_data.CMD_IOBuffer[0]; + break; + } - dbg_printf("<< [READ][DATA] for during command &%02x status &%02x\n", ch376->command, ch376->command_status); + dbg_printf("<< [READ][DATA] for during command &%02x status &%02x\n", ch376->command, ch376->command_status); return data_out; @@ -1829,494 +1956,494 @@ CH376_U8 ch376_read_data_port(struct ch376 *ch376) void ch376_write_command_port(struct ch376 *ch376, CH376_U8 command) { - dbg_printf(">> [WRITE][COMMAND] Write command &%02x status &%02x\n", command, ch376->command_status); + dbg_printf(">> [WRITE][COMMAND] Write command &%02x status &%02x\n", command, ch376->command_status); - ch376->interface_status = 0; + ch376->interface_status = 0; - // Emulate CH376 bug which can get the check byte - // from the command port instead of the data port! - if(ch376->command == CH376_CMD_CHECK_EXIST) - { - ch376->cmd_data.CMD_CheckByte = ~command; - dbg_printf("[WRITE][COMMAND][CH376_CMD_CHECK_EXIST] got check byte &%02x from command port!\n", command); - } + // Emulate CH376 bug which can get the check byte + // from the command port instead of the data port! + if(ch376->command == CH376_CMD_CHECK_EXIST) + { + ch376->cmd_data.CMD_CheckByte = ~command; + dbg_printf("[WRITE][COMMAND][CH376_CMD_CHECK_EXIST] got check byte &%02x from command port!\n", command); + } - switch(command) - { + switch(command) + { case CH376_CMD_CHECK_EXIST: - ch376->command = CH376_CMD_CHECK_EXIST; - dbg_printf("[WRITE][COMMAND][CH376_CMD_CHECK_EXIST] waiting for check byte\n"); - break; + ch376->command = CH376_CMD_CHECK_EXIST; + dbg_printf("[WRITE][COMMAND][CH376_CMD_CHECK_EXIST] waiting for check byte\n"); + break; - case CH376_CMD_GET_FILE_SIZE: - ch376->command = CH376_CMD_GET_FILE_SIZE; - dbg_printf("[WRITE][COMMAND][CH376_CMD_GET_FILE_SIZE] wait for &68 byte\n"); - break; + case CH376_CMD_READ_VAR32: + ch376->command = CH376_CMD_READ_VAR32; + dbg_printf("[WRITE][COMMAND][CH376_CMD_READ_VAR32] wait for var offset byte\n"); + break; case CH376_CMD_GET_IC_VER: - ch376->command = CH376_CMD_GET_IC_VER; - dbg_printf("[WRITE][COMMAND][CH376_CMD_GET_IC_VER]\n"); - break; + ch376->command = CH376_CMD_GET_IC_VER; + dbg_printf("[WRITE][COMMAND][CH376_CMD_GET_IC_VER]\n"); + break; case CH376_CMD_SET_USB_MODE: - ch376->command = CH376_CMD_SET_USB_MODE; - dbg_printf("[WRITE][COMMAND][CH376_CMD_SET_USB_MODE] waiting for usb mode data\n"); - break; + ch376->command = CH376_CMD_SET_USB_MODE; + dbg_printf("[WRITE][COMMAND][CH376_CMD_SET_USB_MODE] waiting for usb mode data\n"); + break; case CH376_CMD_DISK_MOUNT: - ch376->command = CH376_CMD_DISK_MOUNT; - cancel_all_io(ch376); - // If directory is available, we consider that it's mounted! - if(ch376->usb_mode == CH376_ARG_SET_USB_MODE_SD_HOST) - ch376->root_dir_lock = system_obtain_directory_lock(&ch376->context, ch376->sdcard_drive_path, NULL); - else if(ch376->usb_mode == CH376_ARG_SET_USB_MODE_USB_HOST) - ch376->root_dir_lock = system_obtain_directory_lock(&ch376->context, ch376->usb_drive_path, NULL); - - if(ch376->root_dir_lock) - { - ch376->cmd_data.CMD_MountInfo.MOUNT_DeviceType = 0; - ch376->cmd_data.CMD_MountInfo.MOUNT_RemovableMedia = 0; - ch376->cmd_data.CMD_MountInfo.MOUNT_Versions = 0; - ch376->cmd_data.CMD_MountInfo.MOUNT_DataFormatAndEtc = 0; - ch376->cmd_data.CMD_MountInfo.MOUNT_AdditionalLength = 0; - ch376->cmd_data.CMD_MountInfo.MOUNT_Reserved1 = 0; - ch376->cmd_data.CMD_MountInfo.MOUNT_Reserved2 = 0; - ch376->cmd_data.CMD_MountInfo.MOUNT_MiscFlag = 0; - ch376->cmd_data.CMD_MountInfo.MOUNT_VendorIdStr[0] = 'J'; - ch376->cmd_data.CMD_MountInfo.MOUNT_VendorIdStr[1] = 'E'; - ch376->cmd_data.CMD_MountInfo.MOUNT_VendorIdStr[2] = 'D'; - ch376->cmd_data.CMD_MountInfo.MOUNT_VendorIdStr[3] = 'E'; - ch376->cmd_data.CMD_MountInfo.MOUNT_VendorIdStr[4] = '+'; - ch376->cmd_data.CMD_MountInfo.MOUNT_VendorIdStr[5] = 'O'; - ch376->cmd_data.CMD_MountInfo.MOUNT_VendorIdStr[6] = 'F'; - ch376->cmd_data.CMD_MountInfo.MOUNT_VendorIdStr[7] = 'T'; - ch376->cmd_data.CMD_MountInfo.MOUNT_ProductIdStr[ 0] = 'C'; - ch376->cmd_data.CMD_MountInfo.MOUNT_ProductIdStr[ 1] = 'H'; - ch376->cmd_data.CMD_MountInfo.MOUNT_ProductIdStr[ 2] = '3'; - ch376->cmd_data.CMD_MountInfo.MOUNT_ProductIdStr[ 3] = '7'; - ch376->cmd_data.CMD_MountInfo.MOUNT_ProductIdStr[ 4] = '6'; - ch376->cmd_data.CMD_MountInfo.MOUNT_ProductIdStr[ 5] = ' '; - ch376->cmd_data.CMD_MountInfo.MOUNT_ProductIdStr[ 6] = 'E'; - ch376->cmd_data.CMD_MountInfo.MOUNT_ProductIdStr[ 7] = 'M'; - ch376->cmd_data.CMD_MountInfo.MOUNT_ProductIdStr[ 8] = 'U'; - ch376->cmd_data.CMD_MountInfo.MOUNT_ProductIdStr[ 9] = 'L'; - ch376->cmd_data.CMD_MountInfo.MOUNT_ProductIdStr[10] = 'A'; - ch376->cmd_data.CMD_MountInfo.MOUNT_ProductIdStr[11] = 'T'; - ch376->cmd_data.CMD_MountInfo.MOUNT_ProductIdStr[12] = 'O'; - ch376->cmd_data.CMD_MountInfo.MOUNT_ProductIdStr[13] = 'R'; - ch376->cmd_data.CMD_MountInfo.MOUNT_ProductIdStr[14] = ' '; - ch376->cmd_data.CMD_MountInfo.MOUNT_ProductIdStr[15] = ' '; - ch376->cmd_data.CMD_MountInfo.MOUNT_ProductRevStr[0] = 'F'; - ch376->cmd_data.CMD_MountInfo.MOUNT_ProductRevStr[1] = 'A'; - ch376->cmd_data.CMD_MountInfo.MOUNT_ProductRevStr[2] = 'M'; - ch376->cmd_data.CMD_MountInfo.MOUNT_ProductRevStr[3] = 'E'; - - dbg_printf("[WRITE][COMMAND][CH376_CMD_DISK_MOUNT] drive directory is found (mounted :); additional data available\n"); - - ch376->nb_bytes_in_cmd_data = sizeof(ch376->cmd_data.CMD_MountInfo); - ch376->interface_status = 127; // Found :) - ch376->command_status = CH376_INT_SUCCESS; - } - else - { - dbg_printf("[WRITE][COMMAND][CH376_CMD_DISK_MOUNT] drive directory not found\n"); - ch376->command_status = 0x1f; // Don't know if it's this code - } - break; + ch376->command = CH376_CMD_DISK_MOUNT; + cancel_all_io(ch376); + // If directory is available, we consider that it's mounted! + if(ch376->usb_mode == CH376_ARG_SET_USB_MODE_SD_HOST) + ch376->root_dir_lock = system_obtain_directory_lock(&ch376->context, ch376->sdcard_drive_path, NULL); + else if(ch376->usb_mode == CH376_ARG_SET_USB_MODE_USB_HOST) + ch376->root_dir_lock = system_obtain_directory_lock(&ch376->context, ch376->usb_drive_path, NULL); + + if(ch376->root_dir_lock) + { + ch376->cmd_data.CMD_MountInfo.MOUNT_DeviceType = 0; + ch376->cmd_data.CMD_MountInfo.MOUNT_RemovableMedia = 0; + ch376->cmd_data.CMD_MountInfo.MOUNT_Versions = 0; + ch376->cmd_data.CMD_MountInfo.MOUNT_DataFormatAndEtc = 0; + ch376->cmd_data.CMD_MountInfo.MOUNT_AdditionalLength = 0; + ch376->cmd_data.CMD_MountInfo.MOUNT_Reserved1 = 0; + ch376->cmd_data.CMD_MountInfo.MOUNT_Reserved2 = 0; + ch376->cmd_data.CMD_MountInfo.MOUNT_MiscFlag = 0; + ch376->cmd_data.CMD_MountInfo.MOUNT_VendorIdStr[0] = 'J'; + ch376->cmd_data.CMD_MountInfo.MOUNT_VendorIdStr[1] = 'E'; + ch376->cmd_data.CMD_MountInfo.MOUNT_VendorIdStr[2] = 'D'; + ch376->cmd_data.CMD_MountInfo.MOUNT_VendorIdStr[3] = 'E'; + ch376->cmd_data.CMD_MountInfo.MOUNT_VendorIdStr[4] = '+'; + ch376->cmd_data.CMD_MountInfo.MOUNT_VendorIdStr[5] = 'O'; + ch376->cmd_data.CMD_MountInfo.MOUNT_VendorIdStr[6] = 'F'; + ch376->cmd_data.CMD_MountInfo.MOUNT_VendorIdStr[7] = 'T'; + ch376->cmd_data.CMD_MountInfo.MOUNT_ProductIdStr[ 0] = 'C'; + ch376->cmd_data.CMD_MountInfo.MOUNT_ProductIdStr[ 1] = 'H'; + ch376->cmd_data.CMD_MountInfo.MOUNT_ProductIdStr[ 2] = '3'; + ch376->cmd_data.CMD_MountInfo.MOUNT_ProductIdStr[ 3] = '7'; + ch376->cmd_data.CMD_MountInfo.MOUNT_ProductIdStr[ 4] = '6'; + ch376->cmd_data.CMD_MountInfo.MOUNT_ProductIdStr[ 5] = ' '; + ch376->cmd_data.CMD_MountInfo.MOUNT_ProductIdStr[ 6] = 'E'; + ch376->cmd_data.CMD_MountInfo.MOUNT_ProductIdStr[ 7] = 'M'; + ch376->cmd_data.CMD_MountInfo.MOUNT_ProductIdStr[ 8] = 'U'; + ch376->cmd_data.CMD_MountInfo.MOUNT_ProductIdStr[ 9] = 'L'; + ch376->cmd_data.CMD_MountInfo.MOUNT_ProductIdStr[10] = 'A'; + ch376->cmd_data.CMD_MountInfo.MOUNT_ProductIdStr[11] = 'T'; + ch376->cmd_data.CMD_MountInfo.MOUNT_ProductIdStr[12] = 'O'; + ch376->cmd_data.CMD_MountInfo.MOUNT_ProductIdStr[13] = 'R'; + ch376->cmd_data.CMD_MountInfo.MOUNT_ProductIdStr[14] = ' '; + ch376->cmd_data.CMD_MountInfo.MOUNT_ProductIdStr[15] = ' '; + ch376->cmd_data.CMD_MountInfo.MOUNT_ProductRevStr[0] = 'F'; + ch376->cmd_data.CMD_MountInfo.MOUNT_ProductRevStr[1] = 'A'; + ch376->cmd_data.CMD_MountInfo.MOUNT_ProductRevStr[2] = 'M'; + ch376->cmd_data.CMD_MountInfo.MOUNT_ProductRevStr[3] = 'E'; + + dbg_printf("[WRITE][COMMAND][CH376_CMD_DISK_MOUNT] drive directory is found (mounted :); additional data available\n"); + + ch376->nb_bytes_in_cmd_data = sizeof(ch376->cmd_data.CMD_MountInfo); + ch376->interface_status = 127; // Found :) + ch376->command_status = CH376_INT_SUCCESS; + } + else + { + dbg_printf("[WRITE][COMMAND][CH376_CMD_DISK_MOUNT] drive directory not found\n"); + ch376->command_status = 0x1f; // Don't know if it's this code + } + break; case CH376_CMD_GET_STATUS: - ch376->command = CH376_CMD_GET_STATUS; - dbg_printf("[WRITE][COMMAND][CH376_CMD_GET_STATUS] waiting for status reading\n"); - break; + ch376->command = CH376_CMD_GET_STATUS; + dbg_printf("[WRITE][COMMAND][CH376_CMD_GET_STATUS] waiting for status reading\n"); + break; case CH376_CMD_SET_FILE_NAME: - ch376->command = CH376_CMD_SET_FILE_NAME; - ch376->pos_rw_in_cmd_data = 0; - dbg_printf("[WRITE][COMMAND][CH376_CMD_SET_FILE_NAME] waiting for file name\n"); - break; + ch376->command = CH376_CMD_SET_FILE_NAME; + ch376->pos_rw_in_cmd_data = 0; + dbg_printf("[WRITE][COMMAND][CH376_CMD_SET_FILE_NAME] waiting for file name\n"); + break; case CH376_CMD_FILE_OPEN: - ch376->command = CH376_CMD_FILE_OPEN; - // mounted? - if(ch376->root_dir_lock) + ch376->command = CH376_CMD_FILE_OPEN; + // mounted? + if(ch376->root_dir_lock) + { + int i = 0; + + // back to root? + if(ch376->cmd_data.CMD_FileName[i] == '/') { - int i = 0; - - // back to root? - if(ch376->cmd_data.CMD_FileName[i] == '/') - { - dbg_printf("[WRITE][COMMAND][CH376_CMD_FILE_OPEN] opening root directory\n"); - system_release_directory_lock(&ch376->context, ch376->current_dir_lock); - ch376->current_dir_lock = system_clone_directory_lock(&ch376->context, ch376->root_dir_lock); - i++; - } + dbg_printf("[WRITE][COMMAND][CH376_CMD_FILE_OPEN] opening root directory\n"); + system_release_directory_lock(&ch376->context, ch376->current_dir_lock); + ch376->current_dir_lock = system_clone_directory_lock(&ch376->context, ch376->root_dir_lock); + i++; + } - if(ch376->cmd_data.CMD_FileName[i] == '\0') - { - // We are done - ch376->interface_status = 127; // Found :) - ch376->command_status = CH376_ERR_OPEN_DIR; - ch376->current_file_is_directory = CH376_TRUE; - } - else - { - // wildcard? - if(strchr(ch376->cmd_data.CMD_FileName,'*') || strchr(ch376->cmd_data.CMD_FileName,'?')) - { - dbg_printf("[WRITE][COMMAND][CH376_CMD_FILE_OPEN] examining directory contents\n"); - - // Start a directory examine session - system_finish_examine_directory(&ch376->context, ch376->current_directory_browsing); - ch376->current_directory_browsing = system_start_examine_directory(&ch376->context, ch376->current_dir_lock); - normalize_pattern(ch376->cmd_data.CMD_FileName, ch376->dir_pattern); - - goto file_enum_go; - } - else - { - char fixed_file_name[13]; // Max = 8 + '.' + 3 + '\0' - CH376_LOCK current_dir_lock; - trim_file_name(&ch376->cmd_data.CMD_FileName[i], fixed_file_name); - - current_dir_lock = system_obtain_directory_lock(&ch376->context, fixed_file_name, ch376->current_dir_lock); - - // Enter new directory? - if(current_dir_lock) - { - dbg_printf("[WRITE][COMMAND][CH376_CMD_FILE_OPEN] entering directory: %s\n", &ch376->cmd_data.CMD_FileName[i]); - - system_release_directory_lock(&ch376->context, ch376->current_dir_lock); - ch376->current_dir_lock = current_dir_lock; - ch376->current_file_is_directory = CH376_TRUE; - - ch376->interface_status = 127; // Found :) - ch376->command_status = CH376_ERR_OPEN_DIR; - } - // Open existing file? - else - { - system_file_close(&ch376->context, ch376->current_file); - ch376->current_file = system_file_open_existing(&ch376->context, fixed_file_name, ch376->current_dir_lock); - - dbg_printf("[WRITE][COMMAND][CH376_CMD_FILE_OPEN] opening the file: %s\n", &ch376->cmd_data.CMD_FileName[i]); - - if(ch376->current_file) - { - ch376->interface_status = 127; // Found :) - ch376->command_status = CH376_INT_SUCCESS; - ch376->current_file_is_directory = CH376_FALSE; - } - else - { - ch376->interface_status = 0; - ch376->command_status = CH376_ERR_MISS_FILE; - } - } - } - } + if(ch376->cmd_data.CMD_FileName[i] == '\0') + { + // We are done + ch376->interface_status = 127; // Found :) + ch376->command_status = CH376_ERR_OPEN_DIR; + ch376->current_file_is_directory = CH376_TRUE; } else { - dbg_printf("[WRITE][COMMAND][CH376_CMD_FILE_OPEN] no operation possible (device not mounted)\n"); + // wildcard? + if(strchr(ch376->cmd_data.CMD_FileName,'*') || strchr(ch376->cmd_data.CMD_FileName,'?')) + { + dbg_printf("[WRITE][COMMAND][CH376_CMD_FILE_OPEN] examining directory contents\n"); - ch376->interface_status = 0; - ch376->command_status = CH376_RET_ABORT; - } - break; + // Start a directory examine session + system_finish_examine_directory(&ch376->context, ch376->current_directory_browsing); + ch376->current_directory_browsing = system_start_examine_directory(&ch376->context, ch376->current_dir_lock); + normalize_pattern(ch376->cmd_data.CMD_FileName, ch376->dir_pattern); - case CH376_CMD_FILE_CREATE: - ch376->command = CH376_CMD_FILE_CREATE; - // mounted? - if(ch376->root_dir_lock) - { - int i = 0; + goto file_enum_go; + } + else + { + char fixed_file_name[13]; // Max = 8 + '.' + 3 + '\0' + CH376_LOCK current_dir_lock; + trim_file_name(&ch376->cmd_data.CMD_FileName[i], fixed_file_name); - // back to root? - if(ch376->cmd_data.CMD_FileName[i] == '/') - { - dbg_printf("[WRITE][COMMAND][CH376_CMD_FILE_CREATE] opening root directory\n"); - system_release_directory_lock(&ch376->context, ch376->current_dir_lock); - ch376->current_dir_lock = system_clone_directory_lock(&ch376->context, ch376->root_dir_lock); - i++; - } + current_dir_lock = system_obtain_directory_lock(&ch376->context, fixed_file_name, ch376->current_dir_lock); - if(ch376->cmd_data.CMD_FileName[i] == '\0') + // Enter new directory? + if(current_dir_lock) { - // We are done - ch376->interface_status = 127; // Found :) - ch376->command_status = CH376_INT_SUCCESS; + dbg_printf("[WRITE][COMMAND][CH376_CMD_FILE_OPEN] entering directory: %s\n", &ch376->cmd_data.CMD_FileName[i]); + + system_release_directory_lock(&ch376->context, ch376->current_dir_lock); + ch376->current_dir_lock = current_dir_lock; + ch376->current_file_is_directory = CH376_TRUE; + + ch376->interface_status = 127; // Found :) + ch376->command_status = CH376_ERR_OPEN_DIR; } + // Open existing file? else { - char fixed_file_name[13]; // Max = 8 + '.' + 3 + '\0' - trim_file_name(&ch376->cmd_data.CMD_FileName[i], fixed_file_name); - - // Create file - system_file_close(&ch376->context, ch376->current_file); - ch376->current_file = system_file_open_new(&ch376->context, fixed_file_name, ch376->current_dir_lock); - - dbg_printf("[WRITE][COMMAND][CH376_CMD_FILE_CREATE] creating the file: %s\n", &ch376->cmd_data.CMD_FileName[i]); - - if(ch376->current_file) - { - ch376->interface_status = 127; // Found :) - ch376->command_status = CH376_INT_SUCCESS; - } - else - { - ch376->interface_status = 0; - ch376->command_status = CH376_ERR_MISS_FILE; - } + system_file_close(&ch376->context, ch376->current_file); + ch376->current_file = system_file_open_existing(&ch376->context, fixed_file_name, ch376->current_dir_lock); + + dbg_printf("[WRITE][COMMAND][CH376_CMD_FILE_OPEN] opening the file: %s\n", &ch376->cmd_data.CMD_FileName[i]); + + if(ch376->current_file) + { + ch376->interface_status = 127; // Found :) + ch376->command_status = CH376_INT_SUCCESS; + ch376->current_file_is_directory = CH376_FALSE; + } + else + { + ch376->interface_status = 0; + ch376->command_status = CH376_ERR_MISS_FILE; + } } + } + } + } + else + { + dbg_printf("[WRITE][COMMAND][CH376_CMD_FILE_OPEN] no operation possible (device not mounted)\n"); + + ch376->interface_status = 0; + ch376->command_status = CH376_RET_ABORT; + } + break; + + case CH376_CMD_FILE_CREATE: + ch376->command = CH376_CMD_FILE_CREATE; + // mounted? + if(ch376->root_dir_lock) + { + int i = 0; + + // back to root? + if(ch376->cmd_data.CMD_FileName[i] == '/') + { + dbg_printf("[WRITE][COMMAND][CH376_CMD_FILE_CREATE] opening root directory\n"); + system_release_directory_lock(&ch376->context, ch376->current_dir_lock); + ch376->current_dir_lock = system_clone_directory_lock(&ch376->context, ch376->root_dir_lock); + i++; + } + + if(ch376->cmd_data.CMD_FileName[i] == '\0') + { + // We are done + ch376->interface_status = 127; // Found :) + ch376->command_status = CH376_INT_SUCCESS; } else { - dbg_printf("[WRITE][COMMAND][CH376_CMD_FILE_CREATE] no operation possible (device not mounted)\n"); + char fixed_file_name[13]; // Max = 8 + '.' + 3 + '\0' + trim_file_name(&ch376->cmd_data.CMD_FileName[i], fixed_file_name); + + // Create file + system_file_close(&ch376->context, ch376->current_file); + ch376->current_file = system_file_open_new(&ch376->context, fixed_file_name, ch376->current_dir_lock); + dbg_printf("[WRITE][COMMAND][CH376_CMD_FILE_CREATE] creating the file: %s\n", &ch376->cmd_data.CMD_FileName[i]); + + if(ch376->current_file) + { + ch376->interface_status = 127; // Found :) + ch376->command_status = CH376_INT_SUCCESS; + } + else + { ch376->interface_status = 0; - ch376->command_status = CH376_RET_ABORT; + ch376->command_status = CH376_ERR_MISS_FILE; + } } - break; + } + else + { + dbg_printf("[WRITE][COMMAND][CH376_CMD_FILE_CREATE] no operation possible (device not mounted)\n"); + + ch376->interface_status = 0; + ch376->command_status = CH376_RET_ABORT; + } + break; case CH376_CMD_DIR_CREATE: - ch376->command = CH376_CMD_DIR_CREATE; - // mounted? - if(ch376->root_dir_lock) + ch376->command = CH376_CMD_DIR_CREATE; + // mounted? + if(ch376->root_dir_lock) + { + char fixed_file_name[13]; // Max = 8 + '.' + 3 + '\0' + CH376_FILE existing_file; + int i = 0; + + // back to root? + if(ch376->cmd_data.CMD_FileName[i] == '/') { - char fixed_file_name[13]; // Max = 8 + '.' + 3 + '\0' - CH376_FILE existing_file; - int i = 0; - - // back to root? - if(ch376->cmd_data.CMD_FileName[i] == '/') - { - dbg_printf("[WRITE][COMMAND][CH376_CMD_DIR_CREATE] opening root directory\n"); - system_release_directory_lock(&ch376->context, ch376->current_dir_lock); - ch376->current_dir_lock = system_clone_directory_lock(&ch376->context, ch376->root_dir_lock); - i++; - } - - trim_file_name(&ch376->cmd_data.CMD_FileName[i], fixed_file_name); + dbg_printf("[WRITE][COMMAND][CH376_CMD_DIR_CREATE] opening root directory\n"); + system_release_directory_lock(&ch376->context, ch376->current_dir_lock); + ch376->current_dir_lock = system_clone_directory_lock(&ch376->context, ch376->root_dir_lock); + i++; + } - existing_file = system_file_open_existing(&ch376->context, fixed_file_name, ch376->current_dir_lock); + trim_file_name(&ch376->cmd_data.CMD_FileName[i], fixed_file_name); - if(existing_file) - { - system_file_close(&ch376->context, existing_file); - ch376->interface_status = 0; - ch376->command_status = CH376_ERR_FOUND_NAME; - } - else - { - CH376_LOCK created_dir_lock; + existing_file = system_file_open_existing(&ch376->context, fixed_file_name, ch376->current_dir_lock); - // Already created? - created_dir_lock = system_obtain_directory_lock(&ch376->context, fixed_file_name, ch376->current_dir_lock); + if(existing_file) + { + system_file_close(&ch376->context, existing_file); + ch376->interface_status = 0; + ch376->command_status = CH376_ERR_FOUND_NAME; + } + else + { + CH376_LOCK created_dir_lock; - if (!created_dir_lock) - created_dir_lock = system_create_directory(&ch376->context, fixed_file_name, ch376->current_dir_lock); + // Already created? + created_dir_lock = system_obtain_directory_lock(&ch376->context, fixed_file_name, ch376->current_dir_lock); - // Actually created? - if(created_dir_lock) - { - dbg_printf("[WRITE][COMMAND][CH376_CMD_DIR_CREATE] entering created directory: %s\n", &ch376->cmd_data.CMD_FileName[i]); + if(!created_dir_lock) + created_dir_lock = system_create_directory(&ch376->context, fixed_file_name, ch376->current_dir_lock); - system_release_directory_lock(&ch376->context, ch376->current_dir_lock); - ch376->current_dir_lock = created_dir_lock; + // Actually created? + if(created_dir_lock) + { + dbg_printf("[WRITE][COMMAND][CH376_CMD_DIR_CREATE] entering created directory: %s\n", &ch376->cmd_data.CMD_FileName[i]); - ch376->interface_status = 127; - ch376->command_status = CH376_INT_SUCCESS; - } - else - { - dbg_printf("[WRITE][COMMAND][CH376_CMD_DIR_CREATE] directory could not be created: %s\n", &ch376->cmd_data.CMD_FileName[i]); + system_release_directory_lock(&ch376->context, ch376->current_dir_lock); + ch376->current_dir_lock = created_dir_lock; - ch376->interface_status = 0; - ch376->command_status = CH376_ERR_MISS_FILE; - } - } - } - else - { - dbg_printf("[WRITE][COMMAND][CH376_CMD_DIR_CREATE] no operation possible (device not mounted)\n"); + ch376->interface_status = 127; + ch376->command_status = CH376_INT_SUCCESS; + } + else + { + dbg_printf("[WRITE][COMMAND][CH376_CMD_DIR_CREATE] directory could not be created: %s\n", &ch376->cmd_data.CMD_FileName[i]); ch376->interface_status = 0; - ch376->command_status = CH376_RET_ABORT; + ch376->command_status = CH376_ERR_MISS_FILE; + } } - break; + } + else + { + dbg_printf("[WRITE][COMMAND][CH376_CMD_DIR_CREATE] no operation possible (device not mounted)\n"); + + ch376->interface_status = 0; + ch376->command_status = CH376_RET_ABORT; + } + break; case CH376_CMD_FILE_ERASE: - ch376->command = CH376_CMD_FILE_ERASE; - // mounted? - if(ch376->root_dir_lock) + ch376->command = CH376_CMD_FILE_ERASE; + // mounted? + if(ch376->root_dir_lock) + { + char fixed_file_name[13]; // Max = 8 + '.' + 3 + '\0' + int i = 0; + CH376_BOOL file_erased = CH376_FALSE; + + // back to root? + if(ch376->cmd_data.CMD_FileName[i] == '/') { - char fixed_file_name[13]; // Max = 8 + '.' + 3 + '\0' - int i = 0; - CH376_BOOL file_erased = CH376_FALSE; + dbg_printf("[WRITE][COMMAND][CH376_CMD_FILE_ERASE] opening root directory\n"); + system_release_directory_lock(&ch376->context, ch376->current_dir_lock); + ch376->current_dir_lock = system_clone_directory_lock(&ch376->context, ch376->root_dir_lock); + i++; + } - // back to root? - if(ch376->cmd_data.CMD_FileName[i] == '/') - { - dbg_printf("[WRITE][COMMAND][CH376_CMD_FILE_ERASE] opening root directory\n"); - system_release_directory_lock(&ch376->context, ch376->current_dir_lock); - ch376->current_dir_lock = system_clone_directory_lock(&ch376->context, ch376->root_dir_lock); - i++; - } + if(ch376->cmd_data.CMD_FileName[i] != 0) + { + trim_file_name(&ch376->cmd_data.CMD_FileName[i], fixed_file_name); - if (ch376->cmd_data.CMD_FileName[i] != 0) - { - trim_file_name(&ch376->cmd_data.CMD_FileName[i], fixed_file_name); - - if(ch376->current_file) - { - system_file_close(&ch376->context, ch376->current_file); - ch376->current_file = (CH376_FILE)0; - } - - if (ch376->current_file_is_directory) - file_erased = system_directory_delete(&ch376->context, ch376->current_dir_lock); - else - file_erased = system_file_delete(&ch376->context, fixed_file_name, ch376->current_dir_lock); - } + if(ch376->current_file) + { + system_file_close(&ch376->context, ch376->current_file); + ch376->current_file = (CH376_FILE)0; + } - if (file_erased) - { - dbg_printf("[WRITE][COMMAND][CH376_CMD_FILE_ERASE] file or directory deleted: %s\n", &ch376->cmd_data.CMD_FileName[i]); + if(ch376->current_file_is_directory) + file_erased = system_directory_delete(&ch376->context, ch376->current_dir_lock); + else + file_erased = system_file_delete(&ch376->context, fixed_file_name, ch376->current_dir_lock); + } - ch376->interface_status = 127; - ch376->command_status = CH376_INT_SUCCESS; - } - else - { - dbg_printf("[WRITE][COMMAND][CH376_CMD_FILE_ERASE] file or directory could not be deleted: %s\n", &ch376->cmd_data.CMD_FileName[i]); + if(file_erased) + { + dbg_printf("[WRITE][COMMAND][CH376_CMD_FILE_ERASE] file or directory deleted: %s\n", &ch376->cmd_data.CMD_FileName[i]); - ch376->interface_status = 0; - ch376->command_status = CH376_ERR_MISS_FILE; - } + ch376->interface_status = 127; + ch376->command_status = CH376_INT_SUCCESS; } else { - dbg_printf("[WRITE][COMMAND][CH376_CMD_FILE_ERASE] no operation possible (device not mounted)\n"); + dbg_printf("[WRITE][COMMAND][CH376_CMD_FILE_ERASE] file or directory could not be deleted: %s\n", &ch376->cmd_data.CMD_FileName[i]); - ch376->interface_status = 0; - ch376->command_status = CH376_RET_ABORT; + ch376->interface_status = 0; + ch376->command_status = CH376_ERR_MISS_FILE; } - break; + } + else + { + dbg_printf("[WRITE][COMMAND][CH376_CMD_FILE_ERASE] no operation possible (device not mounted)\n"); + + ch376->interface_status = 0; + ch376->command_status = CH376_RET_ABORT; + } + break; case CH376_CMD_RD_USB_DATA0: - ch376->command = CH376_CMD_RD_USB_DATA0; - ch376->pos_rw_in_cmd_data = CMD_DATA_REQ_SIZE; // Will be reset when size is sent - dbg_printf("[WRITE][COMMAND][CH376_CMD_RD_USB_DATA0] waiting for i/o buffer read\n"); - break; + ch376->command = CH376_CMD_RD_USB_DATA0; + ch376->pos_rw_in_cmd_data = CMD_DATA_REQ_SIZE; // Will be reset when size is sent + dbg_printf("[WRITE][COMMAND][CH376_CMD_RD_USB_DATA0] waiting for i/o buffer read\n"); + break; case CH376_CMD_WR_REQ_DATA: - ch376->command = CH376_CMD_WR_REQ_DATA; - ch376->pos_rw_in_cmd_data = CMD_DATA_REQ_SIZE; // Will be reset when size is sent - dbg_printf("[WRITE][COMMAND][CH376_CMD_WR_REQ_DATA] waiting for i/o buffer write\n"); - break; + ch376->command = CH376_CMD_WR_REQ_DATA; + ch376->pos_rw_in_cmd_data = CMD_DATA_REQ_SIZE; // Will be reset when size is sent + dbg_printf("[WRITE][COMMAND][CH376_CMD_WR_REQ_DATA] waiting for i/o buffer write\n"); + break; case CH376_CMD_FILE_ENUM_GO: - ch376->command = CH376_CMD_FILE_ENUM_GO; + ch376->command = CH376_CMD_FILE_ENUM_GO; file_enum_go: - if(system_go_examine_directory(&ch376->context, ch376->current_dir_lock, ch376->current_directory_browsing, &ch376->cmd_data.CMD_FatDirInfo, ch376->dir_pattern)) - { - dbg_printf("[WRITE][COMMAND][CH376_CMD_FILE_ENUM_GO] next directory entry in buffer\n"); - ch376->nb_bytes_in_cmd_data = sizeof(ch376->cmd_data.CMD_FatDirInfo); - ch376->interface_status = 127; - ch376->command_status = CH376_INT_DISK_READ; - } - else - { - dbg_printf("[WRITE][COMMAND][CH376_CMD_FILE_ENUM_GO] directory browing finished\n"); + if(system_go_examine_directory(&ch376->context, ch376->current_dir_lock, ch376->current_directory_browsing, &ch376->cmd_data.CMD_FatDirInfo, ch376->dir_pattern)) + { + dbg_printf("[WRITE][COMMAND][CH376_CMD_FILE_ENUM_GO] next directory entry in buffer\n"); + ch376->nb_bytes_in_cmd_data = sizeof(ch376->cmd_data.CMD_FatDirInfo); + ch376->interface_status = 127; + ch376->command_status = CH376_INT_DISK_READ; + } + else + { + dbg_printf("[WRITE][COMMAND][CH376_CMD_FILE_ENUM_GO] directory browsing finished\n"); - system_finish_examine_directory(&ch376->context, ch376->current_directory_browsing); - ch376->current_directory_browsing = (CH376_DIR)0; + system_finish_examine_directory(&ch376->context, ch376->current_directory_browsing); + ch376->current_directory_browsing = (CH376_DIR)0; - ch376->interface_status = 0; - ch376->command_status = CH376_ERR_OPEN_DIR; - } - break; + ch376->interface_status = 0; + ch376->command_status = CH376_ERR_OPEN_DIR; + } + break; case CH376_CMD_DISK_CAPACITY: - ch376->command = CH376_CMD_DISK_CAPACITY; - // mounted? - if(system_get_disk_info(&ch376->context, ch376->root_dir_lock, &ch376->cmd_data.CMD_DiskQuery)) - { - dbg_printf("[WRITE][COMMAND][CH376_CMD_DISK_CAPACITY] sector capacity in buffer\n"); - // Only first 4 bytes of cmd_data.CMD_DiskQuery - ch376->nb_bytes_in_cmd_data = 4; - ch376->interface_status = 127; - ch376->command_status = CH376_INT_SUCCESS; - } - else - { - dbg_printf("[WRITE][COMMAND][CH376_CMD_DISK_CAPACITY] no operation possible (device not mounted)\n"); - ch376->interface_status = 0; - ch376->command_status = CH376_RET_ABORT; - } - break; + ch376->command = CH376_CMD_DISK_CAPACITY; + // mounted? + if(system_get_disk_info(&ch376->context, ch376->root_dir_lock, &ch376->cmd_data.CMD_DiskQuery)) + { + dbg_printf("[WRITE][COMMAND][CH376_CMD_DISK_CAPACITY] sector capacity in buffer\n"); + // Only first 4 bytes of cmd_data.CMD_DiskQuery + ch376->nb_bytes_in_cmd_data = 4; + ch376->interface_status = 127; + ch376->command_status = CH376_INT_SUCCESS; + } + else + { + dbg_printf("[WRITE][COMMAND][CH376_CMD_DISK_CAPACITY] no operation possible (device not mounted)\n"); + ch376->interface_status = 0; + ch376->command_status = CH376_RET_ABORT; + } + break; case CH376_CMD_DISK_QUERY: - ch376->command = CH376_CMD_DISK_QUERY; - // mounted? - if(system_get_disk_info(&ch376->context, ch376->root_dir_lock, &ch376->cmd_data.CMD_DiskQuery)) - { - dbg_printf("[WRITE][COMMAND][CH376_CMD_DISK_QUERY] sector capacity in buffer\n"); - ch376->nb_bytes_in_cmd_data = sizeof(ch376->cmd_data.CMD_DiskQuery); - ch376->interface_status = 127; - ch376->command_status = CH376_INT_SUCCESS; - } - else - { - dbg_printf("[WRITE][COMMAND][CH376_CMD_DISK_QUERY] no operation possible (device not mounted)\n"); - ch376->interface_status = 0; - ch376->command_status = CH376_RET_ABORT; - } - break; + ch376->command = CH376_CMD_DISK_QUERY; + // mounted? + if(system_get_disk_info(&ch376->context, ch376->root_dir_lock, &ch376->cmd_data.CMD_DiskQuery)) + { + dbg_printf("[WRITE][COMMAND][CH376_CMD_DISK_QUERY] sector capacity in buffer\n"); + ch376->nb_bytes_in_cmd_data = sizeof(ch376->cmd_data.CMD_DiskQuery); + ch376->interface_status = 127; + ch376->command_status = CH376_INT_SUCCESS; + } + else + { + dbg_printf("[WRITE][COMMAND][CH376_CMD_DISK_QUERY] no operation possible (device not mounted)\n"); + ch376->interface_status = 0; + ch376->command_status = CH376_RET_ABORT; + } + break; case CH376_CMD_BYTE_LOCATE: - ch376->command = CH376_CMD_BYTE_LOCATE; - dbg_printf("[WRITE][COMMAND][CH376_CMD_BYTE_LOCATE] waiting for seek position\n"); - ch376->pos_rw_in_cmd_data = 0; - break; + ch376->command = CH376_CMD_BYTE_LOCATE; + dbg_printf("[WRITE][COMMAND][CH376_CMD_BYTE_LOCATE] waiting for seek position\n"); + ch376->pos_rw_in_cmd_data = 0; + break; case CH376_CMD_BYTE_READ: - ch376->command = CH376_CMD_BYTE_READ; - dbg_printf("[WRITE][COMMAND][CH376_CMD_BYTE_READ] waiting for read size\n"); - ch376->pos_rw_in_cmd_data = 0; - break; + ch376->command = CH376_CMD_BYTE_READ; + dbg_printf("[WRITE][COMMAND][CH376_CMD_BYTE_READ] waiting for read size\n"); + ch376->pos_rw_in_cmd_data = 0; + break; case CH376_CMD_BYTE_RD_GO: - ch376->command = CH376_CMD_BYTE_RD_GO; - dbg_printf("[WRITE][COMMAND][CH376_CMD_BYTE_RD_GO] waiting for next chunk to read\n"); - file_read_chunk(ch376); - break; + ch376->command = CH376_CMD_BYTE_RD_GO; + dbg_printf("[WRITE][COMMAND][CH376_CMD_BYTE_RD_GO] waiting for next chunk to read\n"); + file_read_chunk(ch376); + break; case CH376_CMD_BYTE_WRITE: - ch376->command = CH376_CMD_BYTE_WRITE; - dbg_printf("[WRITE][COMMAND][CH376_CMD_BYTE_WRITE] waiting for write size\n"); - ch376->pos_rw_in_cmd_data = 0; - break; + ch376->command = CH376_CMD_BYTE_WRITE; + dbg_printf("[WRITE][COMMAND][CH376_CMD_BYTE_WRITE] waiting for write size\n"); + ch376->pos_rw_in_cmd_data = 0; + break; case CH376_CMD_BYTE_WR_GO: - ch376->command = CH376_CMD_BYTE_WR_GO; - dbg_printf("[WRITE][COMMAND][CH376_CMD_BYTE_WR_GO] waiting for next chunk to write\n"); - file_write_chunk(ch376); - break; + ch376->command = CH376_CMD_BYTE_WR_GO; + dbg_printf("[WRITE][COMMAND][CH376_CMD_BYTE_WR_GO] waiting for next chunk to write\n"); + file_write_chunk(ch376); + break; case CH376_CMD_FILE_CLOSE: - ch376->command = CH376_CMD_FILE_CLOSE; - dbg_printf("[WRITE][COMMAND][CH376_CMD_FILE_CLOSE] waiting for close mode\n"); - break; + ch376->command = CH376_CMD_FILE_CLOSE; + dbg_printf("[WRITE][COMMAND][CH376_CMD_FILE_CLOSE] waiting for close mode\n"); + break; default: - dbg_printf("[WRITE][COMMAND][Unsupported] command &%02x not implemented\n", ch376->command); - ch376->interface_status = 0; - ch376->command_status = CH376_RET_ABORT; - break; - } + dbg_printf("[WRITE][COMMAND][Unsupported] command &%02x not implemented\n", ch376->command); + ch376->interface_status = 0; + ch376->command_status = CH376_RET_ABORT; + break; + } - dbg_printf("<< [WRITE][COMMAND] Write command &%02x status &%02x\n", ch376->command, ch376->command_status); + dbg_printf("<< [WRITE][COMMAND] Write command &%02x status &%02x\n", ch376->command, ch376->command_status); } /* /// */ @@ -2330,196 +2457,214 @@ void ch376_write_data_port(struct ch376 *ch376, CH376_U8 data) switch(ch376->command) { case CH376_CMD_CHECK_EXIST: - ch376->cmd_data.CMD_CheckByte = ~data; - dbg_printf("[WRITE][DATA][CH376_CMD_CHECK_EXIST] got check byte &%02x\n", data); - break; + ch376->cmd_data.CMD_CheckByte = ~data; + dbg_printf("[WRITE][DATA][CH376_CMD_CHECK_EXIST] got check byte &%02x\n", data); + break; + + case CH376_CMD_READ_VAR32: + // dbg_printf("[WRITE][DATA][CH376_CMD_GET_FILE_SIZE] got &%02x byte\n", data); + if(data == CH376_VAR_FILE_SIZE) + { + CH376_S32 file_size = system_get_file_size(&ch376->context, ch376->current_file); + + ch376->cmd_data.CMD_VAR32[0] = (CH376_U8)((file_size & 0x000000ff) >> 0); + ch376->cmd_data.CMD_VAR32[1] = (CH376_U8)((file_size & 0x0000ff00) >> 8); + ch376->cmd_data.CMD_VAR32[2] = (CH376_U8)((file_size & 0x00ff0000) >> 16); + ch376->cmd_data.CMD_VAR32[3] = (CH376_U8)((file_size & 0xff000000) >> 24); + + ch376->nb_bytes_in_cmd_data = sizeof(ch376->cmd_data.CMD_VAR32); + ch376->pos_rw_in_cmd_data = 0; - case CH376_CMD_GET_FILE_SIZE: - // dbg_printf("[WRITE][DATA][CH376_CMD_GET_FILE_SIZE] got &%02x byte\n", data); - if (data == 0x68) - { - CH376_S32 file_size = system_get_file_size(&ch376->context, ch376->current_file); + dbg_printf("[WRITE][DATA][CH376_CMD_GET_FILE_SIZE] done, file size is %d, waiting for data read\n", file_size); - ch376->cmd_data.CMD_FileSize[0] = (CH376_U8)((file_size & 0x000000ff) >> 0); - ch376->cmd_data.CMD_FileSize[1] = (CH376_U8)((file_size & 0x0000ff00) >> 8); - ch376->cmd_data.CMD_FileSize[2] = (CH376_U8)((file_size & 0x00ff0000) >> 16); - ch376->cmd_data.CMD_FileSize[3] = (CH376_U8)((file_size & 0xff000000) >> 24); + // Lignes suivantes utiles? + ch376->interface_status = 127; + ch376->command_status = CH376_INT_SUCCESS; + } + else if(data == CH376_VAR_CURRENT_OFFSET) + { + CH376_S32 file_offset = system_get_file_offset(&ch376->context, ch376->current_file); + + ch376->cmd_data.CMD_VAR32[0] = (CH376_U8)((file_offset & 0x000000ff) >> 0); + ch376->cmd_data.CMD_VAR32[1] = (CH376_U8)((file_offset & 0x0000ff00) >> 8); + ch376->cmd_data.CMD_VAR32[2] = (CH376_U8)((file_offset & 0x00ff0000) >> 16); + ch376->cmd_data.CMD_VAR32[3] = (CH376_U8)((file_offset & 0xff000000) >> 24); + + ch376->nb_bytes_in_cmd_data = sizeof(ch376->cmd_data.CMD_VAR32); + ch376->pos_rw_in_cmd_data = 0; - ch376->nb_bytes_in_cmd_data = sizeof(ch376->cmd_data.CMD_FileSize); - ch376->pos_rw_in_cmd_data = 0; - - dbg_printf("[WRITE][DATA][CH376_CMD_GET_FILE_SIZE] done, file size is %d, waiting for data read\n", file_size); + dbg_printf("[WRITE][DATA][CH376_CMD_GET_FILE_OFFSET] done, file position is %d, waiting for data read\n", file_offset); - // Lignes suivantes utiles? - ch376->interface_status = 127; - ch376->command_status = CH376_INT_SUCCESS; - } - else - { - dbg_printf("[WRITE][DATA][CH376_CMD_GET_FILE_SIZE] wrong command byte: looking for &68, got &%02x\n", data); + // Lignes suivantes utiles? + ch376->interface_status = 127; + ch376->command_status = CH376_INT_SUCCESS; + } + else + { + dbg_printf("[WRITE][DATA][CH376_CMD_READ_VAR32] wrong command byte: looking for &68 or &6c, got &%02x\n", data); - ch376->interface_status = 0; - ch376->command_status = CH376_RET_ABORT; - } - break; + ch376->interface_status = 0; + ch376->command_status = CH376_RET_ABORT; + } + break; case CH376_CMD_SET_USB_MODE: - cancel_all_io(ch376); - switch(data) - { + cancel_all_io(ch376); + switch(data) + { case CH376_ARG_SET_USB_MODE_USB_HOST: - ch376->usb_mode = CH376_ARG_SET_USB_MODE_USB_HOST; - dbg_printf("[WRITE][DATA][CH376_SET_USB_MODE] USB host set\n"); - break; + ch376->usb_mode = CH376_ARG_SET_USB_MODE_USB_HOST; + dbg_printf("[WRITE][DATA][CH376_SET_USB_MODE] USB host set\n"); + break; case CH376_ARG_SET_USB_MODE_SD_HOST: - ch376->usb_mode = CH376_ARG_SET_USB_MODE_SD_HOST; - dbg_printf("[WRITE][DATA][CH376_SET_USB_MODE] SD card set\n"); - break; + ch376->usb_mode = CH376_ARG_SET_USB_MODE_SD_HOST; + dbg_printf("[WRITE][DATA][CH376_SET_USB_MODE] SD card set\n"); + break; default: - ch376->usb_mode = CH376_ARG_SET_USB_MODE_INVALID; - dbg_printf("[WRITE][DATA][CH376_SET_USB_MODE_CODE_INVALID] set\n"); - break; - } - break; + ch376->usb_mode = CH376_ARG_SET_USB_MODE_INVALID; + dbg_printf("[WRITE][DATA][CH376_SET_USB_MODE_CODE_INVALID] set\n"); + break; + } + break; case CH376_CMD_SET_FILE_NAME: - dbg_printf("[WRITE][DATA][CH376_CMD_SET_FILE_NAME] got file name character \"%c\" (&%02x) for position %d\n", data, data, ch376->pos_rw_in_cmd_data); - // protect buffer overflow - if(ch376->pos_rw_in_cmd_data < sizeof(ch376->cmd_data.CMD_FileName)) - { - // store new filename character - ch376->cmd_data.CMD_FileName[ch376->pos_rw_in_cmd_data++] = data; - ch376->cmd_data.CMD_FileName[ch376->pos_rw_in_cmd_data] = '\0'; -// ch376->current_file_is_directory = CH376_FALSE; - } - break; + dbg_printf("[WRITE][DATA][CH376_CMD_SET_FILE_NAME] got file name character \"%c\" (&%02x) for position %d\n", data, data, ch376->pos_rw_in_cmd_data); + // protect buffer overflow + if(ch376->pos_rw_in_cmd_data < sizeof(ch376->cmd_data.CMD_FileName)) + { + // store new filename character + ch376->cmd_data.CMD_FileName[ch376->pos_rw_in_cmd_data++] = data; + ch376->cmd_data.CMD_FileName[ch376->pos_rw_in_cmd_data] = '\0'; + // ch376->current_file_is_directory = CH376_FALSE; + } + break; case CH376_CMD_BYTE_LOCATE: - if(ch376->pos_rw_in_cmd_data < sizeof(ch376->cmd_data.CMD_FileSeek)) + if(ch376->pos_rw_in_cmd_data < sizeof(ch376->cmd_data.CMD_FileSeek)) + { + dbg_printf("[WRITE][DATA][CH376_CMD_BYTE_LOCATE] got byte #%d with value &%02x\n", ch376->pos_rw_in_cmd_data, data); + ch376->cmd_data.CMD_FileSeek[ch376->pos_rw_in_cmd_data] = data; + + if(++ch376->pos_rw_in_cmd_data == sizeof(ch376->cmd_data.CMD_FileSeek)) { - dbg_printf("[WRITE][DATA][CH376_CMD_BYTE_LOCATE] got byte #%d with value &%02x\n", ch376->pos_rw_in_cmd_data, data); - ch376->cmd_data.CMD_FileSeek[ch376->pos_rw_in_cmd_data] = data; + CH376_S32 file_seek_pos = (ch376->cmd_data.CMD_FileSeek[0] << 0) + | (ch376->cmd_data.CMD_FileSeek[1] << 8) + | (ch376->cmd_data.CMD_FileSeek[2] << 16) + | (ch376->cmd_data.CMD_FileSeek[3] << 24); - if(++ch376->pos_rw_in_cmd_data == sizeof(ch376->cmd_data.CMD_FileSeek)) - { - CH376_S32 file_seek_pos = (ch376->cmd_data.CMD_FileSeek[0] << 0) - | (ch376->cmd_data.CMD_FileSeek[1] << 8) - | (ch376->cmd_data.CMD_FileSeek[2] << 16) - | (ch376->cmd_data.CMD_FileSeek[3] << 24); - - file_seek_pos = system_file_seek(&ch376->context, ch376->current_file, file_seek_pos); - - if(file_seek_pos >= 0) - { - dbg_printf("[WRITE][DATA][CH376_CMD_BYTE_LOCATE] all done: seek operated with success (waiting for data read)\n"); - - ch376->cmd_data.CMD_FileSeek[0] = (CH376_U8)((file_seek_pos & 0x000000ff) >> 0); - ch376->cmd_data.CMD_FileSeek[1] = (CH376_U8)((file_seek_pos & 0x0000ff00) >> 8); - ch376->cmd_data.CMD_FileSeek[2] = (CH376_U8)((file_seek_pos & 0x00ff0000) >> 16); - ch376->cmd_data.CMD_FileSeek[3] = (CH376_U8)((file_seek_pos & 0xff000000) >> 24); - - ch376->nb_bytes_in_cmd_data = sizeof(ch376->cmd_data.CMD_FileSeek); - ch376->interface_status = 127; - ch376->command_status = CH376_INT_SUCCESS; - } - else - { - dbg_printf("[WRITE][DATA][CH376_CMD_BYTE_LOCATE] all done: seek failure\n"); - - ch376->interface_status = 0; - ch376->command_status = CH376_RET_ABORT; - } - } - } - break; + file_seek_pos = system_file_seek(&ch376->context, ch376->current_file, file_seek_pos); - case CH376_CMD_WR_REQ_DATA: - if(ch376->nb_bytes_in_cmd_data - && ch376->pos_rw_in_cmd_data != CMD_DATA_REQ_SIZE) - { - CH376_U8 *raw = (CH376_U8 *)&ch376->cmd_data; + if(file_seek_pos >= 0) + { + dbg_printf("[WRITE][DATA][CH376_CMD_BYTE_LOCATE] all done: seek operated with success (waiting for data read)\n"); - if(ch376->nb_bytes_in_cmd_data != ch376->pos_rw_in_cmd_data) - { - raw[ch376->pos_rw_in_cmd_data] = data; + ch376->cmd_data.CMD_FileSeek[0] = (CH376_U8)((file_seek_pos & 0x000000ff) >> 0); + ch376->cmd_data.CMD_FileSeek[1] = (CH376_U8)((file_seek_pos & 0x0000ff00) >> 8); + ch376->cmd_data.CMD_FileSeek[2] = (CH376_U8)((file_seek_pos & 0x00ff0000) >> 16); + ch376->cmd_data.CMD_FileSeek[3] = (CH376_U8)((file_seek_pos & 0xff000000) >> 24); - dbg_printf("[WRITE][DATA][CH376_CMD_WR_REQ_DATA] write \"%c\" (&%02x) to i/o buffer at position &%02x\n", data, data, ch376->pos_rw_in_cmd_data); + ch376->nb_bytes_in_cmd_data = sizeof(ch376->cmd_data.CMD_FileSeek); + ch376->interface_status = 127; + ch376->command_status = CH376_INT_SUCCESS; + } + else + { + dbg_printf("[WRITE][DATA][CH376_CMD_BYTE_LOCATE] all done: seek failure\n"); - if(++ch376->pos_rw_in_cmd_data == ch376->nb_bytes_in_cmd_data) - { - ch376->interface_status = 0; - ch376->command_status = CH376_RET_SUCCESS; - } - } + ch376->interface_status = 0; + ch376->command_status = CH376_RET_ABORT; + } } - else + } + break; + + case CH376_CMD_WR_REQ_DATA: + if(ch376->nb_bytes_in_cmd_data + && ch376->pos_rw_in_cmd_data != CMD_DATA_REQ_SIZE) + { + CH376_U8 *raw = (CH376_U8 *)&ch376->cmd_data; + + if(ch376->nb_bytes_in_cmd_data != ch376->pos_rw_in_cmd_data) { - dbg_printf("[WRITE][DATA][CH376_CMD_WR_REQ_DATA] nothing to write to i/o buffer\n"); + raw[ch376->pos_rw_in_cmd_data] = data; + dbg_printf("[WRITE][DATA][CH376_CMD_WR_REQ_DATA] write \"%c\" (&%02x) to i/o buffer at position &%02x\n", data, data, ch376->pos_rw_in_cmd_data); + + if(++ch376->pos_rw_in_cmd_data == ch376->nb_bytes_in_cmd_data) + { ch376->interface_status = 0; - ch376->command_status = CH376_RET_ABORT; + ch376->command_status = CH376_RET_SUCCESS; + } } - break; + } + else + { + dbg_printf("[WRITE][DATA][CH376_CMD_WR_REQ_DATA] nothing to write to i/o buffer\n"); + + ch376->interface_status = 0; + ch376->command_status = CH376_RET_ABORT; + } + break; case CH376_CMD_BYTE_READ: - if(ch376->pos_rw_in_cmd_data < sizeof(ch376->cmd_data.CMD_FileReadWrite)) - { - dbg_printf("[WRITE][DATA][CH376_CMD_BYTE_READ] got byte #%d with value &%02x\n", ch376->pos_rw_in_cmd_data, data); - ch376->cmd_data.CMD_FileReadWrite[ch376->pos_rw_in_cmd_data] = data; + if(ch376->pos_rw_in_cmd_data < sizeof(ch376->cmd_data.CMD_FileReadWrite)) + { + dbg_printf("[WRITE][DATA][CH376_CMD_BYTE_READ] got byte #%d with value &%02x\n", ch376->pos_rw_in_cmd_data, data); + ch376->cmd_data.CMD_FileReadWrite[ch376->pos_rw_in_cmd_data] = data; - if(++ch376->pos_rw_in_cmd_data == sizeof(ch376->cmd_data.CMD_FileReadWrite)) - { - ch376->bytes_to_read_write = (ch376->cmd_data.CMD_FileReadWrite[0] << 0) - | (ch376->cmd_data.CMD_FileReadWrite[1] << 8); - file_read_chunk(ch376); - } + if(++ch376->pos_rw_in_cmd_data == sizeof(ch376->cmd_data.CMD_FileReadWrite)) + { + ch376->bytes_to_read_write = (ch376->cmd_data.CMD_FileReadWrite[0] << 0) + | (ch376->cmd_data.CMD_FileReadWrite[1] << 8); + file_read_chunk(ch376); } - break; + } + break; case CH376_CMD_BYTE_WRITE: - if(ch376->pos_rw_in_cmd_data < sizeof(ch376->cmd_data.CMD_FileReadWrite)) - { - dbg_printf("[WRITE][DATA][CH376_CMD_BYTE_WRITE] got byte #%d with value &%02x\n", ch376->pos_rw_in_cmd_data, data); - ch376->cmd_data.CMD_FileReadWrite[ch376->pos_rw_in_cmd_data] = data; + if(ch376->pos_rw_in_cmd_data < sizeof(ch376->cmd_data.CMD_FileReadWrite)) + { + dbg_printf("[WRITE][DATA][CH376_CMD_BYTE_WRITE] got byte #%d with value &%02x\n", ch376->pos_rw_in_cmd_data, data); + ch376->cmd_data.CMD_FileReadWrite[ch376->pos_rw_in_cmd_data] = data; - if(++ch376->pos_rw_in_cmd_data == sizeof(ch376->cmd_data.CMD_FileReadWrite)) - { - ch376->bytes_to_read_write = (ch376->cmd_data.CMD_FileReadWrite[0] << 0) - | (ch376->cmd_data.CMD_FileReadWrite[1] << 8); + if(++ch376->pos_rw_in_cmd_data == sizeof(ch376->cmd_data.CMD_FileReadWrite)) + { + ch376->bytes_to_read_write = (ch376->cmd_data.CMD_FileReadWrite[0] << 0) + | (ch376->cmd_data.CMD_FileReadWrite[1] << 8); - if(ch376->bytes_to_read_write > sizeof(ch376->cmd_data.CMD_IOBuffer)) - ch376->nb_bytes_in_cmd_data = sizeof(ch376->cmd_data.CMD_IOBuffer); - else - ch376->nb_bytes_in_cmd_data = (CH376_U8)ch376->bytes_to_read_write; + if(ch376->bytes_to_read_write > sizeof(ch376->cmd_data.CMD_IOBuffer)) + ch376->nb_bytes_in_cmd_data = sizeof(ch376->cmd_data.CMD_IOBuffer); + else + ch376->nb_bytes_in_cmd_data = (CH376_U8)ch376->bytes_to_read_write; - ch376->interface_status = 127; - ch376->command_status = CH376_INT_SUCCESS; - } + ch376->interface_status = 127; + ch376->command_status = CH376_INT_SUCCESS; } - break; + } + break; case CH376_CMD_FILE_CLOSE: - // Note: close mode is not implemented; size if always updated - dbg_printf("[WRITE][DATA][CH376_CMD_FILE_CLOSE] update size: %s\n", ch376->pos_rw_in_cmd_data == 0 ? "no" : "yes"); - if(ch376->current_file) - { - system_file_close(&ch376->context, ch376->current_file); - ch376->current_file = (CH376_FILE)0; + // Note: close mode is not implemented; size if always updated + dbg_printf("[WRITE][DATA][CH376_CMD_FILE_CLOSE] update size: %s\n", ch376->pos_rw_in_cmd_data == 0 ? "no" : "yes"); + if(ch376->current_file) + { + system_file_close(&ch376->context, ch376->current_file); + ch376->current_file = (CH376_FILE)0; - ch376->interface_status = 127; - ch376->command_status = CH376_INT_SUCCESS; - } - else - { - dbg_printf("[WRITE][DATA][CH376_CMD_FILE_CLOSE] failure: not file opened\n"); + ch376->interface_status = 127; + ch376->command_status = CH376_INT_SUCCESS; + } + else + { + dbg_printf("[WRITE][DATA][CH376_CMD_FILE_CLOSE] failure: not file opened\n"); - ch376->interface_status = 0; - ch376->command_status = CH376_RET_ABORT; - } - break; - } + ch376->interface_status = 0; + ch376->command_status = CH376_RET_ABORT; + } + break; + } - dbg_printf("<< [WRITE][DATA] Write data &%02x status &%02x\n", data, ch376->command_status); + dbg_printf("<< [WRITE][DATA] Write data &%02x status &%02x\n", data, ch376->command_status); } @@ -2527,69 +2672,69 @@ void ch376_write_data_port(struct ch376 *ch376, CH376_U8 data) /* /// "CH376 public init & clean" */ -struct ch376 * ch376_create(void *user_data) +struct ch376 * ch376_create(void* user_data) { - struct ch376 *ch376 = system_alloc_mem(sizeof(struct ch376)); + struct ch376 *ch376 = system_alloc_mem(sizeof(struct ch376)); - if(ch376) + if(ch376) + { + if(system_init_context(&ch376->context, user_data)) { - if(system_init_context(&ch376->context, user_data)) - { - ch376->sdcard_drive_path = clone_string("ch376_sdcard_drive/"); - ch376->usb_drive_path = clone_string("ch376_usb_drive/"); - clear_structure(ch376); - } - else - { - system_free_mem(ch376); - ch376 = NULL; - } + ch376->sdcard_drive_path = clone_string("ch376_sdcard_drive/"); + ch376->usb_drive_path = clone_string("ch376_usb_drive/"); + clear_structure(ch376); + } + else + { + system_free_mem(ch376); + ch376 = NULL; } - return ch376; + } + return ch376; } void ch376_destroy(struct ch376 *ch376) { - cancel_all_io(ch376); - system_free_mem(ch376->sdcard_drive_path); - system_free_mem(ch376->usb_drive_path); - system_clean_context(&ch376->context); - system_free_mem(ch376); + cancel_all_io(ch376); + system_free_mem(ch376->sdcard_drive_path); + system_free_mem(ch376->usb_drive_path); + system_clean_context(&ch376->context); + system_free_mem(ch376); } void ch376_reset(struct ch376 *ch376) { - cancel_all_io(ch376); - clear_structure(ch376); + cancel_all_io(ch376); + clear_structure(ch376); } /* /// */ /* /// "CH376 public configuration" */ -void ch376_set_sdcard_drive_path(struct ch376 *ch376, const char *path) +void ch376_set_sdcard_drive_path(struct ch376 *ch376, const char* path) { - dbg_printf("ch376_set_sdcard_drive_path: %s\n", path); - cancel_all_io(ch376); - system_free_mem(ch376->sdcard_drive_path); - ch376->sdcard_drive_path = clone_string(path); + dbg_printf("ch376_set_sdcard_drive_path: %s\n", path); + cancel_all_io(ch376); + system_free_mem(ch376->sdcard_drive_path); + ch376->sdcard_drive_path = clone_string(path); } -void ch376_set_usb_drive_path(struct ch376 *ch376, const char *path) +void ch376_set_usb_drive_path(struct ch376 *ch376, const char* path) { - dbg_printf("ch376_set_usb_drive_path: %s\n", path); - cancel_all_io(ch376); - system_free_mem(ch376->usb_drive_path); - ch376->usb_drive_path = clone_string(path); + dbg_printf("ch376_set_usb_drive_path: %s\n", path); + cancel_all_io(ch376); + system_free_mem(ch376->usb_drive_path); + ch376->usb_drive_path = clone_string(path); } -const char * ch376_get_sdcard_drive_path(struct ch376 *ch376) +const char* ch376_get_sdcard_drive_path(struct ch376 *ch376) { - return ch376->sdcard_drive_path; + return ch376->sdcard_drive_path; } -const char * ch376_get_usb_drive_path(struct ch376 *ch376) +const char* ch376_get_usb_drive_path(struct ch376 *ch376) { - return ch376->usb_drive_path; + return ch376->usb_drive_path; } /* /// */ diff --git a/plugins/ch376/ch376.h b/plugins/ch376/ch376.h index fe8cb32b..38adacb7 100644 --- a/plugins/ch376/ch376.h +++ b/plugins/ch376/ch376.h @@ -37,7 +37,10 @@ typedef BOOL CH376_BOOL; typedef BPTR CH376_FILE; typedef BPTR CH376_LOCK; typedef struct FileInfoBlock * CH376_DIR; -typedef struct { struct Library *DOSBase; } CH376_CONTEXT; +typedef struct +{ + struct Library *DOSBase; +} CH376_CONTEXT; #define CH376_TRUE TRUE #define CH376_FALSE FALSE @@ -60,10 +63,17 @@ typedef UINT64 CH376_U64; typedef INT64 CH376_S64; typedef BOOL CH376_BOOL; typedef HANDLE CH376_FILE; -typedef struct _CH376_LOCK { TCHAR path[MAX_PATH]; HANDLE handle; } * CH376_LOCK; +typedef struct _CH376_LOCK +{ + TCHAR path[MAX_PATH]; + HANDLE handle; +} * CH376_LOCK; typedef WIN32_FIND_DATA * CH376_DIR; -typedef struct { void *dummy; } CH376_CONTEXT; +typedef struct +{ + void* dummy; +} CH376_CONTEXT; #define CH376_TRUE TRUE #define CH376_FALSE FALSE @@ -87,9 +97,16 @@ typedef uint64_t CH376_U64; typedef int64_t CH376_S64; typedef bool CH376_BOOL; typedef FILE * CH376_FILE; -typedef char * CH376_LOCK; -typedef struct _CH376_DIR { DIR *handle; struct dirent *entry; } * CH376_DIR; -typedef struct { void *dummy; } CH376_CONTEXT; +typedef char* CH376_LOCK; +typedef struct _CH376_DIR +{ + DIR *handle; + struct dirent *entry; +} * CH376_DIR; +typedef struct +{ + void* dummy; +} CH376_CONTEXT; #define CH376_TRUE true #define CH376_FALSE false @@ -109,15 +126,15 @@ typedef struct { void *dummy; } CH376_CONTEXT; struct ch376; // Initialization -struct ch376 * ch376_create(void *user_data); +struct ch376 * ch376_create(void* user_data); void ch376_destroy(struct ch376 *ch376); void ch376_reset(struct ch376 *ch376); // Configuration -void ch376_set_sdcard_drive_path(struct ch376 *ch376, const char *path); -void ch376_set_usb_drive_path(struct ch376 *ch376, const char *path); -const char * ch376_get_sdcard_drive_path(struct ch376 *ch376); -const char * ch376_get_usb_drive_path(struct ch376 *ch376); +void ch376_set_sdcard_drive_path(struct ch376 *ch376, const char* path); +void ch376_set_usb_drive_path(struct ch376 *ch376, const char* path); +const char* ch376_get_sdcard_drive_path(struct ch376 *ch376); +const char* ch376_get_usb_drive_path(struct ch376 *ch376); // Runtime void ch376_write_command_port(struct ch376 *ch376, CH376_U8 command); diff --git a/plugins/ch376/oric_ch376_plugin.c b/plugins/ch376/oric_ch376_plugin.c index 0ad31017..9a6dbb12 100644 --- a/plugins/ch376/oric_ch376_plugin.c +++ b/plugins/ch376/oric_ch376_plugin.c @@ -15,61 +15,60 @@ #include "ch376.h" #include "stdio.h" -void dbg_printf(char *fmt, ...); +void dbg_printf(char* fmt, ...); -#define CH376_ORIC_EXTENSION_DATA_PORT 0x340 -#define CH376_ORIC_EXTENSION_COMMAND_PORT 0x341 +#define CH376_ORIC_EXTENSION_DATA_PORT 0x340 +#define CH376_ORIC_EXTENSION_COMMAND_PORT 0x341 struct ch376 * ch376_oric_init() { - return ch376_create(NULL); + return ch376_create(NULL); } void ch376_oric_reset(struct ch376 *ch376) { - ch376_reset(ch376); + ch376_reset(ch376); } void ch376_oric_destroy(struct ch376 *ch376) { - ch376_destroy(ch376); + ch376_destroy(ch376); } void ch376_oric_config(struct ch376 *ch376) { - ch376_set_sdcard_drive_path(ch376, "sdcard/"); - ch376_set_usb_drive_path(ch376, "usbdrive/"); + ch376_set_sdcard_drive_path(ch376, "sdcard/"); + ch376_set_usb_drive_path(ch376, "usbdrive/"); } -void ch376_oric_write(struct ch376 *ch376, Uint16 addr, Uint8 data) +void ch376_oric_write(struct ch376 *ch376, Uint16 addr, Uint8 data) { - if (addr == CH376_ORIC_EXTENSION_DATA_PORT) - { - ch376_write_data_port(ch376, data); - } + if(addr == CH376_ORIC_EXTENSION_DATA_PORT) + { + ch376_write_data_port(ch376, data); + } - if (addr == CH376_ORIC_EXTENSION_COMMAND_PORT) - { - ch376_write_command_port(ch376, data); - } + if(addr == CH376_ORIC_EXTENSION_COMMAND_PORT) + { + ch376_write_command_port(ch376, data); + } } - -unsigned char ch376_oric_read(struct ch376 *ch376, Uint16 addr) +unsigned char ch376_oric_read(struct ch376 *ch376, Uint16 addr) { - unsigned char temp; - if (addr == CH376_ORIC_EXTENSION_DATA_PORT) - { - temp=ch376_read_data_port(ch376); - return temp; - } + unsigned char temp; + if(addr == CH376_ORIC_EXTENSION_DATA_PORT) + { + temp=ch376_read_data_port(ch376); + return temp; + } - if (addr == CH376_ORIC_EXTENSION_COMMAND_PORT) - { - temp=ch376_read_command_port(ch376); - return temp; - } - return 0; + if(addr == CH376_ORIC_EXTENSION_COMMAND_PORT) + { + temp=ch376_read_command_port(ch376); + return temp; + } + return 0; } diff --git a/plugins/ch376/oric_ch376_plugin.h b/plugins/ch376/oric_ch376_plugin.h index 4701665a..2c26542d 100644 --- a/plugins/ch376/oric_ch376_plugin.h +++ b/plugins/ch376/oric_ch376_plugin.h @@ -1,7 +1,7 @@ struct ch376 * ch376_oric_init(void); void ch376_oric_reset(struct ch376 *ch376); -void ch376_oric_write(struct ch376 *ch376, Uint16 addr, Uint8 data); -unsigned char ch376_oric_read(struct ch376 *ch376, Uint16 addr); +void ch376_oric_write(struct ch376 *ch376, Uint16 addr, Uint8 data); +unsigned char ch376_oric_read(struct ch376 *ch376, Uint16 addr); void ch376_oric_config(struct ch376 *ch376); void ch376_oric_destroy(struct ch376 *ch376); void ch376_oric_reset(struct ch376 *ch376); diff --git a/plugins/twilighte_board/README.md b/plugins/twilighte_board/README.md new file mode 100644 index 00000000..92046876 --- /dev/null +++ b/plugins/twilighte_board/README.md @@ -0,0 +1,7 @@ +# Twilighte board emulation + +## Firmware 1 vs Firmware 2 + +Firmware 2 manage a mirroring of ram overlay management in $314. + +It means that firmware 2, when $314 select internal ram overlay in the oric, it selects instead bank 0 (RAM) of the twilighte board. diff --git a/plugins/twilighte_board/oric_twilighte_board_plugin.c b/plugins/twilighte_board/oric_twilighte_board_plugin.c new file mode 100644 index 00000000..e9d969d8 --- /dev/null +++ b/plugins/twilighte_board/oric_twilighte_board_plugin.c @@ -0,0 +1,474 @@ +/******************************************************************** + * * + * Twilighte board emulation * + * * + * Code: * + * Jérôme 'Jede' Debrune * + * Philippe 'OffseT' Rimauro * + * Christian 'Assinie' Lardière * + * * + ** ch376.c *********************************************************/ + +/* + Changes: + XX.XX.2022 - Assinie: Fix bug in banking management + XX.12.2022 - Jede: Firmware 1 and Firmware 2 management. + XX.12.2022 - Now we can attach a microdisc controler with the Twilighte board (as on real hardware : microdisc or cumulus) +*/ + +#define TWILIGHTE_CARD_ORIC_EXTENSION_MIRROR_314 0x314 +#define TWILIGHTE_CARD_ORIC_EXTENSION_DDRA 0x323 +#define TWILIGHTE_CARD_ORIC_EXTENSION_IORAh 0x321 + +#define TWILIGHTE_CARD_ORIC_EXTENSION_DDRB 0x322 +#define TWILIGHTE_CARD_ORIC_EXTENSION_IORB 0x320 + +#define TWILIGHTE_CARD_ORIC_EXTENSION_REGISTER 0x342 +#define TWILIGHTE_CARD_ORIC_EXTENSION_BANKING_REGISTER 0x343 + +/* + * Port B + * 7 6 5 4 3 2 1 0 + * U D F L R + * +-> select left port + * +---> select right port + * + * Port A + * 7 6 5 4 3 2 1 0 + * +---+---> Bank # + * +--> Fire 3 + * +------> Fire 2 + * + * DDRx: bit à 0 => bit en entrée + * bit à 1 => bit en sortie +*/ + +#include +#include +#include +#include +#include + +#include "../../system_sdl.h" + +SDL_bool read_config_int(char* buf, char* token, int* dest, int min, int max); +SDL_bool read_config_bool(char* buf, char* token, SDL_bool* dest); + + +#include "../../system.h" +#include "oric_twilighte_board_plugin.h" + +extern SDL_bool read_config_string(char* buf, char* token, char* dest, Sint32 maxlen); + +static SDL_bool load_rom_twilighte(char* fname, int size, unsigned char where[]) +{ + SDL_RWops* f; + char* tmpname; + + // MinGW doesn't have asprintf :-( + tmpname = malloc(strlen(fname) + 10); + if(!tmpname) + { + + return SDL_FALSE; + } + + sprintf(tmpname, "%s.rom", fname); + f = SDL_RWFromFile(tmpname, "rb"); + if(!f) + { + error_printf("Unable to open '%s'\n", tmpname); + free(tmpname); + return SDL_FALSE; + } + + if(size < 0) + { + int filesize; + SDL_RWseek(f, 0, SEEK_END); + filesize = SDL_RWtell(f); + SDL_RWseek(f, 0, SEEK_SET); + + if(filesize > -size) + { + error_printf("ROM '%s' exceeds %d bytes.\n", fname, -size); + SDL_RWclose(f); + free(tmpname); + return SDL_FALSE; + } + + where += (-size) - filesize; + size = filesize; + } + + if(SDL_RWread(f, where, size, 1) != 1) + { + error_printf("Unable to read '%s'\n", tmpname); + SDL_RWclose(f); + free(tmpname); + return SDL_FALSE; + } + + SDL_RWclose(f); + free(tmpname); + return SDL_TRUE; +} + +struct twilighte* twilighte_oric_init(void) +{ + + FILE* f; + unsigned int i, j; + char* result; + char tbtmp[32]; + char tbtmpram[32]; + char line[1024]; + struct twilighte* twilighte = malloc(sizeof(struct twilighte)); + twilighte->t_banking_register = 0; + twilighte->microdisc=SDL_FALSE; + + twilighte->t_register = 128 + 1; // Firmware + + f = fopen("plugins/twilighte_board/twilighte.cfg", "r"); + if(!f) + { + error_printf("plugins/twilighte_board/twilighte.cfg not found\n"); + return NULL; + } + + for(j = 0; j < 32; j++) + { + twilighte->twilrombankfiles[j][0] = 0; + twilighte->twilrambankfiles[j][0] = 0; + } + + while(!feof(f)) + { + result = fgets(line, 1024, f); + if(result) + { + // FIXME: do something to silence the compiler warning ... + } + + if(read_config_int(line, "firmware", &twilighte->firmware_version, 1, 3)) + { + // because we initialize board version to 1. If firmware_version is set, then we have a look to firmware_version. + // If it's equal to 1, then do not overlap the value + if(twilighte->firmware_version!=1) + { + twilighte->t_register=twilighte->t_register&0b11111110; // Remove bit 0 (firmware 1 which is the default when the .cfg does not contain firmware version) + twilighte->t_register = twilighte->t_register | (twilighte->firmware_version); + } + continue; + } + + if(read_config_bool(line, "microdisc", &twilighte->microdisc)) continue; + + for(j = 0; j < 32; j++) + { + sprintf(tbtmp, "twilbankrom%02d", j+1); + sprintf(tbtmpram, "twilbankram%02d", j+1); + + if(twilighte->twilrombankfiles[j][0] == 0) + { + if(read_config_string(line, tbtmp, twilighte->twilrombankfiles[j], 1024)) + { + break; + } + } + + if(twilighte->twilrambankfiles[j][0] == 0) + { + if(read_config_string(line, tbtmpram, twilighte->twilrambankfiles[j], 1024)) + { + break; + } + } + + } + } + + fclose(f); + + // Now load rom + for(i = 0; i < 32; i++) + { + if(twilighte->twilrombankfiles[i][0] != 0) + { + //error_printf("Load bank (ROM) #%d: %s", i, twilighte->twilrombankfiles[i]); + if(!load_rom_twilighte(twilighte->twilrombankfiles[i], -16384, twilighte->twilrombankdata[i])) + { + error_printf("Cannot load %s", twilighte->twilrombankfiles[i]); + return NULL; + } + } + + if(twilighte->twilrambankfiles[i][0] != 0) + { + //error_printf("Load bank (RAM) #%d: %s", i, twilighte->twilrambankfiles[i]); + if(!load_rom_twilighte(twilighte->twilrambankfiles[i], -16384, twilighte->twilrambankdata[i])) + { + error_printf("Cannot load %s", twilighte->twilrambankfiles[i]); + return NULL; + } + } + + } + + // Flush sram (first bank) + // for (j = 0; j < 16384; j++) twilighte->twilrambankdata[0][j] = 0; + + twilighte->IORAh = 0x07; + twilighte->DDRA = 0b10100111; + twilighte->current_bank = 7; + twilighte->IORB = 0; + twilighte->DDRB = 0b11000000; + twilighte->mirror_0x314_write_detected=SDL_FALSE; + + // It's not really the behavior of the firmware 2, because it initialize 0X314 internal register of the twilighte board to 0 + if(twilighte->firmware_version==2) + twilighte->mirror_0x314=2; + + return twilighte; +} + +unsigned char twilighte_board_mapping_software_bank(struct twilighte *twilighte) +{ + + unsigned char bank=0; + int current_bank = twilighte->IORAh & 0x07; + // RAM Overlay? + if(current_bank == 0) + bank = 0; + // Bank 7 downto 5 are always the same bank on any set + else if((current_bank >=5) && (current_bank <=7)) + bank = current_bank; + // ROM + else if((twilighteboard_oric_read(twilighte, 0x342) & 0x20)==0 && twilighteboard_oric_read(twilighte, 0x343)<=3 && twilighteboard_oric_read(twilighte, 0x343)>=1) + { + bank = current_bank+4*(twilighteboard_oric_read(twilighte, 0x343)+1); + } + else if((twilighteboard_oric_read(twilighte, 0x342) & 0x20)==0 && twilighteboard_oric_read(twilighte, 0x343)<=3 && twilighteboard_oric_read(twilighte, 0x343)==0) + { + bank = current_bank; + } + else if((current_bank >=1) && (current_bank <=4) && (twilighteboard_oric_read(twilighte, 0x342) & 0x20)==0 && twilighteboard_oric_read(twilighte, 0x343)>4) + { + bank = current_bank+4*twilighteboard_oric_read(twilighte, 0x343); + } + // Special case for bank 8,7,6,5 + else if((twilighteboard_oric_read(twilighte, 0x342) & 0x20)==0 && twilighteboard_oric_read(twilighte, 0x343)==4) + { + bank = current_bank+4; + } + // RAM + else if((current_bank >=1) && (current_bank <=4) && (twilighteboard_oric_read(twilighte, 0x342) & 0x20)==0x20) + bank = current_bank+4*twilighteboard_oric_read(twilighte, 0x343)+32; + + + return bank; +} + +unsigned char twilighte_board_mapping_bank(struct twilighte *twilighte) +{ + unsigned char bank; + // RAM Overlay? + if(twilighte->current_bank == 0) + bank = 7; + + // ROM + else if((twilighte->current_bank >=5) && (twilighte->current_bank <=7)) + bank = twilighte->current_bank-1; + + // ROM/RAM fonction du bit5 de twilighte->t_register + else if(twilighte->t_banking_register < 4) + bank = (twilighte->current_bank-1+twilighte->t_banking_register*8); + + // ROM/RAM fonction du bit5 de twilighte->t_register + else if(twilighte->t_banking_register >= 4) + bank = (twilighte->current_bank+3+(twilighte->t_banking_register & 3)*8); + + // Valeurs invalides + else + error_printf("Banking error: bank=%d, set=%d", twilighte->current_bank, twilighte->t_banking_register); + + // error_printf("Banking[0]: set=%d, bank=%d ram/rom=%x => %d", twilighte->t_banking_register, twilighte->current_bank, (twilighte->t_register >> 5) & 1, bank); + return bank; +} + +unsigned char twilighteboard_oric_ROM_RAM_read(struct twilighte* twilighte, uint16_t addr) +{ + unsigned char data; + unsigned char bank; + + if(twilighte->firmware_version==2) + { + if(twilighte->mirror_0x314_write_detected==SDL_TRUE) + { + if((twilighte->mirror_0x314&2)==0) + twilighte->current_bank = 0; + else + { + twilighte->current_bank = 6; + twilighte->t_banking_register=0; + twilighte->t_register=twilighte->t_register&0b1101111; + } + } + } + + if(twilighte->current_bank == 0) + { + data = twilighte->twilrambankdata[7][addr]; + } + else + { + bank=twilighte_board_mapping_bank(twilighte); + + if((twilighte->t_register&32)==32 && twilighte->current_bank<5) // Is it a ram bank access ? + data=twilighte->twilrambankdata[bank][addr]; + else + data=twilighte->twilrombankdata[bank][addr]; + } + return data; +} + +unsigned char twilighteboard_oric_ROM_RAM_write(struct twilighte* twilighte, uint16_t addr, unsigned char data) +{ + + unsigned char bank; + + if(twilighte->firmware_version==2) + { + if(twilighte->mirror_0x314_write_detected==SDL_TRUE) + { + if((twilighte->mirror_0x314&2)==0) + twilighte->current_bank = 0; + else + { + twilighte->current_bank = 6; + twilighte->t_banking_register=0; + twilighte->t_register=twilighte->t_register&0b1101111; + } + } + } + + + if(twilighte->current_bank == 0) + { + twilighte->twilrambankdata[7][addr] = data; + } + else + { + bank=twilighte_board_mapping_bank(twilighte); + + if((twilighte->t_register&32)==32 && twilighte->current_bank<5) // Is it a ram bank access ? + twilighte->twilrambankdata[bank][addr]=data; + + // ROM is readonly + //else + // error_printf("Flash write: set=%d, bank=%d ram/rom=%x => %d, address=%04x, data=%02x", twilighte->t_banking_register, twilighte->current_bank, (twilighte->t_register >> 5) & 1, bank, addr, data); + } + return 0; +} + + +unsigned char twilighteboard_oric_read(struct twilighte* twilighte, uint16_t addr) +{ + if(addr == TWILIGHTE_CARD_ORIC_EXTENSION_REGISTER) + { + return twilighte->t_register; + } + + if(addr == TWILIGHTE_CARD_ORIC_EXTENSION_DDRA) + { + return twilighte->DDRA; + } + + if(addr == TWILIGHTE_CARD_ORIC_EXTENSION_IORAh) + { + return twilighte->IORAh; + } + + if(addr == TWILIGHTE_CARD_ORIC_EXTENSION_DDRB) + { + return twilighte->DDRB; + } + + if(addr == TWILIGHTE_CARD_ORIC_EXTENSION_IORB) + { + return twilighte->IORB; + } + + if(addr == TWILIGHTE_CARD_ORIC_EXTENSION_BANKING_REGISTER) + { + return twilighte->t_banking_register; + } + + // In firmware mode 2, $314 is not returned by the twilighte board + // $314 is only writen in order to have information of the state of the overlay ram + // $314 register is returned by the disk controler + // That is why, it never returns here $314 register from the twilighte board register + + return 0; +} + +unsigned char twilighteboard_oric_write(struct twilighte* twilighte, uint16_t addr, unsigned char mask, unsigned char data) +{ + // mask: $00 => lecture/écriture via + // mask: $ff => mise à jour du port joystick + + if(addr == TWILIGHTE_CARD_ORIC_EXTENSION_DDRA) + { + twilighte->DDRA = data; + } + + if(addr == TWILIGHTE_CARD_ORIC_EXTENSION_IORAh) + { + + if(mask == 0) + twilighte->IORAh = data & twilighte->DDRA; + else + twilighte->IORAh = (twilighte->IORAh & twilighte->DDRA) | (data & (twilighte->DDRA ^ 0xff)); + + twilighte->current_bank = twilighte->IORAh & 7; + } + + if(addr == TWILIGHTE_CARD_ORIC_EXTENSION_DDRB) + { + twilighte->DDRB = data; + } + + if(addr == TWILIGHTE_CARD_ORIC_EXTENSION_IORB) + { + + if(mask == 0) + twilighte->IORB = data & twilighte->DDRB; + else + twilighte->IORB = (twilighte->IORB & twilighte->DDRB) | (data & (twilighte->DDRB ^ 0xff)); + } + + if(addr == TWILIGHTE_CARD_ORIC_EXTENSION_REGISTER) + { + twilighte->t_register = data; + } + + if(addr == TWILIGHTE_CARD_ORIC_EXTENSION_BANKING_REGISTER) + { + twilighte->t_banking_register = data; + } + + if(twilighte->firmware_version==2) + { + if(addr == TWILIGHTE_CARD_ORIC_EXTENSION_MIRROR_314) + { + twilighte->mirror_0x314 = data; + // If bit 1 of $314 is equal to 0 (romdis low), then send bank 0 value + if((twilighte->mirror_0x314&2)==0) // Test bit 1 + { + twilighte->mirror_0x314_write_detected=SDL_TRUE; + } + } + + } + return 0; +} diff --git a/plugins/twilighte_board/oric_twilighte_board_plugin.h b/plugins/twilighte_board/oric_twilighte_board_plugin.h new file mode 100644 index 00000000..8cfd86ce --- /dev/null +++ b/plugins/twilighte_board/oric_twilighte_board_plugin.h @@ -0,0 +1,43 @@ +struct twilbankinfo +{ + unsigned char type; + unsigned char* ptr; +}; + +struct twilighte +{ + unsigned char t_register; + unsigned char t_banking_register; + char twilrombankfiles[32][1024]; + + char twilrambankfiles[32][1024]; + + unsigned char twilrombankdata[32][16834]; + unsigned char twilrambankdata[32][16834]; + + int firmware_version; + + SDL_bool microdisc; + + unsigned char DDRA; + unsigned char IORAh; + + unsigned char DDRB; + unsigned char IORB; + unsigned char current_bank; + unsigned char mirror_0x314; + unsigned char mirror_0x314_write_detected; +}; + +struct twilighte * twilighte_oric_init(void); + +unsigned char twilighte_board_mapping_bank(struct twilighte *twilighte); +unsigned char twilighte_board_mapping_software_bank(struct twilighte *twilighte); + +unsigned char twilighteboard_oric_ROM_RAM_read(struct twilighte *twilighte, uint16_t addr) ; +unsigned char twilighteboard_oric_ROM_RAM_write(struct twilighte *twilighte, uint16_t addr, unsigned char data); + +unsigned char twilighteboard_oric_write(struct twilighte *twilighte, uint16_t addr,unsigned char mask, unsigned char data); +unsigned char twilighteboard_oric_read(struct twilighte* twilighte, uint16_t addr); + + diff --git a/plugins/twilighte_board/twilighte.cfg b/plugins/twilighte_board/twilighte.cfg new file mode 100644 index 00000000..e1b896b4 --- /dev/null +++ b/plugins/twilighte_board/twilighte.cfg @@ -0,0 +1,70 @@ + +twilbankrom07='roms/kernel' +twilbankrom06='roms/basic11b' +twilbankrom05='roms/shell' + + +;twilbankram30='' +;twilbankram29='' +;twilbankram28='' +;twilbankram27='' +;twilbankram26='' +;twilbankram25='' +;twilbankram24='' +;twilbankram23='' +;twilbankram22='' +;twilbankram21='' +;twilbankram20='' +;twilbankram19='' +;twilbankram18='' +;twilbankram17='' +;twilbankram16='' +;twilbankram15='' +;twilbankram14='' +;twilbankram13='' +;twilbankram12='' +;twilbankram11='' +;twilbankram10='' +;twilbankram09='' +;twilbankram08='' +;twilbankram07='' +;twilbankram06='' +;twilbankram05='' +;twilbankram04='' +;twilbankram03='' +;twilbankram02='' +;twilbankram01='' + + + + + + +; How to emulate joysticks attached +; Options are 'none', 'kbjoy1', 'kbjoy2', 'sdljoyN', 'mouse' +twilightejoy_a = kbjoy1 +twilightejoy_b = none + +; Keys to emulate joystick, set 1 +; NOTE: "fire2" is only available on telestrat +; NOTE: "fire3" is only available on telestrat (right port) +kbjoy1_up = 'KP8' +kbjoy1_down = 'KP2' +kbjoy1_left = 'KP4' +kbjoy1_right = 'KP6' +kbjoy1_fire1 = 'KP_ENTER' +kbjoy1_fire2 = 'KP_PLUS' +kbjoy1_fire3 = 'KP_MINUS' + +; Keys to emulate joystick, set 2 +kbjoy2_up = 'W' +kbjoy2_down = 'S' +kbjoy2_left = 'A' +kbjoy2_right = 'D' +kbjoy2_fire1 = 'SPACE' +kbjoy2_fire2 = 'N' +kbjoy2_fire3 = 'LALT' + +firmware = 2 + +microdisc = no diff --git a/render_gl.c b/render_gl.c index 6b7223a7..79409409 100644 --- a/render_gl.c +++ b/render_gl.c @@ -32,7 +32,6 @@ #endif #ifndef __APPLE__ - #include #else #include @@ -110,28 +109,30 @@ extern unsigned char thefont[]; // fcol = foreground colour // bcol = background colour // solidfont = use background colour -static void printchar( int i, int x, int y, unsigned char ch, Uint32 fcol, Uint32 bcol, SDL_bool solidfont ) +static void printchar(int i, int x, int y, unsigned char ch, Uint32 fcol, Uint32 bcol, SDL_bool solidfont) { int px, py, c; - unsigned char *fptr; + unsigned char* fptr; struct texture *ptx = &tx[i]; Uint32 *ptr; - if( ch > 127 ) return; + if(ch > 127) return; ptr = (Uint32 *)&ptx->buf[(y*ptx->w+x)*4]; fptr = &thefont[ch*12]; - for( py=0; py<12; py++ ) + for(py=0; py<12; py++) { - for( c=0x80, px=0; px<8; px++, c>>=1 ) + for(c=0x80, px=0; px<8; px++, c>>=1) { - if( (*fptr)&c ) + if((*fptr)&c) { *(ptr++) = fcol; - } else { - if( solidfont ) + } + else + { + if(solidfont) *(ptr++) = bcol; else ptr++; @@ -143,29 +144,29 @@ static void printchar( int i, int x, int y, unsigned char ch, Uint32 fcol, Uint3 } } -static void update_textzone_texture( struct machine *oric, int i ) +static void update_textzone_texture(struct machine *oric, int i) { int x, y, px, py, o; - if( !tz[i] ) return; - if( !tz[i]->modified ) return; - if( !tx[i+TEX_TZ].buf ) return; + if(!tz[i]) return; + if(!tz[i]->modified) return; + if(!tx[i+TEX_TZ].buf) return; o = 0; - for( y=0, py=0; yh; y++, py+=12 ) + for(y=0, py=0; yh; y++, py+=12) { - for( x=0, px=0; xw; x++, o++, px+=8 ) - printchar( i+TEX_TZ, px, py, tz[i]->tx[o], gpal[tz[i]->fc[o]], gpal[tz[i]->bc[o]], SDL_TRUE ); + for(x=0, px=0; xw; x++, o++, px+=8) + printchar(i+TEX_TZ, px, py, tz[i]->tx[o], gpal[tz[i]->fc[o]], gpal[tz[i]->bc[o]], SDL_TRUE); } - glBindTexture( GL_TEXTURE_2D, tex[i+TEX_TZ] ); - glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, tx[i+TEX_TZ].w, tx[i+TEX_TZ].h, 0, GL_RGBA, GL_UNSIGNED_BYTE, tx[i+TEX_TZ].buf ); + glBindTexture(GL_TEXTURE_2D, tex[i+TEX_TZ]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tx[i+TEX_TZ].w, tx[i+TEX_TZ].h, 0, GL_RGBA, GL_UNSIGNED_BYTE, tx[i+TEX_TZ].buf); tz[i]->modified = SDL_FALSE; } -static void update_video_texture( struct machine *oric ) +static void update_video_texture(struct machine *oric) { int x, y, o, c; Uint8 *sptr; @@ -173,16 +174,16 @@ static void update_video_texture( struct machine *oric ) o = 0; sptr = oric->scr; - for( y=0; y<224; y++ ) + for(y=0; y<224; y++) { - if (!oric->vid_dirty[y]) + if(!oric->vid_dirty[y]) { sptr += 240; o += tx[TEX_VIDEO].w*4; continue; } - for( x=0; x<240; x++ ) + for(x=0; x<240; x++) { c = *(sptr++) * 3; tx[TEX_VIDEO].buf[o++] = oricpalette[c++]; @@ -203,7 +204,7 @@ static void update_video_texture( struct machine *oric ) } sptr -= 240; - for( x=0; x<240; x++ ) + for(x=0; x<240; x++) { c = *(sptr++) * 3; tx[TEX_VIDEO].buf[o++] = oricpalette[c++]; @@ -219,65 +220,73 @@ static void update_video_texture( struct machine *oric ) tx[TEX_VIDEO].buf[o++] = oricpalette[c-1]; tx[TEX_VIDEO].buf[o++] = 0xff; - glBindTexture( GL_TEXTURE_2D, tex[TEX_VIDEO] ); - glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, tx[TEX_VIDEO].w, tx[TEX_VIDEO].h, 0, GL_RGBA, GL_UNSIGNED_BYTE, tx[TEX_VIDEO].buf ); + glBindTexture(GL_TEXTURE_2D, tex[TEX_VIDEO]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tx[TEX_VIDEO].w, tx[TEX_VIDEO].h, 0, GL_RGBA, GL_UNSIGNED_BYTE, tx[TEX_VIDEO].buf); } -void render_begin_gl( struct machine *oric ) +void render_begin_gl(struct machine *oric) { int i; refreshstatus = SDL_TRUE; - update_video_texture( oric ); - for( i=0; inewpopupstr ) + if(oric->newpopupstr) { - memset( tx[TEX_POPUP].buf, 0, tx[TEX_POPUP].w*tx[TEX_POPUP].h*4 ); - for( i=0; oric->popupstr[i]; i++ ) - printchar( TEX_POPUP, i*8, 0, oric->popupstr[i], gpal[1], gpal[0], SDL_TRUE ); - glBindTexture( GL_TEXTURE_2D, tex[TEX_POPUP] ); - glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, tx[TEX_POPUP].w, tx[TEX_POPUP].h, 0, GL_RGBA, GL_UNSIGNED_BYTE, tx[TEX_POPUP].buf ); + memset(tx[TEX_POPUP].buf, 0, tx[TEX_POPUP].w*tx[TEX_POPUP].h*4); + for(i=0; oric->popupstr[i]; i++) + printchar(TEX_POPUP, i*8, 0, oric->popupstr[i], gpal[1], gpal[0], SDL_TRUE); + glBindTexture(GL_TEXTURE_2D, tex[TEX_POPUP]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tx[TEX_POPUP].w, tx[TEX_POPUP].h, 0, GL_RGBA, GL_UNSIGNED_BYTE, tx[TEX_POPUP].buf); oric->newpopupstr = SDL_FALSE; } - if( oric->newstatusstr ) + if(oric->newstatusstr) { - memset( tx[TEX_STATUS].buf, 0, tx[TEX_STATUS].w*tx[TEX_STATUS].h*4 ); - for( i=0; oric->statusstr[i]; i++ ) - printchar( TEX_STATUS, i*8, 0, oric->statusstr[i], gpal[1], gpal[0], SDL_FALSE ); - glBindTexture( GL_TEXTURE_2D, tex[TEX_STATUS] ); - glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, tx[TEX_STATUS].w, tx[TEX_STATUS].h, 0, GL_RGBA, GL_UNSIGNED_BYTE, tx[TEX_STATUS].buf ); + memset(tx[TEX_STATUS].buf, 0, tx[TEX_STATUS].w*tx[TEX_STATUS].h*4); + for(i=0; oric->statusstr[i]; i++) + printchar(TEX_STATUS, i*8, 0, oric->statusstr[i], gpal[1], gpal[0], SDL_FALSE); + glBindTexture(GL_TEXTURE_2D, tex[TEX_STATUS]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tx[TEX_STATUS].w, tx[TEX_STATUS].h, 0, GL_RGBA, GL_UNSIGNED_BYTE, tx[TEX_STATUS].buf); } glClearColor(clrcol[0], clrcol[1], clrcol[2], 1.0f); - glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } -void render_end_gl( struct machine *oric ) +void render_end_gl(struct machine *oric) { - if( oric->emu_mode == EM_RUNNING ) + if(oric->emu_mode == EM_RUNNING) { - if( oric->popupstr[0] ) + if(oric->popupstr[0]) { - glBindTexture( GL_TEXTURE_2D, tex[TEX_POPUP] ); - glBegin( GL_QUADS ); - glTexCoord2f( 0.0f, 0.0f ); glVertex3f( 320.0f, 0.0f, 0.0f ); - glTexCoord2f( 320.0f/512.0f, 0.0f ); glVertex3f( 640.0f, 0.0f, 0.0f ); - glTexCoord2f( 320.0f/512.0f, 12.0f/32.0f ); glVertex3f( 640.0f, 12.0f, 0.0f ); - glTexCoord2f( 0.0f, 12.0f/32.0f ); glVertex3f( 320.0f, 12.0f, 0.0f ); + glBindTexture(GL_TEXTURE_2D, tex[TEX_POPUP]); + glBegin(GL_QUADS); + glTexCoord2f(0.0f, 0.0f); + glVertex3f(320.0f, 0.0f, 0.0f); + glTexCoord2f(320.0f/512.0f, 0.0f); + glVertex3f(640.0f, 0.0f, 0.0f); + glTexCoord2f(320.0f/512.0f, 12.0f/32.0f); + glVertex3f(640.0f, 12.0f, 0.0f); + glTexCoord2f(0.0f, 12.0f/32.0f); + glVertex3f(320.0f, 12.0f, 0.0f); glEnd(); } - if( oric->statusstr[0] ) + if(oric->statusstr[0]) { - glBindTexture( GL_TEXTURE_2D, tex[TEX_STATUS] ); - glBegin( GL_QUADS ); - glTexCoord2f( 0.0f, 0.0f ); glVertex3f( 0.0f, 466.0f, 0.0f ); - glTexCoord2f( 320.0f/512.0f, 0.0f ); glVertex3f( 320.0f, 466.0f, 0.0f ); - glTexCoord2f( 320.0f/512.0f, 12.0f/32.0f ); glVertex3f( 320.0f, 478.0f, 0.0f ); - glTexCoord2f( 0.0f, 12.0f/32.0f ); glVertex3f( 0.0f, 478.0f, 0.0f ); + glBindTexture(GL_TEXTURE_2D, tex[TEX_STATUS]); + glBegin(GL_QUADS); + glTexCoord2f(0.0f, 0.0f); + glVertex3f(0.0f, 466.0f, 0.0f); + glTexCoord2f(320.0f/512.0f, 0.0f); + glVertex3f(320.0f, 466.0f, 0.0f); + glTexCoord2f(320.0f/512.0f, 12.0f/32.0f); + glVertex3f(320.0f, 478.0f, 0.0f); + glTexCoord2f(0.0f, 12.0f/32.0f); + glVertex3f(0.0f, 478.0f, 0.0f); glEnd(); } } @@ -285,7 +294,7 @@ void render_end_gl( struct machine *oric ) SDL_COMPAT_GL_SwapBuffers(); } -static unsigned int rounduppow2( unsigned int x ) +static unsigned int rounduppow2(unsigned int x) { x--; x |= x >> 1; @@ -298,25 +307,25 @@ static unsigned int rounduppow2( unsigned int x ) return x; } -void render_textzone_alloc_gl( struct machine *oric, int i ) +void render_textzone_alloc_gl(struct machine *oric, int i) { - render_textzone_free_gl( oric, i ); + render_textzone_free_gl(oric, i); - if( !tz[i] ) return; + if(!tz[i]) return; #ifdef __amigaos4__ -// seems to be a bug in OS4 SDL or GL that reallocating the texture -// a different size causes problems :-/ Or it might just be me being -// stupid, but i can't see how at this time. Anyway; say hello to mr. -// ugly workaround + // seems to be a bug in OS4 SDL or GL that reallocating the texture + // a different size causes problems :-/ Or it might just be me being + // stupid, but i can't see how at this time. Anyway; say hello to mr. + // ugly workaround tx[i+TEX_TZ].w = 512; tx[i+TEX_TZ].h = 512; #else - tx[i+TEX_TZ].w = rounduppow2( tz[i]->w * 8 ); - tx[i+TEX_TZ].h = rounduppow2( tz[i]->h * 12 ); + tx[i+TEX_TZ].w = rounduppow2(tz[i]->w * 8); + tx[i+TEX_TZ].h = rounduppow2(tz[i]->h * 12); #endif - tx[i+TEX_TZ].buf = malloc( tx[i+TEX_TZ].w*tx[i+TEX_TZ].h*4 ); - if( !tx[i+TEX_TZ].buf ) + tx[i+TEX_TZ].buf = malloc(tx[i+TEX_TZ].w*tx[i+TEX_TZ].h*4); + if(!tx[i+TEX_TZ].buf) { tx[i+TEX_TZ].w = 0; tx[i+TEX_TZ].h = 0; @@ -326,21 +335,21 @@ void render_textzone_alloc_gl( struct machine *oric, int i ) tx[i+TEX_TZ].tw = ((float)(tz[i]->w*8)) / ((float)tx[i+TEX_TZ].w); tx[i+TEX_TZ].th = ((float)(tz[i]->h*12)) / ((float)tx[i+TEX_TZ].h); - glBindTexture( GL_TEXTURE_2D, tex[i+TEX_TZ] ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); - glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, tx[i+TEX_TZ].w, tx[i+TEX_TZ].h, 0, GL_RGBA, GL_UNSIGNED_BYTE, tx[i+TEX_TZ].buf ); + glBindTexture(GL_TEXTURE_2D, tex[i+TEX_TZ]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tx[i+TEX_TZ].w, tx[i+TEX_TZ].h, 0, GL_RGBA, GL_UNSIGNED_BYTE, tx[i+TEX_TZ].buf); tz[i]->modified = SDL_TRUE; } -void render_textzone_free_gl( struct machine *oric, int i ) +void render_textzone_free_gl(struct machine *oric, int i) { - if( tx[i+TEX_TZ].buf ) + if(tx[i+TEX_TZ].buf) { - free( tx[i+TEX_TZ].buf ); + free(tx[i+TEX_TZ].buf); tx[i+TEX_TZ].buf = NULL; } @@ -348,36 +357,44 @@ void render_textzone_free_gl( struct machine *oric, int i ) tx[i+TEX_TZ].h = 0; } -void render_textzone_gl( struct machine *oric, int i ) +void render_textzone_gl(struct machine *oric, int i) { - if( !tz[i] ) return; - if( !tx[i+TEX_TZ].buf ) return; - - glBindTexture( GL_TEXTURE_2D, tex[i+TEX_TZ] ); - glBegin( GL_QUADS ); - glTexCoord2f( 0.0f, 0.0f ); glVertex3f( tz[i]->x, tz[i]->y, 0.0f ); - glTexCoord2f( tx[i+TEX_TZ].tw, 0.0f ); glVertex3f( tz[i]->x+tz[i]->w*8, tz[i]->y, 0.0f ); - glTexCoord2f( tx[i+TEX_TZ].tw, tx[i+TEX_TZ].th ); glVertex3f( tz[i]->x+tz[i]->w*8, tz[i]->y+tz[i]->h*12, 0.0f ); - glTexCoord2f( 0.0f, tx[i+TEX_TZ].th ); glVertex3f( tz[i]->x, tz[i]->y+tz[i]->h*12, 0.0f ); + if(!tz[i]) return; + if(!tx[i+TEX_TZ].buf) return; + + glBindTexture(GL_TEXTURE_2D, tex[i+TEX_TZ]); + glBegin(GL_QUADS); + glTexCoord2f(0.0f, 0.0f); + glVertex3f(tz[i]->x, tz[i]->y, 0.0f); + glTexCoord2f(tx[i+TEX_TZ].tw, 0.0f); + glVertex3f(tz[i]->x+tz[i]->w*8, tz[i]->y, 0.0f); + glTexCoord2f(tx[i+TEX_TZ].tw, tx[i+TEX_TZ].th); + glVertex3f(tz[i]->x+tz[i]->w*8, tz[i]->y+tz[i]->h*12, 0.0f); + glTexCoord2f(0.0f, tx[i+TEX_TZ].th); + glVertex3f(tz[i]->x, tz[i]->y+tz[i]->h*12, 0.0f); glEnd(); } -void render_clear_area_gl( int x, int y, int w, int h ) +void render_clear_area_gl(int x, int y, int w, int h) { } -void render_gimg_gl( int i, Sint32 xp, Sint32 yp ) +void render_gimg_gl(int i, Sint32 xp, Sint32 yp) { - glBindTexture( GL_TEXTURE_2D, tex[i+TEX_GIMG] ); - glBegin( GL_QUADS ); - glTexCoord2f( 0.0f, 0.0f ); glVertex3f( xp, yp, 0.0f ); - glTexCoord2f( tx[i+TEX_GIMG].tw, 0.0f ); glVertex3f( xp+gimgs[i].w, yp, 0.0f ); - glTexCoord2f( tx[i+TEX_GIMG].tw, tx[i+TEX_GIMG].th ); glVertex3f( xp+gimgs[i].w, yp+gimgs[i].h, 0.0f ); - glTexCoord2f( 0.0f, tx[i+TEX_GIMG].th ); glVertex3f( xp, yp+gimgs[i].h, 0.0f ); + glBindTexture(GL_TEXTURE_2D, tex[i+TEX_GIMG]); + glBegin(GL_QUADS); + glTexCoord2f(0.0f, 0.0f); + glVertex3f(xp, yp, 0.0f); + glTexCoord2f(tx[i+TEX_GIMG].tw, 0.0f); + glVertex3f(xp+gimgs[i].w, yp, 0.0f); + glTexCoord2f(tx[i+TEX_GIMG].tw, tx[i+TEX_GIMG].th); + glVertex3f(xp+gimgs[i].w, yp+gimgs[i].h, 0.0f); + glTexCoord2f(0.0f, tx[i+TEX_GIMG].th); + glVertex3f(xp, yp+gimgs[i].h, 0.0f); glEnd(); } -void render_gimgpart_gl( int i, Sint32 xp, Sint32 yp, Sint32 ox, Sint32 oy, Sint32 w, Sint32 h ) +void render_gimgpart_gl(int i, Sint32 xp, Sint32 yp, Sint32 ox, Sint32 oy, Sint32 w, Sint32 h) { float texl, text, texr, texb; @@ -386,34 +403,40 @@ void render_gimgpart_gl( int i, Sint32 xp, Sint32 yp, Sint32 ox, Sint32 oy, Sint texr = ((float)ox+w)/((float)tx[i+TEX_GIMG].w); texb = ((float)oy+h)/((float)tx[i+TEX_GIMG].h); - glBindTexture( GL_TEXTURE_2D, tex[i+TEX_GIMG] ); - glBegin( GL_QUADS ); - glTexCoord2f( texl, text ); glVertex3f( xp, yp, 0.0f ); - glTexCoord2f( texr, text ); glVertex3f( xp+w, yp, 0.0f ); - glTexCoord2f( texr, texb ); glVertex3f( xp+w, yp+h, 0.0f ); - glTexCoord2f( texl, texb ); glVertex3f( xp, yp+h, 0.0f ); + glBindTexture(GL_TEXTURE_2D, tex[i+TEX_GIMG]); + glBegin(GL_QUADS); + glTexCoord2f(texl, text); + glVertex3f(xp, yp, 0.0f); + glTexCoord2f(texr, text); + glVertex3f(xp+w, yp, 0.0f); + glTexCoord2f(texr, texb); + glVertex3f(xp+w, yp+h, 0.0f); + glTexCoord2f(texl, texb); + glVertex3f(xp, yp+h, 0.0f); glEnd(); } -void render_video_gl( struct machine *oric, SDL_bool doublesize ) +void render_video_gl(struct machine *oric, SDL_bool doublesize) { float l, r, t, b; int y; - glBindTexture( GL_TEXTURE_2D, tex[TEX_VIDEO] ); + glBindTexture(GL_TEXTURE_2D, tex[TEX_VIDEO]); - if( doublesize ) + if(doublesize) { - if( oric->hstretch ) + if(oric->hstretch) { l = 0.0f; r = 640.f; t = 14.0f; b = 462.0f; - } else { + } + else + { l = 320.0f-240.0f; r = 320.0f+240.0f; - if( oric->aratio && oric->vid_freq ) + if(oric->aratio && oric->vid_freq) { t = 14.0f + (448.0f-448.0f*(260.0f/308.0f))/2; b = 462.0f - (448.0f-448.0f*(260.0f/308.0f))/2; @@ -425,57 +448,73 @@ void render_video_gl( struct machine *oric, SDL_bool doublesize ) } } - glBegin( GL_QUADS ); - glTexCoord2f( 0.0f, 0.0f ); glVertex3f( l, t, 0.0f ); - glTexCoord2f( 240.0f/256.0f, 0.0f ); glVertex3f( r, t, 0.0f ); - glTexCoord2f( 240.0f/256.0f, 224.0f/256.0f ); glVertex3f( r, b, 0.0f ); - glTexCoord2f( 0.0f, 224.0f/256.0f ); glVertex3f( l, b, 0.0f ); + glBegin(GL_QUADS); + glTexCoord2f(0.0f, 0.0f); + glVertex3f(l, t, 0.0f); + glTexCoord2f(240.0f/256.0f, 0.0f); + glVertex3f(r, t, 0.0f); + glTexCoord2f(240.0f/256.0f, 224.0f/256.0f); + glVertex3f(r, b, 0.0f); + glTexCoord2f(0.0f, 224.0f/256.0f); + glVertex3f(l, b, 0.0f); glEnd(); - if( oric->palghost ) + if(oric->palghost) { float offs = (oric->hstretch) ? 3.2f : 2.2f; - glColor4ub( 255, 255, 255, 64 ); - glBegin( GL_QUADS ); - glTexCoord2f( 0.0f, 0.0f ); glVertex3f( l+offs, t, 0.0f ); - glTexCoord2f( 240.0f/256.0f, 0.0f ); glVertex3f( r+offs, t, 0.0f ); - glTexCoord2f( 240.0f/256.0f, 224.0f/256.0f ); glVertex3f( r+offs, b, 0.0f ); - glTexCoord2f( 0.0f, 224.0f/256.0f ); glVertex3f( l+offs, b, 0.0f ); + glColor4ub(255, 255, 255, 64); + glBegin(GL_QUADS); + glTexCoord2f(0.0f, 0.0f); + glVertex3f(l+offs, t, 0.0f); + glTexCoord2f(240.0f/256.0f, 0.0f); + glVertex3f(r+offs, t, 0.0f); + glTexCoord2f(240.0f/256.0f, 224.0f/256.0f); + glVertex3f(r+offs, b, 0.0f); + glTexCoord2f(0.0f, 224.0f/256.0f); + glVertex3f(l+offs, b, 0.0f); glEnd(); - glColor4ub( 255, 255, 255, 255 ); + glColor4ub(255, 255, 255, 255); } - if( !oric->scanlines ) return; + if(!oric->scanlines) return; - glBindTexture( GL_TEXTURE_2D, tex[TEX_SCANLINES] ); - glBegin( GL_QUADS ); - for( y=14; y<224*2+14; y+=32 ) + glBindTexture(GL_TEXTURE_2D, tex[TEX_SCANLINES]); + glBegin(GL_QUADS); + for(y=14; y<224*2+14; y+=32) { - glTexCoord2f( 0.0f, 0.0f ); glVertex3f( l, y, 0.0f ); - glTexCoord2f( 1.0f, 0.0f ); glVertex3f( r, y, 0.0f ); - glTexCoord2f( 1.0f, 1.0f ); glVertex3f( r, y+32, 0.0f ); - glTexCoord2f( 0.0f, 1.0f ); glVertex3f( l, y+32, 0.0f ); + glTexCoord2f(0.0f, 0.0f); + glVertex3f(l, y, 0.0f); + glTexCoord2f(1.0f, 0.0f); + glVertex3f(r, y, 0.0f); + glTexCoord2f(1.0f, 1.0f); + glVertex3f(r, y+32, 0.0f); + glTexCoord2f(0.0f, 1.0f); + glVertex3f(l, y+32, 0.0f); } glEnd(); return; } - glBegin( GL_QUADS ); - glTexCoord2f( 0.0f, 0.0f ); glVertex3f( 0.0f, 4.0f, 0.0f ); - glTexCoord2f( 240.0f/256.0f, 0.0f ); glVertex3f( 240.0f, 4.0f, 0.0f ); - glTexCoord2f( 240.0f/256.0f, 224.0f/256.0f ); glVertex3f( 240.0f, 228.0f, 0.0f ); - glTexCoord2f( 0.0f, 224.0f/256.0f ); glVertex3f( 0.0f, 228.0f, 0.0f ); + glBegin(GL_QUADS); + glTexCoord2f(0.0f, 0.0f); + glVertex3f(0.0f, 4.0f, 0.0f); + glTexCoord2f(240.0f/256.0f, 0.0f); + glVertex3f(240.0f, 4.0f, 0.0f); + glTexCoord2f(240.0f/256.0f, 224.0f/256.0f); + glVertex3f(240.0f, 228.0f, 0.0f); + glTexCoord2f(0.0f, 224.0f/256.0f); + glVertex3f(0.0f, 228.0f, 0.0f); glEnd(); } -void preinit_render_gl( struct machine *oric ) +void preinit_render_gl(struct machine *oric) { Sint32 i; screen = NULL; dodeltex = SDL_FALSE; - for( i=0; ishut_render( oric ); + oric->shut_render(oric); fullscreen = !fullscreen; - if( oric->init_render( oric ) ) return SDL_TRUE; - set_render_mode( oric, RENDERMODE_NULL ); + if(oric->init_render(oric)) return SDL_TRUE; + set_render_mode(oric, RENDERMODE_NULL); oric->emu_mode = EM_PLEASEQUIT; return SDL_FALSE; #endif } -static SDL_bool go_go_gadget_texture( int i, int w, int h, int blendtype, SDL_bool callteximg2d ) +static SDL_bool go_go_gadget_texture(int i, int w, int h, int blendtype, SDL_bool callteximg2d) { tx[i].w = w; tx[i].h = h; - tx[i].buf = malloc( w*h*4 ); - if( !tx[i].buf ) return SDL_FALSE; + tx[i].buf = malloc(w*h*4); + if(!tx[i].buf) return SDL_FALSE; - memset( tx[i].buf, 0, w*h*4 ); + memset(tx[i].buf, 0, w*h*4); - glBindTexture( GL_TEXTURE_2D, tex[i] ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, blendtype ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, blendtype ); - if( callteximg2d )glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, tx[i].buf ); + glBindTexture(GL_TEXTURE_2D, tex[i]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, blendtype); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, blendtype); + if(callteximg2d)glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, tx[i].buf); return SDL_TRUE; } -SDL_bool init_render_gl( struct machine *oric ) +SDL_bool init_render_gl(struct machine *oric) { - int depth, i, x, y; + Uint32 flags = SDL_COMPAT_OPENGL | (fullscreen? SDL_COMPAT_FULLSCREEN : 0); int BitsPerPixel = SDL_COMPAT_GetBitsPerPixel(); + int depth = 32; + int y = 480 + (oric->show_keyboard? 240:0); + int x = 640; + int i; - depth = 32; - if( BitsPerPixel ) + if(BitsPerPixel) depth = BitsPerPixel; - if (oric->show_keyboard) { - screen = SDL_COMPAT_SetVideoMode( 640, 480+240, depth, fullscreen ? SDL_COMPAT_OPENGL|SDL_COMPAT_FULLSCREEN : SDL_COMPAT_OPENGL ); - } else { - screen = SDL_COMPAT_SetVideoMode( 640, 480, depth, fullscreen ? SDL_COMPAT_OPENGL|SDL_COMPAT_FULLSCREEN : SDL_COMPAT_OPENGL ); - } + screen = SDL_COMPAT_SetVideoMode(x, y, depth, flags); - if( !screen ) + if(!screen) { - printf( "SDL video failed\n" ); + printf("SDL video failed\n"); return SDL_FALSE; } - glMatrixMode( GL_PROJECTION ); - if (oric->show_keyboard) { - glOrtho( 0.0f, 640.0f, 480.0f+240.0f, 0.0f, 0.0f, 1.0f ); - } else { - glOrtho( 0.0f, 640.0f, 480.0f, 0.0f, 0.0f, 1.0f ); + glMatrixMode(GL_PROJECTION); + if(oric->show_keyboard) + { + glOrtho(0.0f, 640.0f, 480.0f+240.0f, 0.0f, 0.0f, 1.0f); + } + else + { + glOrtho(0.0f, 640.0f, 480.0f, 0.0f, 0.0f, 1.0f); } - glMatrixMode( GL_MODELVIEW ); + glMatrixMode(GL_MODELVIEW); glLoadIdentity(); - glDisable( GL_DEPTH_TEST ); - glColor4ub( 255, 255, 255, 255 ); + glDisable(GL_DEPTH_TEST); + glColor4ub(255, 255, 255, 255); - glGenTextures( NUM_TEXTURES, tex ); + glGenTextures(NUM_TEXTURES, tex); dodeltex = SDL_TRUE; - glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); - glEnable( GL_TEXTURE_2D ); - glEnable( GL_BLEND ); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_TEXTURE_2D); + glEnable(GL_BLEND); // Allocate texture buffers - if( !go_go_gadget_texture( TEX_VIDEO, 256, 256, GL_LINEAR, SDL_TRUE ) ) return SDL_FALSE; - if( !go_go_gadget_texture( TEX_SCANLINES, 32, 32, GL_NEAREST, SDL_FALSE ) ) return SDL_FALSE; - if( !go_go_gadget_texture( TEX_STATUS, 512, 32, GL_NEAREST, SDL_TRUE ) ) return SDL_FALSE; - if( !go_go_gadget_texture( TEX_POPUP, 512, 32, GL_NEAREST, SDL_TRUE ) ) return SDL_FALSE; + if(!go_go_gadget_texture(TEX_VIDEO, 256, 256, GL_LINEAR, SDL_TRUE)) return SDL_FALSE; + if(!go_go_gadget_texture(TEX_SCANLINES, 32, 32, GL_NEAREST, SDL_FALSE)) return SDL_FALSE; + if(!go_go_gadget_texture(TEX_STATUS, 512, 32, GL_NEAREST, SDL_TRUE)) return SDL_FALSE; + if(!go_go_gadget_texture(TEX_POPUP, 512, 32, GL_NEAREST, SDL_TRUE)) return SDL_FALSE; - for( y=0; y<32; y++ ) + for(y=0; y<32; y++) { - for( x=0; x<32*4; ) + for(x=0; x<32*4;) { tx[TEX_SCANLINES].buf[y*32*4+x++] = 0x00; tx[TEX_SCANLINES].buf[y*32*4+x++] = 0x00; @@ -578,19 +619,19 @@ SDL_bool init_render_gl( struct machine *oric ) tx[TEX_SCANLINES].buf[y*32*4+x++] = (y&1) ? 0x30 : 0x00; } } - glBindTexture( GL_TEXTURE_2D, tex[TEX_SCANLINES] ); - glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, tx[TEX_SCANLINES].w, tx[TEX_SCANLINES].h, 0, GL_RGBA, GL_UNSIGNED_BYTE, tx[TEX_SCANLINES].buf ); + glBindTexture(GL_TEXTURE_2D, tex[TEX_SCANLINES]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tx[TEX_SCANLINES].w, tx[TEX_SCANLINES].h, 0, GL_RGBA, GL_UNSIGNED_BYTE, tx[TEX_SCANLINES].buf); - for( i=0; inewpopupstr ) + if(oric->newpopupstr) { dst_scanline = (Uint8*)screen->pixels; dst_scanline += 320 * pixel_size; - if( oric->sw_depth == 16 ) + if(oric->sw_depth == 16) { Uint16 *dst_pixel; - for( y=12; y!=0; --y, dst_scanline += screen->pitch) + for(y=12; y!=0; --y, dst_scanline += screen->pitch) { dst_pixel = (Uint16 *)dst_scanline; - for( x=320; x<640; x++, dst_pixel++ ) + for(x=320; x<640; x++, dst_pixel++) *dst_pixel = gpal[0]; } - } else { + } + else + { Uint32 *dst_pixel; - for( y=12; y!=0; --y, dst_scanline += screen->pitch) + for(y=12; y!=0; --y, dst_scanline += screen->pitch) { dst_pixel = (Uint32 *)dst_scanline; - for( x=320; x<640; x++, dst_pixel++ ) + for(x=320; x<640; x++, dst_pixel++) *dst_pixel = gpal[0]; } } oric->newpopupstr = SDL_FALSE; } - - if( oric->newstatusstr ) + + if(oric->newstatusstr) { refreshstatus = SDL_TRUE; oric->newstatusstr = SDL_FALSE; } } -void render_end_sw( struct machine *oric ) +void render_end_sw(struct machine *oric) { int i; Uint32 char_pitch; @@ -150,42 +152,42 @@ void render_end_sw( struct machine *oric ) char_pitch = 8 * pixel_size; - if( oric->emu_mode == EM_RUNNING ) + if(oric->emu_mode == EM_RUNNING) { - if( oric->popupstr[0] ) + if(oric->popupstr[0]) { dst_pixel = (Uint8*)screen->pixels; dst_pixel += 320 * pixel_size; - for( i=0; oric->popupstr[i]; i++, dst_pixel += char_pitch ) - printchar( dst_pixel, oric->popupstr[i], gpal[1], gpal[0], SDL_TRUE ); + for(i=0; oric->popupstr[i]; i++, dst_pixel += char_pitch) + printchar(dst_pixel, oric->popupstr[i], gpal[1], gpal[0], SDL_TRUE); } - - if( oric->statusstr[0] ) + + if(oric->statusstr[0]) { dst_pixel = (Uint8*)screen->pixels; dst_pixel += 466 * screen->pitch; - for( i=0; oric->statusstr[i]; i++, dst_pixel += char_pitch ) - printchar( dst_pixel, oric->statusstr[i], gpal[1], 0, SDL_FALSE ); + for(i=0; oric->statusstr[i]; i++, dst_pixel += char_pitch) + printchar(dst_pixel, oric->statusstr[i], gpal[1], 0, SDL_FALSE); } } - if( SDL_MUSTLOCK( screen ) ) - SDL_UnlockSurface( screen ); + if(SDL_MUSTLOCK(screen)) + SDL_UnlockSurface(screen); - SDL_COMPAT_Flip( screen ); + SDL_COMPAT_Flip(screen); } -void render_textzone_alloc_sw( struct machine *oric, int i ) +void render_textzone_alloc_sw(struct machine *oric, int i) { } -void render_textzone_free_sw( struct machine *oric, int i ) +void render_textzone_free_sw(struct machine *oric, int i) { } -void render_textzone_sw( struct machine *oric, int i ) +void render_textzone_sw(struct machine *oric, int i) { int x, y, o; Uint32 char_pitch; @@ -198,18 +200,18 @@ void render_textzone_sw( struct machine *oric, int i ) dst_scanline += screen->pitch * ptz->y + pixel_size * ptz->x; o = 0; - for( y=ptz->h; y!=0; --y, dst_scanline+=12*screen->pitch ) + for(y=ptz->h; y!=0; --y, dst_scanline+=12*screen->pitch) { dst_pixel = dst_scanline; - for( x=ptz->w; x!=0; --x, ++o, dst_pixel+=char_pitch ) - printchar( dst_pixel, ptz->tx[o], gpal[ptz->fc[o]], gpal[ptz->bc[o]], SDL_TRUE ); + for(x=ptz->w; x!=0; --x, ++o, dst_pixel+=char_pitch) + printchar(dst_pixel, ptz->tx[o], gpal[ptz->fc[o]], gpal[ptz->bc[o]], SDL_TRUE); } } // Clear an area to background -void render_clear_area_sw( int x, int y, int w, int h ) +void render_clear_area_sw(int x, int y, int w, int h) { Uint8 *dst_scanline; Sint32 i; @@ -217,12 +219,12 @@ void render_clear_area_sw( int x, int y, int w, int h ) dst_scanline = (Uint8 *)screen->pixels; dst_scanline += screen->pitch * y + pixel_size * x; - for( i=0; ipitch ) - memset( dst_scanline, 0, pixel_size*w ); + for(i=0; ipitch) + memset(dst_scanline, 0, pixel_size*w); } // Draw a GUI image at X,Y -void render_gimg_sw( int img_id, Sint32 xp, Sint32 yp ) +void render_gimg_sw(int img_id, Sint32 xp, Sint32 yp) { struct guiimg *gi = &gimgs[img_id]; Uint8 *src_scanline, *dst_scanline; @@ -233,12 +235,12 @@ void render_gimg_sw( int img_id, Sint32 xp, Sint32 yp ) dst_scanline = (Uint8 *)screen->pixels; dst_scanline += screen->pitch * yp + pixel_size * xp; - for( i=gi->h; i!=0; --i, src_scanline+=pixel_size*gi->w, dst_scanline+=screen->pitch ) - memcpy( dst_scanline, src_scanline, pixel_size*gi->w ); + for(i=gi->h; i!=0; --i, src_scanline+=pixel_size*gi->w, dst_scanline+=screen->pitch) + memcpy(dst_scanline, src_scanline, pixel_size*gi->w); } // Draw part of an image (xp,yp = screen location, ox, oy = offset into image, w, h = dimensions) -void render_gimgpart_sw( int img_id, Sint32 xp, Sint32 yp, Sint32 ox, Sint32 oy, Sint32 w, Sint32 h ) +void render_gimgpart_sw(int img_id, Sint32 xp, Sint32 yp, Sint32 ox, Sint32 oy, Sint32 w, Sint32 h) { struct guiimg *gi = &gimgs[img_id]; Uint8 *src_scanline, *dst_scanline; @@ -250,12 +252,12 @@ void render_gimgpart_sw( int img_id, Sint32 xp, Sint32 yp, Sint32 ox, Sint32 oy, dst_scanline = (Uint8 *)screen->pixels; dst_scanline += screen->pitch * yp + pixel_size * xp; - for( i=h; i!=0; --i, src_scanline+=pixel_size*gi->w, dst_scanline+=screen->pitch ) - memcpy( dst_scanline, src_scanline, pixel_size*w ); + for(i=h; i!=0; --i, src_scanline+=pixel_size*gi->w, dst_scanline+=screen->pitch) + memcpy(dst_scanline, src_scanline, pixel_size*w); } // Copy the video output buffer to the SDL surface, assuming 16bpp video mode -void render_video_sw_16bpp( struct machine *oric, SDL_bool doublesize ) +void render_video_sw_16bpp(struct machine *oric, SDL_bool doublesize) { int x, y; Uint8 *src_pixel; @@ -265,12 +267,12 @@ void render_video_sw_16bpp( struct machine *oric, SDL_bool doublesize ) Uint16 *dst_pixel; Uint32 *dst_even_pixel, *dst_odd_pixel; - if( !oric->scr ) + if(!oric->scr) return; - if( doublesize ) + if(doublesize) { - if( needclr ) + if(needclr) { SDL_FillRect(screen, NULL, gpal[0]); needclr = SDL_FALSE; @@ -285,11 +287,11 @@ void render_video_sw_16bpp( struct machine *oric, SDL_bool doublesize ) dst_odd_scanline = dst_even_scanline; dst_odd_scanline += screen->pitch; - if( oric->scanlines ) + if(oric->scanlines) { - for( y=0; y<224; y++, dst_even_scanline+=dst_pitch_x2, dst_odd_scanline+=dst_pitch_x2 ) + for(y=0; y<224; y++, dst_even_scanline+=dst_pitch_x2, dst_odd_scanline+=dst_pitch_x2) { - if (!oric->vid_dirty[y]) + if(!oric->vid_dirty[y]) { src_pixel += 240; continue; @@ -297,7 +299,7 @@ void render_video_sw_16bpp( struct machine *oric, SDL_bool doublesize ) dst_even_pixel = (Uint32*)dst_even_scanline; dst_odd_pixel = (Uint32*)dst_odd_scanline; - for( x=240; x!=0; --x ) + for(x=240; x!=0; --x) { c = *(src_pixel++); *(dst_even_pixel++) = dpal[c]; @@ -306,10 +308,12 @@ void render_video_sw_16bpp( struct machine *oric, SDL_bool doublesize ) oric->vid_dirty[y] = SDL_FALSE; } - } else { - for( y=0; y<224; y++, dst_even_scanline+=dst_pitch_x2, dst_odd_scanline+=dst_pitch_x2 ) + } + else + { + for(y=0; y<224; y++, dst_even_scanline+=dst_pitch_x2, dst_odd_scanline+=dst_pitch_x2) { - if (!oric->vid_dirty[y]) + if(!oric->vid_dirty[y]) { src_pixel += 240; continue; @@ -317,11 +321,11 @@ void render_video_sw_16bpp( struct machine *oric, SDL_bool doublesize ) dst_even_pixel = (Uint32*)dst_even_scanline; dst_odd_pixel = (Uint32*)dst_odd_scanline; - for( x=240; x!=0; --x ) + for(x=240; x!=0; --x) { - c = dpal[*(src_pixel++)]; - *(dst_even_pixel++) = c; - *(dst_odd_pixel++) = c; + c = dpal[*(src_pixel++)]; + *(dst_even_pixel++) = c; + *(dst_odd_pixel++) = c; } oric->vid_dirty[y] = SDL_FALSE; } @@ -334,22 +338,22 @@ void render_video_sw_16bpp( struct machine *oric, SDL_bool doublesize ) src_pixel = oric->scr; dst_scanline = (Uint8*)screen->pixels; - for( y=0; y<4; y++ ) + for(y=0; y<4; y++) { - memset( dst_scanline, 0, 240*pixel_size ); + memset(dst_scanline, 0, 240*pixel_size); dst_scanline += screen->pitch; } - for( ; y<228; y++, dst_scanline+=screen->pitch ) + for(; y<228; y++, dst_scanline+=screen->pitch) { dst_pixel = (Uint16*)dst_scanline; - for( x=240; x!=0; --x ) + for(x=240; x!=0; --x) *(dst_pixel++) = (Uint16)pal[*(src_pixel++)]; } } // Copy the video output buffer to the SDL surface, assuming 32bpp video mode -void render_video_sw_32bpp( struct machine *oric, SDL_bool doublesize ) +void render_video_sw_32bpp(struct machine *oric, SDL_bool doublesize) { int x, y; Uint8 *src_pixel; @@ -358,12 +362,12 @@ void render_video_sw_32bpp( struct machine *oric, SDL_bool doublesize ) Uint8 *dst_scanline, *dst_even_scanline, *dst_odd_scanline; Uint32 *dst_pixel, *dst_even_pixel, *dst_odd_pixel; - if( !oric->scr ) + if(!oric->scr) return; - if( doublesize ) + if(doublesize) { - if( needclr ) + if(needclr) { SDL_FillRect(screen, NULL, gpal[0]); needclr = SDL_FALSE; @@ -378,11 +382,11 @@ void render_video_sw_32bpp( struct machine *oric, SDL_bool doublesize ) dst_odd_scanline = dst_even_scanline; dst_odd_scanline += screen->pitch; - if( oric->scanlines ) + if(oric->scanlines) { - for( y=0; y<224; y++, dst_even_scanline+=dst_pitch_x2, dst_odd_scanline+=dst_pitch_x2 ) + for(y=0; y<224; y++, dst_even_scanline+=dst_pitch_x2, dst_odd_scanline+=dst_pitch_x2) { - if (!oric->vid_dirty[y]) + if(!oric->vid_dirty[y]) { src_pixel += 240; continue; @@ -390,7 +394,7 @@ void render_video_sw_32bpp( struct machine *oric, SDL_bool doublesize ) dst_even_pixel = (Uint32*)dst_even_scanline; dst_odd_pixel = (Uint32*)dst_odd_scanline; - for( x=240; x!=0; --x ) + for(x=240; x!=0; --x) { c2 = pal[(*src_pixel)+8]; c = pal[*(src_pixel++)]; @@ -404,10 +408,12 @@ void render_video_sw_32bpp( struct machine *oric, SDL_bool doublesize ) oric->vid_dirty[y] = SDL_FALSE; } - } else { - for( y=0; y<224; y++, dst_even_scanline+=dst_pitch_x2, dst_odd_scanline+=dst_pitch_x2 ) + } + else + { + for(y=0; y<224; y++, dst_even_scanline+=dst_pitch_x2, dst_odd_scanline+=dst_pitch_x2) { - if (!oric->vid_dirty[y]) + if(!oric->vid_dirty[y]) { src_pixel += 240; continue; @@ -415,15 +421,15 @@ void render_video_sw_32bpp( struct machine *oric, SDL_bool doublesize ) dst_even_pixel = (Uint32*)dst_even_scanline; dst_odd_pixel = (Uint32*)dst_odd_scanline; - for( x=240; x!=0; --x ) - { - c = pal[*(src_pixel++)]; + for(x=240; x!=0; --x) + { + c = pal[*(src_pixel++)]; - *(dst_even_pixel++) = c; - *(dst_even_pixel++) = c; - *(dst_odd_pixel++) = c; - *(dst_odd_pixel++) = c; - } + *(dst_even_pixel++) = c; + *(dst_even_pixel++) = c; + *(dst_odd_pixel++) = c; + *(dst_odd_pixel++) = c; + } oric->vid_dirty[y] = SDL_FALSE; } } @@ -435,44 +441,48 @@ void render_video_sw_32bpp( struct machine *oric, SDL_bool doublesize ) src_pixel = oric->scr; dst_scanline = (Uint8*)screen->pixels; - for( y=0; y<4; y++ ) + for(y=0; y<4; y++) { - memset( dst_scanline, 0, 240*pixel_size ); + memset(dst_scanline, 0, 240*pixel_size); dst_scanline += screen->pitch; } - for( ; y<228; y++, dst_scanline+=screen->pitch ) + for(; y<228; y++, dst_scanline+=screen->pitch) { dst_pixel = (Uint32*)dst_scanline; - for( x=240; x!=0; --x ) + for(x=240; x!=0; --x) *(dst_pixel++) = pal[*(src_pixel++)]; } } -void render_sw_detectvideo( struct machine *oric ) +void render_sw_detectvideo(struct machine *oric) { +#ifndef __ANDROID__ int BitsPerPixel = SDL_COMPAT_GetBitsPerPixel(); // Guess the suitable video mode, either 16bpp or 32bpp oric->sw_depth = 16; - switch( BitsPerPixel ) + switch(BitsPerPixel) { // Great, cases we handle case 8: case 16: case 24: case 32: - oric->sw_depth = BitsPerPixel; + oric->sw_depth = BitsPerPixel; break; // Damn, cases we don't handle. Let's say 16 bpp gonna be ok default: break; } +#else + oric->sw_depth = 32; +#endif } -void preinit_render_sw( struct machine *oric ) +void preinit_render_sw(struct machine *oric) { Sint32 i; @@ -480,15 +490,15 @@ void preinit_render_sw( struct machine *oric ) screen = NULL; // Images are not set yet - for( i=0; ishut_render( oric ); + oric->shut_render(oric); fullscreen = !fullscreen; - if( oric->init_render( oric ) ) return SDL_TRUE; - set_render_mode( oric, RENDERMODE_NULL ); - oric->emu_mode = EM_PLEASEQUIT; + if(oric->init_render(oric)) return SDL_TRUE; + set_render_mode(oric, RENDERMODE_NULL); + oric->emu_mode = EM_PLEASEQUIT; return SDL_FALSE; #endif } @@ -537,7 +547,7 @@ DEFINE_guiimg_to_img_X_bpp(32) // --- end of guiimg_to_img_X_bpp template function --------------------------- -SDL_bool init_render_sw( struct machine *oric ) +SDL_bool init_render_sw(struct machine *oric) { int i; unsigned char* pal_it; @@ -546,55 +556,64 @@ SDL_bool init_render_sw( struct machine *oric ) pixel_size = oric->sw_depth / 8; surfacemode = fullscreen ? SDL_COMPAT_FULLSCREEN : SDL_SWSURFACE; - if( hwsurface ) { surfacemode &= ~SDL_SWSURFACE; surfacemode |= SDL_COMPAT_HWSURFACE; } + if(hwsurface) + { + surfacemode &= ~SDL_SWSURFACE; + surfacemode |= SDL_COMPAT_HWSURFACE; + } // Try to setup the video display - if (oric->show_keyboard) { - screen = SDL_COMPAT_SetVideoMode( 640, 480+240, oric->sw_depth, surfacemode ); - } else { - screen = SDL_COMPAT_SetVideoMode( 640, 480, oric->sw_depth, surfacemode ); + if(oric->show_keyboard) + { + screen = SDL_COMPAT_SetVideoMode(640, 480+240, oric->sw_depth, surfacemode); + } + else + { + screen = SDL_COMPAT_SetVideoMode(640, 480, oric->sw_depth, surfacemode); } - - if( !screen ) + + if(!screen) { - printf( "SDL video failed\n" ); + printf("SDL video failed\n"); return SDL_FALSE; } - SDL_COMPAT_WM_SetCaption( APP_NAME_FULL, APP_NAME_FULL ); + SDL_COMPAT_WM_SetCaption(APP_NAME_FULL, APP_NAME_FULL); // Set the video bit depth dependent function - if (oric->sw_depth == 16) { + if(oric->sw_depth == 16) + { printchar = printchar_16bpp; guiimg_to_img = guiimg_to_img_16bpp; -// SDL_COMPAT_WM_SetCaption( "16bit video", "16bit video" ); + // SDL_COMPAT_WM_SetCaption( "16bit video", "16bit video" ); } - else if (oric->sw_depth == 32) { + else if(oric->sw_depth == 32) + { printchar = printchar_32bpp; guiimg_to_img = guiimg_to_img_32bpp; -// SDL_COMPAT_WM_SetCaption( "32bit video", "32bit video" ); + // SDL_COMPAT_WM_SetCaption( "32bit video", "32bit video" ); } // Convert the GUI palette to the screen format bti depth pal_it = sgpal; - for( i=0; iformat, pal_it[0], pal_it[1], pal_it[2] ); + for(i=0; iformat, pal_it[0], pal_it[1], pal_it[2]); // Convert the Oric palette to the screen format bti depth pal_it = oricpalette; - for( i=0; i<8; i++, pal_it+=3 ) + for(i=0; i<8; i++, pal_it+=3) { - pal[i ] = SDL_MapRGB( screen->format, pal_it[0], pal_it[1], pal_it[2] ); - pal[i+8] = SDL_MapRGB( screen->format, pal_it[0]/2, pal_it[1]/2, pal_it[2]/2 ); + pal[i ] = SDL_MapRGB(screen->format, pal_it[0], pal_it[1], pal_it[2]); + pal[i+8] = SDL_MapRGB(screen->format, pal_it[0]/2, pal_it[1]/2, pal_it[2]/2); } // Get the images for the GUI - for( i=0; ipitch; offset_top += pixel_size * 80; - ula_set_dirty( oric ); + ula_set_dirty(oric); // Job done return SDL_TRUE; } -void shut_render_sw( struct machine *oric ) +void shut_render_sw(struct machine *oric) { Sint32 i; - for( i=0; i 127 ) return; - + + if(ch > 127) return; + src_byte = &thefont[ch*12]; dst_scanline = ptr; - - for( y=12; y!=0; --y, ++src_byte, dst_scanline+=screen->pitch ) + + for(y=12; y!=0; --y, ++src_byte, dst_scanline+=screen->pitch) { dst_pixel = dst_scanline; - - for( mask=0x80, x=8; x!=0; --x, ++dst_pixel, mask>>=1 ) + + for(mask=0x80, x=8; x!=0; --x, ++dst_pixel, mask>>=1) { - if( (*src_byte)&mask ) + if((*src_byte)&mask) *dst_pixel = fcol; - else if( solidfont ) + else if(solidfont) *dst_pixel = bcol; } } } -void render_begin_sw8( struct machine *oric ) +void render_begin_sw8(struct machine *oric) { int y; Uint8 *dst_scanline; - - if( SDL_MUSTLOCK( screen ) ) - SDL_LockSurface( screen ); - - if( oric->newpopupstr ) + + if(SDL_MUSTLOCK(screen)) + SDL_LockSurface(screen); + + if(oric->newpopupstr) { dst_scanline = (Uint8*)screen->pixels; dst_scanline += 320; - - for( y=12; y!=0; --y, dst_scanline += screen->pitch) + + for(y=12; y!=0; --y, dst_scanline += screen->pitch) memset(dst_scanline, GPAL_FIRSTPEN, 320); oric->newpopupstr = SDL_FALSE; } - - if( oric->newstatusstr ) + + if(oric->newstatusstr) { refreshstatus = SDL_TRUE; oric->newstatusstr = SDL_FALSE; } } -void render_end_sw8( struct machine *oric ) +void render_end_sw8(struct machine *oric) { int i; Uint32 char_pitch; Uint8 *dst_pixel; - + char_pitch = 8; - - if( oric->emu_mode == EM_RUNNING ) + + if(oric->emu_mode == EM_RUNNING) { - if( oric->popupstr[0] ) + if(oric->popupstr[0]) { dst_pixel = (Uint8*)screen->pixels; dst_pixel += 320; - - for( i=0; oric->popupstr[i]; i++, dst_pixel += char_pitch ) - printchar( dst_pixel, oric->popupstr[i], GPAL_FIRSTPEN+1, GPAL_FIRSTPEN, SDL_TRUE ); + + for(i=0; oric->popupstr[i]; i++, dst_pixel += char_pitch) + printchar(dst_pixel, oric->popupstr[i], GPAL_FIRSTPEN+1, GPAL_FIRSTPEN, SDL_TRUE); } - - if( oric->statusstr[0] ) + + if(oric->statusstr[0]) { dst_pixel = (Uint8*)screen->pixels; dst_pixel += 466 * screen->pitch; - - for( i=0; oric->statusstr[i]; i++, dst_pixel += char_pitch ) - printchar( dst_pixel, oric->statusstr[i], GPAL_FIRSTPEN+1, 0, SDL_FALSE ); + + for(i=0; oric->statusstr[i]; i++, dst_pixel += char_pitch) + printchar(dst_pixel, oric->statusstr[i], GPAL_FIRSTPEN+1, 0, SDL_FALSE); } } - - if( SDL_MUSTLOCK( screen ) ) - SDL_UnlockSurface( screen ); - - SDL_COMPAT_Flip( screen ); + + if(SDL_MUSTLOCK(screen)) + SDL_UnlockSurface(screen); + + SDL_COMPAT_Flip(screen); } -void render_textzone_alloc_sw8( struct machine *oric, int i ) +void render_textzone_alloc_sw8(struct machine *oric, int i) { } -void render_textzone_free_sw8( struct machine *oric, int i ) +void render_textzone_free_sw8(struct machine *oric, int i) { } -void render_textzone_sw8( struct machine *oric, int i ) +void render_textzone_sw8(struct machine *oric, int i) { int x, y, o; struct textzone *ptz = tz[i]; Uint8 *dst_scanline, *dst_pixel; - + dst_scanline = (Uint8 *)screen->pixels; dst_scanline += screen->pitch * ptz->y + ptz->x; - + o = 0; - for( y=ptz->h; y!=0; --y, dst_scanline+=12*screen->pitch ) + for(y=ptz->h; y!=0; --y, dst_scanline+=12*screen->pitch) { dst_pixel = dst_scanline; - - for( x=ptz->w; x!=0; --x, ++o, dst_pixel+=8 ) - printchar( dst_pixel, ptz->tx[o], GPAL_FIRSTPEN+ptz->fc[o], GPAL_FIRSTPEN+ptz->bc[o], SDL_TRUE ); + + for(x=ptz->w; x!=0; --x, ++o, dst_pixel+=8) + printchar(dst_pixel, ptz->tx[o], GPAL_FIRSTPEN+ptz->fc[o], GPAL_FIRSTPEN+ptz->bc[o], SDL_TRUE); } } // Clear an area to background -void render_clear_area_sw8( int x, int y, int w, int h ) +void render_clear_area_sw8(int x, int y, int w, int h) { Uint8 *dst_scanline; Sint32 i; - + dst_scanline = (Uint8 *)screen->pixels; dst_scanline += screen->pitch * y + x; - - for( i=0; ipitch ) - memset( dst_scanline, 0, w ); + + for(i=0; ipitch) + memset(dst_scanline, 0, w); } // Draw a GUI image at X,Y -void render_gimg_sw8( int img_id, Sint32 xp, Sint32 yp ) +void render_gimg_sw8(int img_id, Sint32 xp, Sint32 yp) { struct guiimg *gi = &gimgs[img_id]; Uint8 *src_scanline, *dst_scanline; Sint32 i; - + src_scanline = mgimg[img_id]; - + dst_scanline = (Uint8 *)screen->pixels; dst_scanline += screen->pitch * yp + xp; - - for( i=gi->h; i!=0; --i, src_scanline+=gi->w, dst_scanline+=screen->pitch ) - memcpy( dst_scanline, src_scanline, gi->w ); + + for(i=gi->h; i!=0; --i, src_scanline+=gi->w, dst_scanline+=screen->pitch) + memcpy(dst_scanline, src_scanline, gi->w); } // Draw part of an image (xp,yp = screen location, ox, oy = offset into image, w, h = dimensions) -void render_gimgpart_sw8( int img_id, Sint32 xp, Sint32 yp, Sint32 ox, Sint32 oy, Sint32 w, Sint32 h ) +void render_gimgpart_sw8(int img_id, Sint32 xp, Sint32 yp, Sint32 ox, Sint32 oy, Sint32 w, Sint32 h) { struct guiimg *gi = &gimgs[img_id]; Uint8 *src_scanline, *dst_scanline; Sint32 i; - + src_scanline = mgimg[img_id]; src_scanline += gi->w * oy + ox; - + dst_scanline = (Uint8 *)screen->pixels; dst_scanline += screen->pitch * yp + xp; - - for( i=h; i!=0; --i, src_scanline+=gi->w, dst_scanline+=screen->pitch ) - memcpy( dst_scanline, src_scanline, w ); + + for(i=h; i!=0; --i, src_scanline+=gi->w, dst_scanline+=screen->pitch) + memcpy(dst_scanline, src_scanline, w); } // Copy the video output buffer to the SDL surface, assuming 16bpp video mode -void render_video_sw8( struct machine *oric, SDL_bool doublesize ) +void render_video_sw8(struct machine *oric, SDL_bool doublesize) { int x, y; Uint16 *src_pixel; @@ -234,60 +234,62 @@ void render_video_sw8( struct machine *oric, SDL_bool doublesize ) Uint32 c; Uint8 *dst_scanline, *dst_even_scanline, *dst_odd_scanline; Uint32 *dst_even_pixel, *dst_odd_pixel; - - if( !oric->scr ) + + if(!oric->scr) return; - - if( doublesize ) + + if(doublesize) { - if( needclr ) + if(needclr) { SDL_FillRect(screen, NULL, GPAL_FIRSTPEN); needclr = SDL_FALSE; } - + src_pixel = (Uint16 *)oric->scr; - + dst_pitch_x2 = 2 * screen->pitch; - + dst_even_scanline = ((Uint8*)screen->pixels) + offset_top; - + dst_odd_scanline = dst_even_scanline; dst_odd_scanline += screen->pitch; - - if( oric->scanlines ) + + if(oric->scanlines) { - for( y=0; y<224; y++, dst_even_scanline+=dst_pitch_x2, dst_odd_scanline+=dst_pitch_x2 ) + for(y=0; y<224; y++, dst_even_scanline+=dst_pitch_x2, dst_odd_scanline+=dst_pitch_x2) { - if (!oric->vid_dirty[y]) + if(!oric->vid_dirty[y]) { src_pixel += 120; continue; } dst_even_pixel = (Uint32*)dst_even_scanline; dst_odd_pixel = (Uint32*)dst_odd_scanline; - - for( x=0; x<120; x++ ) + + for(x=0; x<120; x++) { c = *(src_pixel++); *(dst_even_pixel++) = qpen[c]; *(dst_odd_pixel++) = qpen[c+8*257]; } oric->vid_dirty[y] = SDL_FALSE; - + } - } else { - for( y=0; y<224; y++, dst_even_scanline+=dst_pitch_x2, dst_odd_scanline+=dst_pitch_x2 ) + } + else + { + for(y=0; y<224; y++, dst_even_scanline+=dst_pitch_x2, dst_odd_scanline+=dst_pitch_x2) { - if (!oric->vid_dirty[y]) + if(!oric->vid_dirty[y]) { src_pixel += 120; continue; } dst_even_pixel = (Uint32*)dst_even_scanline; dst_odd_pixel = (Uint32*)dst_odd_scanline; - - for( x=0; x<120; x++ ) + + for(x=0; x<120; x++) { c = qpen[*(src_pixel++)]; *(dst_even_pixel++) = c; @@ -298,47 +300,47 @@ void render_video_sw8( struct machine *oric, SDL_bool doublesize ) } return; } - + needclr = SDL_TRUE; - + src_pixel = (Uint16 *)oric->scr; dst_scanline = (Uint8*)screen->pixels; - - for( y=0; y<4; y++ ) + + for(y=0; y<4; y++) { - memset( dst_scanline, 0, 240 ); + memset(dst_scanline, 0, 240); dst_scanline += screen->pitch; } - for( ; y<228; y++, dst_scanline+=screen->pitch ) + for(; y<228; y++, dst_scanline+=screen->pitch) { memcpy(dst_scanline, src_pixel, 240); src_pixel += 240; } } -void preinit_render_sw8( struct machine *oric ) +void preinit_render_sw8(struct machine *oric) { // Screen surface is not set yet screen = NULL; } -SDL_bool render_togglefullscreen_sw8( struct machine *oric ) +SDL_bool render_togglefullscreen_sw8(struct machine *oric) { #if defined(__amigaos4__) || defined(__linux__) // Use SDL_WM_ToggleFullScreen on systems where it is supported - if( SDL_COMPAT_WM_ToggleFullScreen( screen ) ) + if(SDL_COMPAT_WM_ToggleFullScreen(screen)) { fullscreen = !fullscreen; return SDL_TRUE; } - + return SDL_FALSE; #else - oric->shut_render( oric ); + oric->shut_render(oric); fullscreen = !fullscreen; - if( oric->init_render( oric ) ) return SDL_TRUE; - set_render_mode( oric, RENDERMODE_NULL ); - oric->emu_mode = EM_PLEASEQUIT; + if(oric->init_render(oric)) return SDL_TRUE; + set_render_mode(oric, RENDERMODE_NULL); + oric->emu_mode = EM_PLEASEQUIT; return SDL_FALSE; #endif } @@ -352,34 +354,34 @@ static int find_best_pen(Uint8 r, int g, int b) { int i; int closest_pen=-1, closest_distance=8000; - + /* First, look for an exact match */ - for( i=0; i= 256) + if(next_gimgcol >= 256) return closest_pen; - + colours[next_gimgcol].r = r; colours[next_gimgcol].g = g; colours[next_gimgcol].b = b; - + return next_gimgcol++; } @@ -388,46 +390,49 @@ static SDL_bool guiimg_to_img(Uint8** dst, const struct guiimg* src) size_t i; const Uint8 *src_pixel; Uint8 *dst_pixel; - - (*dst) = (Uint8 *)malloc( src->w*src->h ); - if ((*dst) == NULL) + + (*dst) = (Uint8 *)malloc(src->w*src->h); + if((*dst) == NULL) return SDL_FALSE; - + src_pixel = src->buf; dst_pixel = *dst; - - for( i=src->w*src->h; i!=0; --i, src_pixel += 3, ++dst_pixel ) + + for(i=src->w*src->h; i!=0; --i, src_pixel += 3, ++dst_pixel) (*dst_pixel) = find_best_pen(src_pixel[0], src_pixel[1], src_pixel[2]); - + return SDL_TRUE; } -SDL_bool init_render_sw8( struct machine *oric ) +SDL_bool init_render_sw8(struct machine *oric) { int i, j; Sint32 surfacemode; - + surfacemode = SDL_COMPAT_HWPALETTE; - if( fullscreen ) surfacemode |= SDL_COMPAT_FULLSCREEN; - if( hwsurface ) surfacemode |= SDL_COMPAT_HWSURFACE; - + if(fullscreen) surfacemode |= SDL_COMPAT_FULLSCREEN; + if(hwsurface) surfacemode |= SDL_COMPAT_HWSURFACE; + // Try to setup the video display - screen = SDL_COMPAT_SetVideoMode( 640, 480, 8, surfacemode ); - if (oric->show_keyboard) { - screen = SDL_COMPAT_SetVideoMode( 640, 480+240, 8, surfacemode ); - } else { - screen = SDL_COMPAT_SetVideoMode( 640, 480, 8, surfacemode ); + screen = SDL_COMPAT_SetVideoMode(640, 480, 8, surfacemode); + if(oric->show_keyboard) + { + screen = SDL_COMPAT_SetVideoMode(640, 480+240, 8, surfacemode); } - - if( !screen ) + else { - printf( "SDL video failed\n" ); + screen = SDL_COMPAT_SetVideoMode(640, 480, 8, surfacemode); + } + + if(!screen) + { + printf("SDL video failed\n"); return SDL_FALSE; } - - SDL_COMPAT_WM_SetCaption( APP_NAME_FULL, APP_NAME_FULL ); - - for( i=0; i<8; i++ ) + + SDL_COMPAT_WM_SetCaption(APP_NAME_FULL, APP_NAME_FULL); + + for(i=0; i<8; i++) { colours[i].r = oricpalette[i*3 ]; colours[i+8].r = oricpalette[i*3 ]/2; @@ -436,42 +441,42 @@ SDL_bool init_render_sw8( struct machine *oric ) colours[i].b = oricpalette[i*3+2]; colours[i+8].b = oricpalette[i*3+2]/2; } - - for( i=0; ipitch + 80; - - ula_set_dirty( oric ); - + + ula_set_dirty(oric); + // Job done return SDL_TRUE; } -void shut_render_sw8( struct machine *oric ) +void shut_render_sw8(struct machine *oric) { // The surface will be freed by SDL_Quit, or a call to SDL_COMPAT_SetVideoMode from a different render module } diff --git a/render_sw8.h b/render_sw8.h index f114779b..6b54daf4 100644 --- a/render_sw8.h +++ b/render_sw8.h @@ -19,17 +19,17 @@ ** Software rendering */ -void render_begin_sw8( struct machine *oric ); -void render_end_sw8( struct machine *oric ); -void render_textzone_alloc_sw8( struct machine *oric, int i ); -void render_textzone_free_sw8( struct machine *oric, int i ); -void render_textzone_sw8( struct machine *oric, int i ); -void render_gimg_sw8( int i, Sint32 xp, Sint32 yp ); -void render_gimgpart_sw8( int i, Sint32 xp, Sint32 yp, Sint32 ox, Sint32 oy, Sint32 w, Sint32 h ); -void render_video_sw8( struct machine *oric, SDL_bool doublesize ); -void render_clear_area_sw8( int x, int y, int w, int h ); -SDL_bool render_togglefullscreen_sw8( struct machine *oric ); -void preinit_render_sw8( struct machine *oric ); -SDL_bool init_render_sw8( struct machine *oric ); -void shut_render_sw8( struct machine *oric ); +void render_begin_sw8(struct machine *oric); +void render_end_sw8(struct machine *oric); +void render_textzone_alloc_sw8(struct machine *oric, int i); +void render_textzone_free_sw8(struct machine *oric, int i); +void render_textzone_sw8(struct machine *oric, int i); +void render_gimg_sw8(int i, Sint32 xp, Sint32 yp); +void render_gimgpart_sw8(int i, Sint32 xp, Sint32 yp, Sint32 ox, Sint32 oy, Sint32 w, Sint32 h); +void render_video_sw8(struct machine *oric, SDL_bool doublesize); +void render_clear_area_sw8(int x, int y, int w, int h); +SDL_bool render_togglefullscreen_sw8(struct machine *oric); +void preinit_render_sw8(struct machine *oric); +SDL_bool init_render_sw8(struct machine *oric); +void shut_render_sw8(struct machine *oric); diff --git a/roms/basic11b.sym b/roms/basic11b.sym index 6fdc9cf8..c830875b 100644 --- a/roms/basic11b.sym +++ b/roms/basic11b.sym @@ -10,6 +10,7 @@ c4d3 InsDelLine c4e0 DeleteLine c524 InsertLine c55f SetLineLinkPtrs +c444 FreeMemCheck c592 GetLine c5e8 ReadKey c5fa TokeniseLine @@ -167,6 +168,7 @@ ede0 SetupTimer ee1a StopTimer ee22 IRQ ee8c ResetTimer +ee1a StopTimer ee9d GetTimer eeab SetTimer eec9 Delay @@ -213,6 +215,7 @@ fb14 KeyClickH fb1c KeyClickHData fb2a KeyClickL fb32 KeyClickLData +fb14 KeyClickH fb40 SOUND fbd0 PLAY fc18 MUSIC diff --git a/roms/bd500.sym b/roms/bd500.sym new file mode 100644 index 00000000..996bcf14 --- /dev/null +++ b/roms/bd500.sym @@ -0,0 +1,8 @@ +0320 BD_command +0321 BD_track +0322 BD_sector +0323 BD_data +0310 BD_ovlon +0312 BD_control +0313 BD_ovloff +0317 BD_romoff diff --git a/roms/orix10.rom b/roms/empty_orix.rom similarity index 85% rename from roms/orix10.rom rename to roms/empty_orix.rom index 71ca140e..eaf2f772 100644 Binary files a/roms/orix10.rom and b/roms/empty_orix.rom differ diff --git a/roms/kernel.rom b/roms/kernel.rom new file mode 100644 index 00000000..45388d21 Binary files /dev/null and b/roms/kernel.rom differ diff --git a/roms/orixbank1.rom b/roms/orixbank1.rom new file mode 100644 index 00000000..eaf2f772 Binary files /dev/null and b/roms/orixbank1.rom differ diff --git a/roms/orixbank2.rom b/roms/orixbank2.rom new file mode 100644 index 00000000..eaf2f772 Binary files /dev/null and b/roms/orixbank2.rom differ diff --git a/roms/orixbank3.rom b/roms/orixbank3.rom new file mode 100644 index 00000000..eaf2f772 Binary files /dev/null and b/roms/orixbank3.rom differ diff --git a/roms/orixbank4.rom b/roms/orixbank4.rom new file mode 100644 index 00000000..eaf2f772 Binary files /dev/null and b/roms/orixbank4.rom differ diff --git a/roms/orixbank5.rom b/roms/orixbank5.rom new file mode 100644 index 00000000..ed0a3453 Binary files /dev/null and b/roms/orixbank5.rom differ diff --git a/roms/orixbank6.rom b/roms/orixbank6.rom new file mode 100644 index 00000000..38bad85f Binary files /dev/null and b/roms/orixbank6.rom differ diff --git a/roms/orixbank7.rom b/roms/orixbank7.rom new file mode 100644 index 00000000..a9f37356 Binary files /dev/null and b/roms/orixbank7.rom differ diff --git a/roms/pravetzt-1.0.pch b/roms/pravetzt-1.0.pch new file mode 100644 index 00000000..e5505bf5 --- /dev/null +++ b/roms/pravetzt-1.0.pch @@ -0,0 +1,74 @@ +; +; ROM patches file +; +; This file describes how to patch a ROM for things like turbotape, +; and filename decoding. +; + +; ****** ROM INFORMATION ****** + +; This part isn't actual patches, just information about +; the hardware the ROM expects to be present. + +; ROM expects a special keyboard layout? +keymap = qwerty + +; ****** FILENAME DECODING ******* + +; When the PC is about to execute this address, we should be at a point +; in CLOAD/CSAVE/STORE/RECALL where the filename is valid in memory. +fd_cload_getname_pc = $e4af +fd_csave_getname_pc = $e7ef +;fd_store_getname_pc = +;fd_recall_getname_pc = + +; The address to read the CLOAD filename +fd_getname_addr = $0035 + + +; ****** TURBOTAPE ****** + +; Address of the "Cassette Sync" function in ROM +tt_getsync_pc = $e696 + +; Address of the RTS at the end of the cassette sync function (so we can +; skip the function) +tt_getsync_end_pc = $e6b9 + +; If turbotape is enabled, but no tape is inserted, the cassette sync +; function will be executed normally. Here we have an address inside the +; loop that waits for the cassette sync signal, so that we can break out +; of it if a tape is inserted. +tt_getsync_loop_pc = $e681 + +; Address of the "Read Byte" function in ROM +tt_readbyte_pc = $e630 + +; Address of the RTS at the end of the read byte function +tt_readbyte_end_pc = $e65b + +; Set carry at end of readbyte routine? +tt_readbyte_setcarry = no + +; In order to simulate the effects of the read byte routine, you can +; specify an address to write the byte read, and an address to write +; zero to. +tt_readbyte_storebyte_addr = $002f +;tt_readbyte_storezero_addr = + +; Address of the "put byte" function in ROM +tt_putbyte_pc = $e5c6 + +; Address of the RTS at the end of the put byte function +tt_putbyte_end_pc = $e5f2 + +; Address of the RTS at the end of CSAVE +tt_csave_end_pc = $e7fe + +; Address of the RTS at the end of STORE +;tt_store_end_pc = + +; Address of the function that writes the tape leader +; (so we can write a shorter one) +tt_writeleader_pc = $e6ba +tt_writeleader_end_pc = $e6c9 diff --git a/roms/pravetzt-1.0.sym b/roms/pravetzt-1.0.sym new file mode 100644 index 00000000..6dbf9368 --- /dev/null +++ b/roms/pravetzt-1.0.sym @@ -0,0 +1,217 @@ +c006 JumpTab +c0ea Keywords +c2ac ErrorMsgs +c3ca FindForVar +c3f8 VarAlloc +c448 FreeMemCheck +c47c PrintError +c4b5 BackToBASIC +c4e3 InsDelLine +c4e0 DeleteLine +c524 InsertLine +c56f SetLineLinkPtrs +c5a2 GetLine +c5f8 ReadKey +c60a TokeniseLine +c6a5 EDIT +c6de FindLine +c719 NEW +c738 CLEAR +c773 LIST +c824 LLIST +c832 LPRINT +c841 FOR +c8c1 DoNextLine +c8fe DoStatement +c91f RESTORE +c93f STOP +c941 END +c91e CONT +c98b RUN +c996 GOSUB +c9b3 GOTO +c9e0 RETURN +ca0a DATA +ca1c FindEndOfStatement +ca1f FindEOL +ca3e IF +ca61 REM +ca78 ON +ca98 Txt2Int +cad2 LET +cb61 PRINT +cb9f NewLine +cc59 SetCursor +cbed PrintString +cc0a CLS +cc8c TRON +cc8f TROFF +ccba GET +ccc9 INPUT +ccfd READ +ce0c NEXT +ce77 GetExpr +ce8b EvalExpr +cfac DoOper +cf74 GetItem +d03c NOT +d059 EvalBracket +cff0 GetVarVal +d087 Compare +d0f2 DIM +d0fc GetVarFromText +d361 DimArray +d3eb GetArrayElement +d47e FRE +d4a6 POS +d401 DEF +d593 STR +d5a3 SetupString +d4fa GetString +d595 GarbageCollect +d730 CopyString +d767 StrCat +d816 CHR +d82a LEFT +d856 RIGHT +d861 MID +d8a6 LEN +d8b5 ASC +d80a GetByteExpr +d867 FP2Int +d938 PEEK +d894 POKE +d89d WAIT +d8ac DOKE +d983 DEEK +d993 Byte2Hex +d9b5 HEX +d93d LORES +d965 RowCalc +da3f SCRN +d9c6 PLOT +da16 UNTIL +daab REPEAT +dada KEY +da6b TxtTest +db92 Normalise +dbb9 AddMantissas +dc79 LN +dd4d UnpackFPA +dda3 FPAMult10 +ddbf FPADiv10 +d0d0 LOG +de77 PI +def4 RoundFPA +df0b FALSE +df0f TRUE +df04 GetSign +df12 SGN +df31 ABS +df4c CompareFPA +df8c FPA2Int +dfa5 INT +dfcf GetNumber +e076 AddToFPA +e0c1 PrintInt +e22a SQR +e27c ExpData +e2a6 EXP +e313 SeriesEval +e34b RND +e387 COS +e38e SIN +e3d7 TAN +e407 TrigData +e43b ATN +e46f ATNData +e4a8 TapeSync +e4f2 VERIFY +e554 IncTapeCount +e57d PrintSearching +e585 PrintSaving +e58c PrintFName +e594 PrintFound +e5a4 PrintLoading +e5ab PrintVerifying +e5b6 PrintMsg +e5ea ClrStatus +e563 ClrTapeStatus +e5c6 PutTapeByte +e630 GetTapeByte +e696 SyncTape +e6ba WriteLeader +e6ca SetupTape +e725 GetTapeParams +e7aa CLOAD +e903 CLEAR +e7db CSAVE +e80d CALL +e987 STORE +e9d1 RECALL +e87d HiresTest +e905 CheckKbd +e965 HIMEM +e974 GRAB +e994 RELEASE +e9a9 TEXT +e9bb HIRES +ec45 POINT +eccc StartBASIC +edc4 CopyMem +ecc7 SetupTimer +ed01 StopTimer +ed09 IRQ +ed70 ResetTimer +ed81 GetTimer +ed8f SetTimer +e0ad Delay +eee8 WritePixel +eef8 DrawLine +ebdf CURSET +ebe2 CURMOV +ebe5 DRAW +ebeb PATTERN +ebee CHAR +ebf4 PAPER +ebf7 INK +ebfa FILL +ebe8 CIRCLE +f43c ReadKbd +f4ef Key2ASCII +f523 FindKey +f561 ReadKbdCol +f535 WriteToAY +f57b PrintChar +f5d3 ControlChr +f71a ClearLine +f73f Char2Scr +f7e4 PrintA +f7e0 AltChars +f82f PrintStatus +f88f Reset +f8af BASICStart +f8b5 BASICRestart +f920 HiresMode +f967 LoresMode +f960 ResetVIA +f9c9 SetupText +fa14 RamTest +fa85 PING +faa7 PingData +fa9b SHOOT +fabd ShootData +fab1 EXPLODE +facb ExplodeData +fac7 ZAP +fb06 ZapData +fafa KeyClickH +fb1c KeyClickHData +fb10 KeyClickL +fb32 KeyClickLData +fb26 SOUND +fbb6 PLAY +fbfe MUSIC +fc5e MusicData +fc78 CharSet +ff78 KeyCodeTab diff --git a/roms/pravetzt.pch b/roms/pravetzt.pch index 49766948..f6c4dfa9 100644 --- a/roms/pravetzt.pch +++ b/roms/pravetzt.pch @@ -77,8 +77,8 @@ tt_writeleader_end_pc = $e769 $3F78:37EAEDEB20F5F938EEF436392CE9E8EC $3F88:35F2E23B2EEFE730F6E6342D0BF0E52F $3F98:0000000000000000311BFA00087FE10D -$3FA8:F8F1325C0A5DF35E33E4E327095BF73D +$3FA8:F8F1325C0A5DF37C33E4E327095BF73D $3FB8:264A4D4B2055592A4E545E283C49484C $3FC8:2552423A3E4F47295646245F0B50453F $3FD8:0000000000000000211B5A00087F410D -$3FE8:5851407C0A7D537E23444322097B572B +$3FE8:585140600A7D537E23444322097B572B diff --git a/roms/pravetzt.sym b/roms/pravetzt.sym index 6fdc9cf8..c830875b 100644 --- a/roms/pravetzt.sym +++ b/roms/pravetzt.sym @@ -10,6 +10,7 @@ c4d3 InsDelLine c4e0 DeleteLine c524 InsertLine c55f SetLineLinkPtrs +c444 FreeMemCheck c592 GetLine c5e8 ReadKey c5fa TokeniseLine @@ -167,6 +168,7 @@ ede0 SetupTimer ee1a StopTimer ee22 IRQ ee8c ResetTimer +ee1a StopTimer ee9d GetTimer eeab SetTimer eec9 Delay @@ -213,6 +215,7 @@ fb14 KeyClickH fb1c KeyClickHData fb2a KeyClickL fb32 KeyClickLData +fb14 KeyClickH fb40 SOUND fbd0 PLAY fc18 MUSIC diff --git a/roms/shell.rom b/roms/shell.rom new file mode 100644 index 00000000..d10b0e0d Binary files /dev/null and b/roms/shell.rom differ diff --git a/snapshot.c b/snapshot.c index d3b649be..76425911 100644 --- a/snapshot.c +++ b/snapshot.c @@ -41,17 +41,21 @@ #include "tape.h" #include "msgbox.h" +#ifdef WWW +#include +#endif + extern char diskpath[]; #define MAX_BLOCK (262144) -static unsigned char *buf; +static unsigned char* buf; static int offs = 0; #define PUTU32(val) ok=putu32(ok, (Uint32)val) static SDL_bool putu32(SDL_bool stillok, Uint32 val) { - if (!stillok) return SDL_FALSE; - if ((offs+4) > MAX_BLOCK) return SDL_FALSE; + if(!stillok) return SDL_FALSE; + if((offs+4) > MAX_BLOCK) return SDL_FALSE; buf[offs++] = (val>>24)&0xff; buf[offs++] = (val>>16)&0xff; buf[offs++] = (val>>8)&0xff; @@ -62,8 +66,8 @@ static SDL_bool putu32(SDL_bool stillok, Uint32 val) #define PUTU16(val) ok=putu16(ok, (Uint16)val) static SDL_bool putu16(SDL_bool stillok, Uint16 val) { - if (!stillok) return SDL_FALSE; - if ((offs+2) > MAX_BLOCK) return SDL_FALSE; + if(!stillok) return SDL_FALSE; + if((offs+2) > MAX_BLOCK) return SDL_FALSE; buf[offs++] = (val>>8)&0xff; buf[offs++] = val&0xff; return SDL_TRUE; @@ -72,35 +76,35 @@ static SDL_bool putu16(SDL_bool stillok, Uint16 val) #define PUTU8(val) ok=putu8(ok, (Uint8)val) static SDL_bool putu8(SDL_bool stillok, Uint8 val) { - if (!stillok) return SDL_FALSE; - if (offs >= MAX_BLOCK) return SDL_FALSE; + if(!stillok) return SDL_FALSE; + if(offs >= MAX_BLOCK) return SDL_FALSE; buf[offs++] = val&0xff; return SDL_TRUE; } #define PUTDATA(data, size) ok=putdata(ok, data, size) -static SDL_bool putdata(SDL_bool stillok, unsigned char *data, Uint32 size) +static SDL_bool putdata(SDL_bool stillok, unsigned char* data, Uint32 size) { - if (!stillok) return SDL_FALSE; - if ((offs+size) > MAX_BLOCK) return SDL_FALSE; - memcpy( &buf[offs], data, size ); + if(!stillok) return SDL_FALSE; + if((offs+size) > MAX_BLOCK) return SDL_FALSE; + memcpy(&buf[offs], data, size); offs += size; return SDL_TRUE; } #define PUTSTR(str) ok=putstr(ok, str) -static SDL_bool putstr(SDL_bool stillok, char *str) +static SDL_bool putstr(SDL_bool stillok, char* str) { - if (!stillok) return SDL_FALSE; + if(!stillok) return SDL_FALSE; stillok = putu32(stillok, (int)strlen(str)+1); - return putdata(stillok, (unsigned char *)str, (int)strlen(str)+1); + return putdata(stillok, (unsigned char*)str, (int)strlen(str)+1); } #define WRITEBLOCK() ok=writeblock(ok, f) static SDL_bool writeblock(SDL_bool stillok, FILE *f) { - if (!stillok) return SDL_FALSE; - if (offs <= 8) return SDL_TRUE; // No block to write + if(!stillok) return SDL_FALSE; + if(offs <= 8) return SDL_TRUE; // No block to write buf[4] = ((offs-8)>>24)&0xff; buf[5] = ((offs-8)>>16)&0xff; @@ -114,11 +118,11 @@ static SDL_bool writeblock(SDL_bool stillok, FILE *f) // ID must be 4 bytes long! #define NEWBLOCK(id) ok=newblock(ok, id, f) -static SDL_bool newblock(SDL_bool stillok, char *id, FILE *f) +static SDL_bool newblock(SDL_bool stillok, char* id, FILE *f) { - if (!stillok) return SDL_FALSE; + if(!stillok) return SDL_FALSE; // Got an old block? - if (!writeblock(stillok, f)) return SDL_FALSE; + if(!writeblock(stillok, f)) return SDL_FALSE; // Start a new one! memcpy(buf, id, 4); @@ -127,14 +131,14 @@ static SDL_bool newblock(SDL_bool stillok, char *id, FILE *f) } #define DATABLOCK(data, len) ok = datablock(ok, data, len, f) -static SDL_bool datablock(SDL_bool stillok, unsigned char *data, Uint32 len, FILE *f) +static SDL_bool datablock(SDL_bool stillok, unsigned char* data, Uint32 len, FILE *f) { Uint32 lenbe = _BE32(len); - if (!stillok) return SDL_FALSE; + if(!stillok) return SDL_FALSE; // Anything to write? - if (len == 0) return SDL_TRUE; + if(len == 0) return SDL_TRUE; // Got an old block? - if (!writeblock(stillok, f)) return SDL_FALSE; + if(!writeblock(stillok, f)) return SDL_FALSE; stillok = (fwrite("DATA", 4, 1, f) == 1); stillok &= (fwrite(&lenbe, 4, 1, f) == 1); @@ -144,7 +148,7 @@ static SDL_bool datablock(SDL_bool stillok, unsigned char *data, Uint32 len, FIL return stillok; } -SDL_bool save_snapshot(struct machine *oric, char *filename) +SDL_bool save_snapshot(struct machine *oric, char* filename) { SDL_bool ok = SDL_TRUE; struct m6502 *cpu = &oric->cpu; @@ -153,14 +157,14 @@ SDL_bool save_snapshot(struct machine *oric, char *filename) FILE *f = NULL; buf = malloc(MAX_BLOCK); - if (!buf) + if(!buf) { msgbox(oric, MSGBOX_OK, "Snapshot failed: out of memory (1)\n"); return SDL_FALSE; } f = fopen(filename, "wb"); - if (!f) + if(!f) { msgbox(oric, MSGBOX_OK, "Unable to create snapshot file (2)"); free(buf); @@ -248,24 +252,24 @@ SDL_bool save_snapshot(struct machine *oric, char *filename) PUTU8(oric->ay.bmode); PUTU8(oric->ay.creg); PUTDATA(&oric->ay.eregs[0], NUM_AY_REGS); - for (i=0; i<8; i++) + for(i=0; i<8; i++) PUTU8(oric->ay.keystates[i]); - for (i=0; i<3; i++) + for(i=0; i<3; i++) PUTU32(oric->ay.toneper[i]); PUTU32(oric->ay.noiseper); PUTU32(oric->ay.envper); - for (i=0; i<3; i++) + for(i=0; i<3; i++) { PUTU16(oric->ay.tonebit[i]); PUTU16(oric->ay.noisebit[i]); PUTU16(oric->ay.vol[i]); } PUTU16(oric->ay.newout); - for (i=0; i<3; i++) + for(i=0; i<3; i++) PUTU32(oric->ay.ct[i]); PUTU32(oric->ay.ctn); PUTU32(oric->ay.cte); - for (i=0; i<3; i++) + for(i=0; i<3; i++) { PUTU32(oric->ay.tonepos[i]); PUTU32(oric->ay.tonestep[i]); @@ -315,7 +319,7 @@ SDL_bool save_snapshot(struct machine *oric, char *filename) PUTU32(oric->via.irqbit); - switch (oric->drivetype) + switch(oric->drivetype) { case DRV_JASMIN: NEWBLOCK("JSM\x00"); @@ -334,55 +338,55 @@ SDL_bool save_snapshot(struct machine *oric, char *filename) break; case DRV_PRAVETZ: - { - Uint8 tmp[PRAV_TRACKS_PER_DISK*PRAV_RAW_TRACK_SIZE*2]; - NEWBLOCK("PRV\x00"); - PUTU8(oric->pravetz.olay); // 1 - PUTU8(oric->pravetz.romdis); // 2 - PUTU16(oric->pravetz.extension); // 4 - PUTU8(oric->wddisk.c_drive); // 5 - PUTU32(oric->wddisk.currentop); // 9 - - for (i=0; i<2; i++) { - PUTU8(oric->pravetz.drv[i].volume); // +1 - PUTU8(oric->pravetz.drv[i].select); // +2 - PUTU8(oric->pravetz.drv[i].motor_on); // +3 - PUTU8(oric->pravetz.drv[i].write_ready); // +4 - PUTU16(oric->pravetz.drv[i].byte); // +6 - PUTU16(oric->pravetz.drv[i].half_track); // +8 - PUTU8(oric->pravetz.drv[i].dirty); // +9 - PUTU8(oric->pravetz.drv[i].prot); // +10 - } - - /* Snapshot format is limited to one datablock per block, */ - /* concatenate these into a temporary one... */ - memcpy(tmp, &oric->pravetz.drv[0].image[0][0], PRAV_TRACKS_PER_DISK*PRAV_RAW_TRACK_SIZE); - memcpy(&tmp[PRAV_TRACKS_PER_DISK*PRAV_RAW_TRACK_SIZE], &oric->pravetz.drv[1].image[0][0], PRAV_TRACKS_PER_DISK*PRAV_RAW_TRACK_SIZE); - DATABLOCK(tmp, PRAV_TRACKS_PER_DISK*PRAV_RAW_TRACK_SIZE*2); + Uint8 tmp[PRAV_TRACKS_PER_DISK*PRAV_RAW_TRACK_SIZE*2]; + NEWBLOCK("PRV\x00"); + PUTU8(oric->pravetz.olay); // 1 + PUTU8(oric->pravetz.romdis); // 2 + PUTU16(oric->pravetz.extension); // 4 + PUTU8(oric->wddisk.c_drive); // 5 + PUTU32(oric->wddisk.currentop); // 9 + + for(i=0; i<2; i++) + { + PUTU8(oric->pravetz.drv[i].volume); // +1 + PUTU8(oric->pravetz.drv[i].select); // +2 + PUTU8(oric->pravetz.drv[i].motor_on); // +3 + PUTU8(oric->pravetz.drv[i].write_ready); // +4 + PUTU16(oric->pravetz.drv[i].byte); // +6 + PUTU16(oric->pravetz.drv[i].half_track); // +8 + PUTU8(oric->pravetz.drv[i].dirty); // +9 + PUTU8(oric->pravetz.drv[i].prot); // +10 + } - for (i=0; i<2; i++) - { - if ((oric->pravetz.drv[i].pimg == NULL) || - (oric->pravetz.drv[i].pimg->rawimage == NULL)) - break; + /* Snapshot format is limited to one datablock per block, */ + /* concatenate these into a temporary one... */ + memcpy(tmp, &oric->pravetz.drv[0].image[0][0], PRAV_TRACKS_PER_DISK*PRAV_RAW_TRACK_SIZE); + memcpy(&tmp[PRAV_TRACKS_PER_DISK*PRAV_RAW_TRACK_SIZE], &oric->pravetz.drv[1].image[0][0], PRAV_TRACKS_PER_DISK*PRAV_RAW_TRACK_SIZE); + DATABLOCK(tmp, PRAV_TRACKS_PER_DISK*PRAV_RAW_TRACK_SIZE*2); - NEWBLOCK("PVD\x00"); - PUTU16(i); - PUTU32(oric->wddisk.disk[i]->rawimagelen); - /* Convert sector_ptr to an offset */ - if ((oric->pravetz.drv[i].sector_ptr == NULL) || - (oric->pravetz.drv[i].pimg == NULL) || - (oric->pravetz.drv[i].pimg->rawimage == NULL)) - PUTU32(0xffffffff); - else - PUTU32((Uint32)(oric->pravetz.drv[i].sector_ptr - oric->pravetz.drv[i].pimg->rawimage)); - DATABLOCK(oric->wddisk.disk[i]->rawimage, oric->wddisk.disk[i]->rawimagelen); + for(i=0; i<2; i++) + { + if((oric->pravetz.drv[i].pimg == NULL) || + (oric->pravetz.drv[i].pimg->rawimage == NULL)) + break; + + NEWBLOCK("PVD\x00"); + PUTU16(i); + PUTU32(oric->wddisk.disk[i]->rawimagelen); + /* Convert sector_ptr to an offset */ + if((oric->pravetz.drv[i].sector_ptr == NULL) || + (oric->pravetz.drv[i].pimg == NULL) || + (oric->pravetz.drv[i].pimg->rawimage == NULL)) + PUTU32(0xffffffff); + else + PUTU32((Uint32)(oric->pravetz.drv[i].sector_ptr - oric->pravetz.drv[i].pimg->rawimage)); + DATABLOCK(oric->wddisk.disk[i]->rawimage, oric->wddisk.disk[i]->rawimagelen); + } } - } } - if( do_wd17xx ) + if(do_wd17xx) { NEWBLOCK("WDD\x00"); PUTU8(oric->wddisk.r_status); @@ -403,9 +407,9 @@ SDL_bool save_snapshot(struct machine *oric, char *filename) PUTU32(oric->wddisk.ddstatus); PUTU32(oric->wddisk.crc); - for (i=0; i<4; i++) + for(i=0; i<4; i++) { - if( oric->wddisk.disk[i] ) + if(oric->wddisk.disk[i]) { NEWBLOCK("DSK\x00"); PUTU16(oric->wddisk.disk[i]->drivenum); @@ -420,11 +424,11 @@ SDL_bool save_snapshot(struct machine *oric, char *filename) } } - if (oric->type == MACH_TELESTRAT) + if(oric->type == MACH_TELESTRAT) { // Bank info NEWBLOCK("BNK\x00"); - for (i=0; i<8; i++) + for(i=0; i<8; i++) PUTU8(oric->tele_bank[i].type); PUTU8(oric->tele_currbank); @@ -470,10 +474,10 @@ SDL_bool save_snapshot(struct machine *oric, char *filename) } // Symbols - if (oric->romsyms.numsyms) + if(oric->romsyms.numsyms) { NEWBLOCK("SYR\x00"); - for (i=0; iromsyms.numsyms; i++) + for(i=0; iromsyms.numsyms; i++) { PUTSTR(oric->romsyms.syms[i].name); PUTU16(oric->romsyms.syms[i].addr); @@ -481,10 +485,10 @@ SDL_bool save_snapshot(struct machine *oric, char *filename) } } - if (oric->usersyms.numsyms) + if(oric->usersyms.numsyms) { NEWBLOCK("SYU\x00"); - for (i=0; iusersyms.numsyms; i++) + for(i=0; iusersyms.numsyms; i++) { PUTSTR(oric->usersyms.syms[i].name); PUTU16(oric->usersyms.syms[i].addr); @@ -492,16 +496,16 @@ SDL_bool save_snapshot(struct machine *oric, char *filename) } } - if (oric->type == MACH_TELESTRAT) + if(oric->type == MACH_TELESTRAT) { - for (j=0; j<8; j++) + for(j=0; j<8; j++) { - if (oric->tele_banksyms[j].numsyms) + if(oric->tele_banksyms[j].numsyms) { char name[8]; sprintf(name, "SY%d%c", j, 0); NEWBLOCK(name); - for (i=0; itele_banksyms[j].numsyms; i++) + for(i=0; itele_banksyms[j].numsyms; i++) { PUTSTR(oric->tele_banksyms[j].syms[i].name); PUTU16(oric->romsyms.syms[i].addr); @@ -512,12 +516,12 @@ SDL_bool save_snapshot(struct machine *oric, char *filename) } // Breakpoints - if ((cpu->anybp) || (cpu->anymbp)) + if((cpu->anybp) || (cpu->anymbp)) { NEWBLOCK("BKP\x00"); - for (i=0; i<16; i++) + for(i=0; i<16; i++) PUTU32(cpu->breakpoints[i]); - for (i=0; i<16; i++) + for(i=0; i<16; i++) { PUTU8(cpu->membreakpoints[i].flags); PUTU8(cpu->membreakpoints[i].lastval); @@ -529,9 +533,19 @@ SDL_bool save_snapshot(struct machine *oric, char *filename) fclose(f); free(buf); - if (!ok) + if(!ok) msgbox(oric, MSGBOX_OK, "Snapshot failed! (3)"); +#ifdef WWW + // sync from memory state to persisted + EM_ASM( + FS.syncfs(function(err) + { + assert(!err); + }); + ); +#endif + return ok; } @@ -542,7 +556,7 @@ struct blockheader unsigned char id[4]; unsigned int offset; unsigned int size; - unsigned char *buf; + unsigned char* buf; struct blockheader *datablock; int offs; }; @@ -564,9 +578,9 @@ static SDL_bool getheaders(struct machine *oric, FILE *f) /* and make sure the file structure is sane. */ offset = 0; numhdrs = 0; - while (offset < filesize) + while(offset < filesize) { - if (fread(hdr, 8, 1, f) != 1) + if(fread(hdr, 8, 1, f) != 1) { msgbox(oric, MSGBOX_OK, "Snapshot load failed: Read error (4)"); numhdrs = 0; @@ -574,7 +588,7 @@ static SDL_bool getheaders(struct machine *oric, FILE *f) } size = (hdr[4]<<24)|(hdr[5]<<16)|(hdr[6]<<8)|hdr[7]; - if ((size == 0) || ((offset+size) > filesize)) + if((size == 0) || ((offset+size) > filesize)) { msgbox(oric, MSGBOX_OK, "Snapshot load failed: Invalid file structure (5)"); numhdrs = 0; @@ -588,7 +602,7 @@ static SDL_bool getheaders(struct machine *oric, FILE *f) /* Allocate memory to store all the block headers */ bkh = (struct blockheader *)malloc(numhdrs*sizeof(struct blockheader)); - if (!bkh) + if(!bkh) { msgbox(oric, MSGBOX_OK, "Snapshot load failed: Out of memory (6)"); numhdrs = 0; @@ -600,9 +614,9 @@ static SDL_bool getheaders(struct machine *oric, FILE *f) fseek(f, 0, SEEK_SET); offset = 0; i = 0; - while (offset < filesize) + while(offset < filesize) { - if (fread(hdr, 8, 1, f) != 1) + if(fread(hdr, 8, 1, f) != 1) { msgbox(oric, MSGBOX_OK, "Snapshot load failed: Read error (7)"); free(bkh); @@ -612,7 +626,7 @@ static SDL_bool getheaders(struct machine *oric, FILE *f) } size = (hdr[4]<<24)|(hdr[5]<<16)|(hdr[6]<<8)|hdr[7]; - if ((size == 0) || ((offset+size) > filesize)) + if((size == 0) || ((offset+size) > filesize)) { msgbox(oric, MSGBOX_OK, "Snapshot load failed: Invalid file structure (8)"); free(bkh); @@ -627,7 +641,7 @@ static SDL_bool getheaders(struct machine *oric, FILE *f) bkh[i].size = size; //printf("Block: %c%c%c%c (@ %d, size %d)\n", bkh[i].id[0], bkh[i].id[1], (bkh[i].id[2]>31)?bkh[i].id[2]:'.', (bkh[i].id[3]>31)?bkh[i].id[3]:'.', bkh[i].offset, bkh[i].size); - if ((i>0) && (memcmp(bkh[i].id, "DATA", 4)==0)) + if((i>0) && (memcmp(bkh[i].id, "DATA", 4)==0)) { bkh[i-1].datablock = &bkh[i]; } @@ -642,7 +656,7 @@ static SDL_bool getheaders(struct machine *oric, FILE *f) static void free_block(struct blockheader *blk) { - if ((!blk)||(!blk->buf)) return; + if((!blk)||(!blk->buf)) return; free(blk->buf); blk->buf = NULL; } @@ -651,63 +665,63 @@ static void free_blockheaders(void) { int i; - if (!bkh) return; + if(!bkh) return; - for (i=0; i31)?id[2]:'.', (id[3]>31)?id[3]:'.'); - if (required) msgbox(oric, MSGBOX_OK, "Snapshot load failed: Invalid file (9)"); + if(required) msgbox(oric, MSGBOX_OK, "Snapshot load failed: Invalid file (9)"); return NULL; } - if ((datarequired) && (bkh[i].datablock == NULL)) + if((datarequired) && (bkh[i].datablock == NULL)) { - if (required) msgbox(oric, MSGBOX_OK, "Snapshot load failed: Invalid file (10)"); + if(required) msgbox(oric, MSGBOX_OK, "Snapshot load failed: Invalid file (10)"); return NULL; } - if ((expectedsize != -1) && (bkh[i].size != expectedsize)) + if((expectedsize != -1) && (bkh[i].size != expectedsize)) { //printf("Size for %c%c%c%c is %d, expected %d\n", id[0], id[1], (id[2]>31)?id[2]:'.', (id[3]>31)?id[3]:'.', bkh[i].size, expectedsize); - if (required) msgbox(oric, MSGBOX_OK, "Snapshot load failed: Invalid file (11)"); + if(required) msgbox(oric, MSGBOX_OK, "Snapshot load failed: Invalid file (11)"); return NULL; } /* Already loaded it?! */ - if (bkh[i].buf) + if(bkh[i].buf) { bkh[i].offs = 0; return &bkh[i]; } bkh[i].buf = malloc(bkh[i].size); - if (!bkh[i].buf) + if(!bkh[i].buf) { - if (required) msgbox(oric, MSGBOX_OK, "Snapshot load failed: Out of memory (12)"); + if(required) msgbox(oric, MSGBOX_OK, "Snapshot load failed: Out of memory (12)"); return NULL; } fseek(f, bkh[i].offset, SEEK_SET); - if (fread(bkh[i].buf, bkh[i].size, 1, f) != 1) + if(fread(bkh[i].buf, bkh[i].size, 1, f) != 1) { - if (required) msgbox(oric, MSGBOX_OK, "Snapshot load failed: Read error (13)"); + if(required) msgbox(oric, MSGBOX_OK, "Snapshot load failed: Read error (13)"); return NULL; } @@ -715,24 +729,24 @@ static struct blockheader *load_block(struct machine *oric, char *id, FILE *f, S return &bkh[i]; } -static SDL_bool read_block(struct machine *oric, struct blockheader *blk, FILE *f, SDL_bool required, unsigned char *destbuf) +static SDL_bool read_block(struct machine *oric, struct blockheader *blk, FILE *f, SDL_bool required, unsigned char* destbuf) { - if (!blk) + if(!blk) { - if (required) msgbox(oric, MSGBOX_OK, "Snapshot load failed: Internal error (14)"); + if(required) msgbox(oric, MSGBOX_OK, "Snapshot load failed: Internal error (14)"); return SDL_FALSE; } - if (blk->buf) + if(blk->buf) { memcpy(destbuf, blk->buf, blk->size); return SDL_TRUE; } fseek(f, blk->offset, SEEK_SET); - if (fread(destbuf, blk->size, 1, f) != 1) + if(fread(destbuf, blk->size, 1, f) != 1) { - if (required) msgbox(oric, MSGBOX_OK, "Snapshot load failed: Read error (15)"); + if(required) msgbox(oric, MSGBOX_OK, "Snapshot load failed: Read error (15)"); return SDL_FALSE; } @@ -746,12 +760,14 @@ static Uint32 getu32(struct blockheader *blk) return val; } +#ifdef WWW_MONITOR static Sint32 gets32(struct blockheader *blk) { Sint32 val = (blk->buf[blk->offs]<<24)|(blk->buf[blk->offs+1]<<16)|(blk->buf[blk->offs+2]<<8)|blk->buf[blk->offs+3]; blk->offs+=4; return val; } +#endif static Uint16 getu16(struct blockheader *blk) { @@ -772,13 +788,13 @@ static Uint8 getu8(struct blockheader *blk) return blk->buf[blk->offs++]; } -static void getdata(struct blockheader *blk, unsigned char *dest, unsigned int size) +static void getdata(struct blockheader *blk, unsigned char* dest, unsigned int size) { memcpy(dest, &blk->buf[blk->offs], size); blk->offs += size; } -SDL_bool load_snapshot(struct machine *oric, char *filename) +SDL_bool load_snapshot(struct machine *oric, char* filename) { struct m6502 *cpu = &oric->cpu; int i; @@ -788,7 +804,7 @@ SDL_bool load_snapshot(struct machine *oric, char *filename) struct blockheader *blk = NULL; f = fopen(filename, "rb"); - if (!f) + if(!f) { msgbox(oric, MSGBOX_OK, "Unable to open snapshot file (16)"); return SDL_FALSE; @@ -802,7 +818,7 @@ SDL_bool load_snapshot(struct machine *oric, char *filename) /* Get the main block */ blk = load_block(oric, "OSN\x00", f, SDL_TRUE, 21, SDL_TRUE); - if (!blk) + if(!blk) { free_blockheaders(); fclose(f); @@ -813,7 +829,7 @@ SDL_bool load_snapshot(struct machine *oric, char *filename) type = blk->buf[0]; drivetype = blk->buf[14]; - if (type >= MACH_LAST) + if(type >= MACH_LAST) { msgbox(oric, MSGBOX_OK, "Snapshot load failed: Invalid file (17)"); free_blockheaders(); @@ -825,27 +841,27 @@ SDL_bool load_snapshot(struct machine *oric, char *filename) /* Perform some validation */ if((oric->drivetype != drivetype) || // Unrecognised or invalid drive type - (oric->memsize != blk->datablock->size)) // Memsize incorrect for type + (oric->memsize != blk->datablock->size)) // Memsize incorrect for type { msgbox(oric, MSGBOX_OK, "Snapshot load failed: Invalid file (18)"); free_blockheaders(); fclose(f); - if (back2mon) setemumode(oric, NULL, EM_DEBUG); + if(back2mon) setemumode(oric, NULL, EM_DEBUG); return SDL_FALSE; } /* Read in the memory */ - if (!read_block(oric, blk->datablock, f, SDL_TRUE, oric->mem)) + if(!read_block(oric, blk->datablock, f, SDL_TRUE, oric->mem)) { free_blockheaders(); fclose(f); - if (back2mon) setemumode(oric, NULL, EM_DEBUG); + if(back2mon) setemumode(oric, NULL, EM_DEBUG); return SDL_FALSE; } /* Clear things that will get replaced */ - clear_patches( oric ); - if (oric->tapebuf) + clear_patches(oric); + if(oric->tapebuf) { free(oric->tapebuf); oric->tapebuf = NULL; @@ -856,35 +872,37 @@ SDL_bool load_snapshot(struct machine *oric, char *filename) oric->overclockmult = getu32(blk); oric->overclockshift = getu32(blk); oric->vsync = getu16(blk); - oric->romdis = getu8 (blk); - oric->romon = getu8 (blk); - oric->vsynchack = getu8 (blk); + oric->romdis = getu8(blk); + oric->romon = getu8(blk); + oric->vsynchack = getu8(blk); blk->offs++; // Skip drivetype (already got it) - oric->tapeturbo = getu8 (blk); - oric->vid_mode = getu8 (blk); + oric->tapeturbo = getu8(blk); + oric->vid_mode = getu8(blk); oric->keymap = getu32(blk); // Finished with this one free_block(blk); oric->vid_freq = oric->vid_mode&2; - if( oric->vid_mode & 4 ) + if(oric->vid_mode & 4) { oric->vid_addr = oric->vidbases[0]; oric->vid_ch_base = &oric->mem[oric->vidbases[1]]; - } else { + } + else + { oric->vid_addr = oric->vidbases[2]; oric->vid_ch_base = &oric->mem[oric->vidbases[3]]; } /* Get the CPU block */ blk = load_block(oric, "CPU\x00", f, SDL_TRUE, 21, SDL_FALSE); - if (!blk) + if(!blk) { free_blockheaders(); fclose(f); - setmenutoggles( oric ); - if (back2mon) setemumode(oric, NULL, EM_DEBUG); + setmenutoggles(oric); + if(back2mon) setemumode(oric, NULL, EM_DEBUG); return SDL_FALSE; } @@ -893,28 +911,28 @@ SDL_bool load_snapshot(struct machine *oric, char *filename) cpu->lastpc = getu16(blk); cpu->calcpc = getu16(blk); cpu->calcint = getu16(blk); - cpu->nmi = getu8 (blk); - cpu->a = getu8 (blk); - cpu->x = getu8 (blk); - cpu->y = getu8 (blk); - cpu->sp = getu8 (blk); - i = getu8 (blk); + cpu->nmi = getu8(blk); + cpu->a = getu8(blk); + cpu->x = getu8(blk); + cpu->y = getu8(blk); + cpu->sp = getu8(blk); + i = getu8(blk); SETFLAGS(i); - cpu->irq = getu8 (blk); - cpu->nmicount = getu8 (blk); - cpu->calcop = getu8 (blk); + cpu->irq = getu8(blk); + cpu->nmicount = getu8(blk); + cpu->calcop = getu8(blk); // Finished with this one free_block(blk); /* Get the AY block */ blk = load_block(oric, "AY\x00\x00", f, SDL_TRUE, 153, SDL_FALSE); - if (!blk) + if(!blk) { free_blockheaders(); fclose(f); - setmenutoggles( oric ); - if (back2mon) setemumode(oric, NULL, EM_DEBUG); + setmenutoggles(oric); + if(back2mon) setemumode(oric, NULL, EM_DEBUG); return SDL_FALSE; } @@ -922,24 +940,24 @@ SDL_bool load_snapshot(struct machine *oric, char *filename) oric->ay.creg = getu8(blk); getdata(blk, &oric->ay.eregs[0], NUM_AY_REGS); memcpy(&oric->ay.regs[0], &oric->ay.eregs[0], NUM_AY_REGS); - for (i=0; i<8; i++) + for(i=0; i<8; i++) oric->ay.keystates[i] = getu8(blk); - for (i=0; i<3; i++) + for(i=0; i<3; i++) oric->ay.toneper[i] = getu32(blk); oric->ay.noiseper = getu32(blk); oric->ay.envper = getu32(blk); - for (i=0; i<3; i++) + for(i=0; i<3; i++) { oric->ay.tonebit[i] = getu16(blk); oric->ay.noisebit[i] = getu16(blk); oric->ay.vol[i] = getu16(blk); } oric->ay.newout = getu16(blk); - for (i=0; i<3; i++) + for(i=0; i<3; i++) oric->ay.ct[i] = getu32(blk); oric->ay.ctn = getu32(blk); oric->ay.cte = getu32(blk); - for (i=0; i<3; i++) + for(i=0; i<3; i++) { oric->ay.tonepos[i] = getu32(blk); oric->ay.tonestep[i] = getu32(blk); @@ -957,47 +975,47 @@ SDL_bool load_snapshot(struct machine *oric, char *filename) /* Get the VIA block */ blk = load_block(oric, "VIA\x00", f, SDL_TRUE, 39, SDL_FALSE); - if (!blk) + if(!blk) { free_blockheaders(); fclose(f); - setmenutoggles( oric ); - if (back2mon) setemumode(oric, NULL, EM_DEBUG); + setmenutoggles(oric); + if(back2mon) setemumode(oric, NULL, EM_DEBUG); return SDL_FALSE; } - oric->via.ifr = getu8 (blk); - oric->via.irb = getu8 (blk); - oric->via.orb = getu8 (blk); - oric->via.irbl = getu8 (blk); - oric->via.ira = getu8 (blk); - oric->via.ora = getu8 (blk); - oric->via.iral = getu8 (blk); - oric->via.ddra = getu8 (blk); - oric->via.ddrb = getu8 (blk); - oric->via.t1l_l = getu8 (blk); - oric->via.t1l_h = getu8 (blk); + oric->via.ifr = getu8(blk); + oric->via.irb = getu8(blk); + oric->via.orb = getu8(blk); + oric->via.irbl = getu8(blk); + oric->via.ira = getu8(blk); + oric->via.ora = getu8(blk); + oric->via.iral = getu8(blk); + oric->via.ddra = getu8(blk); + oric->via.ddrb = getu8(blk); + oric->via.t1l_l = getu8(blk); + oric->via.t1l_h = getu8(blk); oric->via.t1c = getu16(blk); - oric->via.t2l_l = getu8 (blk); - oric->via.t2l_h = getu8 (blk); + oric->via.t2l_l = getu8(blk); + oric->via.t2l_h = getu8(blk); oric->via.t2c = getu16(blk); - oric->via.sr = getu8 (blk); - oric->via.acr = getu8 (blk); - oric->via.pcr = getu8 (blk); - oric->via.ier = getu8 (blk); - oric->via.ca1 = getu8 (blk); - oric->via.ca2 = getu8 (blk); - oric->via.cb1 = getu8 (blk); - oric->via.cb2 = getu8 (blk); - oric->via.srcount = getu8 (blk); - oric->via.t1reload = getu8 (blk); - oric->via.t2reload = getu8 (blk); + oric->via.sr = getu8(blk); + oric->via.acr = getu8(blk); + oric->via.pcr = getu8(blk); + oric->via.ier = getu8(blk); + oric->via.ca1 = getu8(blk); + oric->via.ca2 = getu8(blk); + oric->via.cb1 = getu8(blk); + oric->via.cb2 = getu8(blk); + oric->via.srcount = getu8(blk); + oric->via.t1reload = getu8(blk); + oric->via.t2reload = getu8(blk); oric->via.srtime = getu16(blk); - oric->via.t1run = getu8 (blk); - oric->via.t2run = getu8 (blk); - oric->via.ca2pulse = getu8 (blk); - oric->via.cb2pulse = getu8 (blk); - oric->via.srtrigger= getu8 (blk); + oric->via.t1run = getu8(blk); + oric->via.t2run = getu8(blk); + oric->via.ca2pulse = getu8(blk); + oric->via.cb2pulse = getu8(blk); + oric->via.srtrigger= getu8(blk); oric->via.irqbit = getu32(blk); // Finished with this one @@ -1005,18 +1023,18 @@ SDL_bool load_snapshot(struct machine *oric, char *filename) /* Get the tape block */ blk = load_block(oric, "TAP\x00", f, SDL_TRUE, 46, SDL_FALSE); - if (!blk) + if(!blk) { free_blockheaders(); fclose(f); - setmenutoggles( oric ); - if (back2mon) setemumode(oric, NULL, EM_DEBUG); + setmenutoggles(oric); + if(back2mon) setemumode(oric, NULL, EM_DEBUG); return SDL_FALSE; } - oric->tapebit = getu8 (blk); - oric->tapeout = getu8 (blk); - oric->tapeparity = getu8 (blk); + oric->tapebit = getu8(blk); + oric->tapeout = getu8(blk); + oric->tapeparity = getu8(blk); oric->tapelen = getu32(blk); oric->tapeoffs = getu32(blk); oric->tapecount = getu32(blk); @@ -1024,14 +1042,14 @@ SDL_bool load_snapshot(struct machine *oric, char *filename) oric->tapedupbytes= getu32(blk); oric->tapehdrend = getu32(blk); oric->tapedelay = getu32(blk); - oric->tapemotor = getu8 (blk); + oric->tapemotor = getu8(blk); oric->tapeturbo_forceoff= getu8(blk); - oric->rawtape = getu8 (blk); + oric->rawtape = getu8(blk); oric->nonrawend = getu32(blk); oric->tapehitend = getu32(blk); oric->tapeturbo_syncstack = getu32(blk); - if (!blk->datablock) + if(!blk->datablock) { oric->tapelen = 0; oric->tapeoffs = 0; @@ -1039,22 +1057,22 @@ SDL_bool load_snapshot(struct machine *oric, char *filename) else { oric->tapebuf = malloc(blk->datablock->size); - if (!oric->tapebuf) + if(!oric->tapebuf) { msgbox(oric, MSGBOX_OK, "Snapshot load failed: Out of memory (19)"); free_blockheaders(); fclose(f); - setmenutoggles( oric ); - if (back2mon) setemumode(oric, NULL, EM_DEBUG); + setmenutoggles(oric); + if(back2mon) setemumode(oric, NULL, EM_DEBUG); return SDL_FALSE; } - if (!read_block(oric, blk->datablock, f, SDL_TRUE, oric->tapebuf)) + if(!read_block(oric, blk->datablock, f, SDL_TRUE, oric->tapebuf)) { free_blockheaders(); fclose(f); - setmenutoggles( oric ); - if (back2mon) setemumode(oric, NULL, EM_DEBUG); + setmenutoggles(oric); + if(back2mon) setemumode(oric, NULL, EM_DEBUG); return SDL_FALSE; } } @@ -1063,7 +1081,7 @@ SDL_bool load_snapshot(struct machine *oric, char *filename) free_block(blk); /* Get the patch block */ - if ((blk = load_block(oric, "PCH\x00", f, SDL_FALSE, 76, SDL_FALSE))) + if((blk = load_block(oric, "PCH\x00", f, SDL_FALSE, 76, SDL_FALSE))) { oric->pch_fd_cload_getname_pc = getu32(blk); oric->pch_fd_csave_getname_pc = getu32(blk); @@ -1084,25 +1102,25 @@ SDL_bool load_snapshot(struct machine *oric, char *filename) oric->pch_tt_store_end_pc = getu32(blk); oric->pch_tt_writeleader_pc = getu32(blk); oric->pch_tt_writeleader_end_pc = getu32(blk); - oric->pch_tt_readbyte_setcarry = getu8 (blk); - oric->pch_tt_available = getu8 (blk); - oric->pch_tt_save_available = getu8 (blk); + oric->pch_tt_readbyte_setcarry = getu8(blk); + oric->pch_tt_available = getu8(blk); + oric->pch_tt_save_available = getu8(blk); // Finished with this one free_block(blk); } - switch (oric->drivetype) + switch(oric->drivetype) { case DRV_JASMIN: /* Get the jasmin block */ blk = load_block(oric, "JSM\x00", f, SDL_TRUE, 2, SDL_FALSE); - if (!blk) + if(!blk) { free_blockheaders(); fclose(f); - setmenutoggles( oric ); - if (back2mon) setemumode(oric, NULL, EM_DEBUG); + setmenutoggles(oric); + if(back2mon) setemumode(oric, NULL, EM_DEBUG); return SDL_FALSE; } @@ -1118,12 +1136,12 @@ SDL_bool load_snapshot(struct machine *oric, char *filename) case DRV_MICRODISC: /* Get the microdisc block */ blk = load_block(oric, "MDC\x00", f, SDL_TRUE, 4, SDL_FALSE); - if (!blk) + if(!blk) { free_blockheaders(); fclose(f); - setmenutoggles( oric ); - if (back2mon) setemumode(oric, NULL, EM_DEBUG); + setmenutoggles(oric); + if(back2mon) setemumode(oric, NULL, EM_DEBUG); return SDL_FALSE; } @@ -1139,155 +1157,155 @@ SDL_bool load_snapshot(struct machine *oric, char *filename) break; case DRV_PRAVETZ: - { - Uint8 tmp[PRAV_TRACKS_PER_DISK*PRAV_RAW_TRACK_SIZE*2]; - Uint32 offs_; - - /* Get the pravetz block */ - blk = load_block(oric, "PRV\x00", f, SDL_TRUE, 9+2*10, SDL_TRUE); - if (!blk) - { - free_blockheaders(); - fclose(f); - setmenutoggles( oric ); - if (back2mon) setemumode(oric, NULL, EM_DEBUG); - return SDL_FALSE; - } - - oric->pravetz.olay = getu8(blk); - oric->pravetz.romdis = getu8(blk); - oric->pravetz.extension = getu16(blk); - oric->wddisk.c_drive = getu8(blk); - oric->wddisk.currentop = getu32(blk); - - for (i=0; i<2; i++) { - oric->pravetz.drv[i].volume = getu8(blk); - oric->pravetz.drv[i].select = getu8(blk); - oric->pravetz.drv[i].motor_on = getu8(blk); - oric->pravetz.drv[i].write_ready = getu8(blk); - oric->pravetz.drv[i].byte = getu16(blk); - oric->pravetz.drv[i].half_track = getu16(blk); - oric->pravetz.drv[i].dirty = getu8(blk); - oric->pravetz.drv[i].prot = getu8(blk); - } - - if (!read_block(oric, blk->datablock, f, SDL_TRUE, tmp)) - { - free_blockheaders(); - fclose(f); - setmenutoggles( oric ); - if (back2mon) setemumode(oric, NULL, EM_DEBUG); - return SDL_FALSE; - } + Uint8 tmp[PRAV_TRACKS_PER_DISK*PRAV_RAW_TRACK_SIZE*2]; + Uint32 offs_; - memcpy(&oric->pravetz.drv[0].image[0][0], tmp, PRAV_TRACKS_PER_DISK*PRAV_RAW_TRACK_SIZE); - memcpy(&oric->pravetz.drv[1].image[0][0], &tmp[PRAV_TRACKS_PER_DISK*PRAV_RAW_TRACK_SIZE], PRAV_TRACKS_PER_DISK*PRAV_RAW_TRACK_SIZE); - - free_block(blk); - - // Get the disk images - while ((blk = load_block(oric, "PVD\x00", f, SDL_FALSE, -1, SDL_FALSE))) - { - // Get the drive associated with this disk image - i = getu16(blk); - if ((i<0) || (i>1) || (oric->wddisk.disk[i] != NULL) || (!blk->datablock) || (blk->size != 10)) + /* Get the pravetz block */ + blk = load_block(oric, "PRV\x00", f, SDL_TRUE, 9+2*10, SDL_TRUE); + if(!blk) { - msgbox(oric, MSGBOX_OK, "Snapshot load failed: Invalid file (PVD1)"); free_blockheaders(); fclose(f); - setmenutoggles( oric ); - if (back2mon) setemumode(oric, NULL, EM_DEBUG); + setmenutoggles(oric); + if(back2mon) setemumode(oric, NULL, EM_DEBUG); return SDL_FALSE; } - // Allocate a diskimage header - oric->wddisk.disk[i] = (struct diskimage *)malloc(sizeof(struct diskimage)); - if (!oric->wddisk.disk[i]) - { - msgbox(oric, MSGBOX_OK, "Snapshot load failed: Out of memory (PVD2)"); - free_blockheaders(); - fclose(f); - setmenutoggles( oric ); - if (back2mon) setemumode(oric, NULL, EM_DEBUG); - return SDL_FALSE; - } - memset(oric->wddisk.disk[i], 0, sizeof(struct diskimage)); + oric->pravetz.olay = getu8(blk); + oric->pravetz.romdis = getu8(blk); + oric->pravetz.extension = getu16(blk); + oric->wddisk.c_drive = getu8(blk); + oric->wddisk.currentop = getu32(blk); - // Allocate space for the disk image - oric->wddisk.disk[i]->rawimage = malloc(blk->datablock->size); - if (!oric->wddisk.disk[i]) + for(i=0; i<2; i++) { - free(oric->wddisk.disk[i]); - oric->wddisk.disk[i] = NULL; - msgbox(oric, MSGBOX_OK, "Snapshot load failed: Out of memory (PVD3)"); - free_blockheaders(); - fclose(f); - setmenutoggles( oric ); - if (back2mon) setemumode(oric, NULL, EM_DEBUG); - return SDL_FALSE; + oric->pravetz.drv[i].volume = getu8(blk); + oric->pravetz.drv[i].select = getu8(blk); + oric->pravetz.drv[i].motor_on = getu8(blk); + oric->pravetz.drv[i].write_ready = getu8(blk); + oric->pravetz.drv[i].byte = getu16(blk); + oric->pravetz.drv[i].half_track = getu16(blk); + oric->pravetz.drv[i].dirty = getu8(blk); + oric->pravetz.drv[i].prot = getu8(blk); } - // Read in the disk image - if (!read_block(oric, blk->datablock, f, SDL_TRUE, oric->wddisk.disk[i]->rawimage)) + if(!read_block(oric, blk->datablock, f, SDL_TRUE, tmp)) { - free(oric->wddisk.disk[i]->rawimage); - free(oric->wddisk.disk[i]); - oric->wddisk.disk[i] = NULL; free_blockheaders(); fclose(f); - setmenutoggles( oric ); - if (back2mon) setemumode(oric, NULL, EM_DEBUG); + setmenutoggles(oric); + if(back2mon) setemumode(oric, NULL, EM_DEBUG); return SDL_FALSE; } - oric->wddisk.disk[i]->cachedtrack = -1; - oric->wddisk.disk[i]->cachedside = -1; - - // Fill out the disk image header - oric->wddisk.disk[i]->drivenum = i; - oric->wddisk.disk[i]->rawimagelen = getu32(blk); + memcpy(&oric->pravetz.drv[0].image[0][0], tmp, PRAV_TRACKS_PER_DISK*PRAV_RAW_TRACK_SIZE); + memcpy(&oric->pravetz.drv[1].image[0][0], &tmp[PRAV_TRACKS_PER_DISK*PRAV_RAW_TRACK_SIZE], PRAV_TRACKS_PER_DISK*PRAV_RAW_TRACK_SIZE); - sprintf(oric->wddisk.disk[i]->filename, "%s%cSNAPDISK%d.DSK", diskpath, PATHSEP, i); - - offs_ = getu32(blk); - oric->pravetz.drv[i].pimg = oric->wddisk.disk[i]; - if (offs_ == 0xffffffff) - oric->pravetz.drv[i].sector_ptr = NULL; - else - oric->pravetz.drv[i].sector_ptr = &oric->pravetz.drv[i].pimg->rawimage[offs_]; - - blk->id[0] = 0; // Don't find this one again free_block(blk); + + // Get the disk images + while((blk = load_block(oric, "PVD\x00", f, SDL_FALSE, -1, SDL_FALSE))) + { + // Get the drive associated with this disk image + i = getu16(blk); + if((i<0) || (i>1) || (oric->wddisk.disk[i] != NULL) || (!blk->datablock) || (blk->size != 10)) + { + msgbox(oric, MSGBOX_OK, "Snapshot load failed: Invalid file (PVD1)"); + free_blockheaders(); + fclose(f); + setmenutoggles(oric); + if(back2mon) setemumode(oric, NULL, EM_DEBUG); + return SDL_FALSE; + } + + // Allocate a diskimage header + oric->wddisk.disk[i] = (struct diskimage *)malloc(sizeof(struct diskimage)); + if(!oric->wddisk.disk[i]) + { + msgbox(oric, MSGBOX_OK, "Snapshot load failed: Out of memory (PVD2)"); + free_blockheaders(); + fclose(f); + setmenutoggles(oric); + if(back2mon) setemumode(oric, NULL, EM_DEBUG); + return SDL_FALSE; + } + memset(oric->wddisk.disk[i], 0, sizeof(struct diskimage)); + + // Allocate space for the disk image + oric->wddisk.disk[i]->rawimage = malloc(blk->datablock->size); + if(!oric->wddisk.disk[i]) + { + free(oric->wddisk.disk[i]); + oric->wddisk.disk[i] = NULL; + msgbox(oric, MSGBOX_OK, "Snapshot load failed: Out of memory (PVD3)"); + free_blockheaders(); + fclose(f); + setmenutoggles(oric); + if(back2mon) setemumode(oric, NULL, EM_DEBUG); + return SDL_FALSE; + } + + // Read in the disk image + if(!read_block(oric, blk->datablock, f, SDL_TRUE, oric->wddisk.disk[i]->rawimage)) + { + free(oric->wddisk.disk[i]->rawimage); + free(oric->wddisk.disk[i]); + oric->wddisk.disk[i] = NULL; + free_blockheaders(); + fclose(f); + setmenutoggles(oric); + if(back2mon) setemumode(oric, NULL, EM_DEBUG); + return SDL_FALSE; + } + + oric->wddisk.disk[i]->cachedtrack = -1; + oric->wddisk.disk[i]->cachedside = -1; + + // Fill out the disk image header + oric->wddisk.disk[i]->drivenum = i; + oric->wddisk.disk[i]->rawimagelen = getu32(blk); + + sprintf(oric->wddisk.disk[i]->filename, "%s%cSNAPDISK%d.DSK", diskpath, PATHSEP, i); + + offs_ = getu32(blk); + oric->pravetz.drv[i].pimg = oric->wddisk.disk[i]; + if(offs_ == 0xffffffff) + oric->pravetz.drv[i].sector_ptr = NULL; + else + oric->pravetz.drv[i].sector_ptr = &oric->pravetz.drv[i].pimg->rawimage[offs_]; + + blk->id[0] = 0; // Don't find this one again + free_block(blk); + } } - } } - if (do_wd17xx) + if(do_wd17xx) { Uint8 disks[4]; /* Get the wd17xx block */ blk = load_block(oric, "WDD\x00", f, SDL_TRUE, 38, SDL_FALSE); - if (!blk) + if(!blk) { free_blockheaders(); fclose(f); - setmenutoggles( oric ); - if (back2mon) setemumode(oric, NULL, EM_DEBUG); + setmenutoggles(oric); + if(back2mon) setemumode(oric, NULL, EM_DEBUG); return SDL_FALSE; } - oric->wddisk.r_status = getu8 (blk); - oric->wddisk.r_track = getu8 (blk); - oric->wddisk.r_sector = getu8 (blk); - oric->wddisk.r_data = getu8 (blk); - oric->wddisk.c_drive = getu8 (blk); - oric->wddisk.c_side = getu8 (blk); - oric->wddisk.c_track = getu8 (blk); - oric->wddisk.c_sector = getu8 (blk); - oric->wddisk.sectype = getu8 (blk); - oric->wddisk.last_step_in = getu8 (blk); + oric->wddisk.r_status = getu8(blk); + oric->wddisk.r_track = getu8(blk); + oric->wddisk.r_sector = getu8(blk); + oric->wddisk.r_data = getu8(blk); + oric->wddisk.c_drive = getu8(blk); + oric->wddisk.c_side = getu8(blk); + oric->wddisk.c_track = getu8(blk); + oric->wddisk.c_sector = getu8(blk); + oric->wddisk.sectype = getu8(blk); + oric->wddisk.last_step_in = getu8(blk); getdata(blk, disks, 4); oric->wddisk.currentop = getu32(blk); oric->wddisk.curroffs = getu32(blk); @@ -1301,59 +1319,59 @@ SDL_bool load_snapshot(struct machine *oric, char *filename) free_block(blk); // Get the disk images - while ((blk = load_block(oric, "DSK\x00", f, SDL_FALSE, -1, SDL_FALSE))) + while((blk = load_block(oric, "DSK\x00", f, SDL_FALSE, -1, SDL_FALSE))) { int track_to_cache=-1, side_to_cache=-1; // Get the drive associated with this disk image i = getu16(blk); - if ((i<0) || (i>3) || (oric->wddisk.disk[i] != NULL) || (!blk->datablock) || (blk->size != 16)) + if((i<0) || (i>3) || (oric->wddisk.disk[i] != NULL) || (!blk->datablock) || (blk->size != 16)) { msgbox(oric, MSGBOX_OK, "Snapshot load failed: Invalid file (20)"); free_blockheaders(); fclose(f); - setmenutoggles( oric ); - if (back2mon) setemumode(oric, NULL, EM_DEBUG); + setmenutoggles(oric); + if(back2mon) setemumode(oric, NULL, EM_DEBUG); return SDL_FALSE; } // Allocate a diskimage header oric->wddisk.disk[i] = (struct diskimage *)malloc(sizeof(struct diskimage)); - if (!oric->wddisk.disk[i]) + if(!oric->wddisk.disk[i]) { msgbox(oric, MSGBOX_OK, "Snapshot load failed: Out of memory (21)"); free_blockheaders(); fclose(f); - setmenutoggles( oric ); - if (back2mon) setemumode(oric, NULL, EM_DEBUG); + setmenutoggles(oric); + if(back2mon) setemumode(oric, NULL, EM_DEBUG); return SDL_FALSE; } memset(oric->wddisk.disk[i], 0, sizeof(struct diskimage)); // Allocate space for the disk image oric->wddisk.disk[i]->rawimage = malloc(blk->datablock->size); - if (!oric->wddisk.disk[i]) + if(!oric->wddisk.disk[i]) { free(oric->wddisk.disk[i]); oric->wddisk.disk[i] = NULL; msgbox(oric, MSGBOX_OK, "Snapshot load failed: Out of memory (22)"); free_blockheaders(); fclose(f); - setmenutoggles( oric ); - if (back2mon) setemumode(oric, NULL, EM_DEBUG); + setmenutoggles(oric); + if(back2mon) setemumode(oric, NULL, EM_DEBUG); return SDL_FALSE; } // Read in the disk image - if (!read_block(oric, blk->datablock, f, SDL_TRUE, oric->wddisk.disk[i]->rawimage)) + if(!read_block(oric, blk->datablock, f, SDL_TRUE, oric->wddisk.disk[i]->rawimage)) { free(oric->wddisk.disk[i]->rawimage); free(oric->wddisk.disk[i]); oric->wddisk.disk[i] = NULL; free_blockheaders(); fclose(f); - setmenutoggles( oric ); - if (back2mon) setemumode(oric, NULL, EM_DEBUG); + setmenutoggles(oric); + if(back2mon) setemumode(oric, NULL, EM_DEBUG); return SDL_FALSE; } @@ -1369,10 +1387,10 @@ SDL_bool load_snapshot(struct machine *oric, char *filename) side_to_cache = gets16(blk); oric->wddisk.disk[i]->rawimagelen = getu32(blk); - if ((track_to_cache != -1) && (side_to_cache != -1)) + if((track_to_cache != -1) && (side_to_cache != -1)) diskimage_cachetrack(oric->wddisk.disk[i], track_to_cache, side_to_cache); - if (oric->wddisk.c_drive == i) + if(oric->wddisk.c_drive == i) oric->wddisk.currsector = wd17xx_find_sector(&oric->wddisk, oric->wddisk.r_sector); sprintf(oric->wddisk.disk[i]->filename, "%s%cSNAPDISK%d.DSK", diskpath, PATHSEP, i); @@ -1382,20 +1400,20 @@ SDL_bool load_snapshot(struct machine *oric, char *filename) } } - if (oric->type == MACH_TELESTRAT) + if(oric->type == MACH_TELESTRAT) { /* Get the bank information block */ blk = load_block(oric, "BNK\x00", f, SDL_TRUE, 9, SDL_FALSE); - if (!blk) + if(!blk) { free_blockheaders(); fclose(f); - setmenutoggles( oric ); - if (back2mon) setemumode(oric, NULL, EM_DEBUG); + setmenutoggles(oric); + if(back2mon) setemumode(oric, NULL, EM_DEBUG); return SDL_FALSE; } - for (i=0; i<8; i++) + for(i=0; i<8; i++) oric->tele_bank[i].type = getu8(blk); oric->tele_currbank = getu8(blk); @@ -1404,12 +1422,12 @@ SDL_bool load_snapshot(struct machine *oric, char *filename) /* Get the ACIA block */ blk = load_block(oric, "ACI\x00", f, SDL_TRUE, ACIA_LAST, SDL_FALSE); - if (!blk) + if(!blk) { free_blockheaders(); fclose(f); - setmenutoggles( oric ); - if (back2mon) setemumode(oric, NULL, EM_DEBUG); + setmenutoggles(oric); + if(back2mon) setemumode(oric, NULL, EM_DEBUG); return SDL_FALSE; } @@ -1420,12 +1438,12 @@ SDL_bool load_snapshot(struct machine *oric, char *filename) /* Get the AUX ACIA block */ blk = load_block(oric, "AUX\x00", f, SDL_TRUE, ACIA_LAST, SDL_FALSE); - if (!blk) + if(!blk) { free_blockheaders(); fclose(f); - setmenutoggles( oric ); - if (back2mon) setemumode(oric, NULL, EM_DEBUG); + setmenutoggles(oric); + if(back2mon) setemumode(oric, NULL, EM_DEBUG); return SDL_FALSE; } @@ -1434,74 +1452,75 @@ SDL_bool load_snapshot(struct machine *oric, char *filename) /* Get the VIA block */ blk = load_block(oric, "TVA\x00", f, SDL_TRUE, 39, SDL_FALSE); - if (!blk) + if(!blk) { free_blockheaders(); fclose(f); - setmenutoggles( oric ); - if (back2mon) setemumode(oric, NULL, EM_DEBUG); + setmenutoggles(oric); + if(back2mon) setemumode(oric, NULL, EM_DEBUG); return SDL_FALSE; } - oric->tele_via.ifr = getu8 (blk); - oric->tele_via.irb = getu8 (blk); - oric->tele_via.orb = getu8 (blk); - oric->tele_via.irbl = getu8 (blk); - oric->tele_via.ira = getu8 (blk); - oric->tele_via.ora = getu8 (blk); - oric->tele_via.iral = getu8 (blk); - oric->tele_via.ddra = getu8 (blk); - oric->tele_via.ddrb = getu8 (blk); - oric->tele_via.t1l_l = getu8 (blk); - oric->tele_via.t1l_h = getu8 (blk); + oric->tele_via.ifr = getu8(blk); + oric->tele_via.irb = getu8(blk); + oric->tele_via.orb = getu8(blk); + oric->tele_via.irbl = getu8(blk); + oric->tele_via.ira = getu8(blk); + oric->tele_via.ora = getu8(blk); + oric->tele_via.iral = getu8(blk); + oric->tele_via.ddra = getu8(blk); + oric->tele_via.ddrb = getu8(blk); + oric->tele_via.t1l_l = getu8(blk); + oric->tele_via.t1l_h = getu8(blk); oric->tele_via.t1c = getu16(blk); - oric->tele_via.t2l_l = getu8 (blk); - oric->tele_via.t2l_h = getu8 (blk); + oric->tele_via.t2l_l = getu8(blk); + oric->tele_via.t2l_h = getu8(blk); oric->tele_via.t2c = getu16(blk); - oric->tele_via.sr = getu8 (blk); - oric->tele_via.acr = getu8 (blk); - oric->tele_via.pcr = getu8 (blk); - oric->tele_via.ier = getu8 (blk); - oric->tele_via.ca1 = getu8 (blk); - oric->tele_via.ca2 = getu8 (blk); - oric->tele_via.cb1 = getu8 (blk); - oric->tele_via.cb2 = getu8 (blk); - oric->tele_via.srcount = getu8 (blk); - oric->tele_via.t1reload = getu8 (blk); - oric->tele_via.t2reload = getu8 (blk); + oric->tele_via.sr = getu8(blk); + oric->tele_via.acr = getu8(blk); + oric->tele_via.pcr = getu8(blk); + oric->tele_via.ier = getu8(blk); + oric->tele_via.ca1 = getu8(blk); + oric->tele_via.ca2 = getu8(blk); + oric->tele_via.cb1 = getu8(blk); + oric->tele_via.cb2 = getu8(blk); + oric->tele_via.srcount = getu8(blk); + oric->tele_via.t1reload = getu8(blk); + oric->tele_via.t2reload = getu8(blk); oric->tele_via.srtime = getu16(blk); - oric->tele_via.t1run = getu8 (blk); - oric->tele_via.t2run = getu8 (blk); - oric->tele_via.ca2pulse = getu8 (blk); - oric->tele_via.cb2pulse = getu8 (blk); - oric->tele_via.srtrigger= getu8 (blk); + oric->tele_via.t1run = getu8(blk); + oric->tele_via.t2run = getu8(blk); + oric->tele_via.ca2pulse = getu8(blk); + oric->tele_via.cb2pulse = getu8(blk); + oric->tele_via.srtrigger= getu8(blk); oric->tele_via.irqbit = getu32(blk); // Finished with this one free_block(blk); } +#ifdef WWW_MONITOR /* Get the rom symbols block */ - if ((blk = load_block(oric, "SYR\x00", f, SDL_FALSE, -1, SDL_FALSE))) + if((blk = load_block(oric, "SYR\x00", f, SDL_FALSE, -1, SDL_FALSE))) { mon_symsfromsnapshot(&oric->romsyms, blk->buf, blk->size); free_block(blk); } /* Get the user symbols block */ - if ((blk = load_block(oric, "SYU\x00", f, SDL_FALSE, -1, SDL_FALSE))) + if((blk = load_block(oric, "SYU\x00", f, SDL_FALSE, -1, SDL_FALSE))) { mon_symsfromsnapshot(&oric->usersyms, blk->buf, blk->size); free_block(blk); } - if (oric->type == MACH_TELESTRAT) + if(oric->type == MACH_TELESTRAT) { - for (i=0; i<8; i++) + for(i=0; i<8; i++) { char name[8]; sprintf(name, "SY%d%c", i, 0); - if ((blk = load_block(oric, name, f, SDL_FALSE, -1, SDL_FALSE))) + if((blk = load_block(oric, name, f, SDL_FALSE, -1, SDL_FALSE))) { mon_symsfromsnapshot(&oric->tele_banksyms[i], blk->buf, blk->size); free_block(blk); @@ -1510,32 +1529,33 @@ SDL_bool load_snapshot(struct machine *oric, char *filename) } /* ... and finally, breakpoints! */ - if ((blk = load_block(oric, "BKP\x00", f, SDL_FALSE, -1, SDL_FALSE))) + if((blk = load_block(oric, "BKP\x00", f, SDL_FALSE, -1, SDL_FALSE))) { cpu->anybp = SDL_FALSE; cpu->anymbp = SDL_FALSE; - for (i=0; i<16; i++) + for(i=0; i<16; i++) { cpu->breakpoints[i] = gets32(blk); - if (cpu->breakpoints[i] != -1) cpu->anybp = SDL_TRUE; + if(cpu->breakpoints[i] != -1) cpu->anybp = SDL_TRUE; } - for (i=0; i<16; i++) + for(i=0; i<16; i++) { cpu->membreakpoints[i].flags = getu8(blk); cpu->membreakpoints[i].lastval = getu8(blk); cpu->membreakpoints[i].addr = getu16(blk); - if (cpu->membreakpoints[i].flags) cpu->anymbp = SDL_TRUE; + if(cpu->membreakpoints[i].flags) cpu->anymbp = SDL_TRUE; } free_block(blk); } +#endif free_blockheaders(); fclose(f); - setmenutoggles( oric ); - if (back2mon) setemumode(oric, NULL, EM_DEBUG); + setmenutoggles(oric); + if(back2mon) setemumode(oric, NULL, EM_DEBUG); return SDL_TRUE; } diff --git a/snapshot.h b/snapshot.h index de71c9ab..c59b3cf3 100644 --- a/snapshot.h +++ b/snapshot.h @@ -20,6 +20,6 @@ ** */ -SDL_bool save_snapshot(struct machine *oric, char *filename); -SDL_bool load_snapshot(struct machine *oric, char *filename); +SDL_bool save_snapshot(struct machine *oric, char* filename); +SDL_bool load_snapshot(struct machine *oric, char* filename); diff --git a/system.h b/system.h index 5d9c661c..215d4378 100644 --- a/system.h +++ b/system.h @@ -51,16 +51,24 @@ #define ROMPREFIX "roms\\" #define IMAGEPREFIX "images\\" -#else +#elif defined(WWW) #define PATHSEP '/' #define PATHSEPSTR "/" -#define FILEPREFIX -#define ROMPREFIX "roms/" -#define IMAGEPREFIX "images/" +#define FILEPREFIX "assets/" +#define ROMPREFIX "assets/roms/" +#define IMAGEPREFIX "assets/images/" + +#else +#define PATHSEP '/' +#define PATHSEPSTR "/" +#define ROMPREFIX "roms"PATHSEPSTR +#define IMAGEPREFIX "images"PATHSEPSTR #endif +const char* get_fileprefix(); + /* SDL related stuff */ #include "system_sdl.h" diff --git a/system_sdl.c b/system_sdl.c index 43306ebd..a6dc4394 100644 --- a/system_sdl.c +++ b/system_sdl.c @@ -67,7 +67,12 @@ #endif #if SDL_MAJOR_VERSION == 1 -/* NOP */ +static SDL_Surface* g_icon = NULL; + +static void FreeResources(void) +{ + // nope +} #else static SDL_bool g_fullscreen = SDL_FALSE; static SDL_GLContext g_glcontext = NULL; @@ -92,7 +97,7 @@ static void FreeResources(void) g_glcontext = NULL; } - if (g_texture) + if(g_texture) { SDL_DestroyTexture(g_texture); g_texture = NULL; @@ -120,16 +125,42 @@ static void FreeResources(void) } #endif +int SDL_COMPAT_Init(Uint32 flags) +{ + int rc; + +#ifdef DEBUG_SDLINFO + SDL_version ver; + SDL_VERSION(&ver); + fprintf(stderr,"SDL version %u.%u.%u", ver.major, ver.minor, ver.patch); + +#if SDL_MAJOR_VERSION == 1 + // SDL_GetVersion not defined in SDL-1.x +#else + SDL_GetVersion(&ver); + fprintf(stderr,"/%u.%u.%u", ver.major, ver.minor, ver.patch); +#endif + + fprintf(stderr,"\n"); +#endif + + rc = SDL_Init(flags); + if(rc < 0) + error_printf("SDL init failed: %s", SDL_GetError()); + + return rc; +} + #if SDL_MAJOR_VERSION == 1 int SDL_COMPAT_GetWMInfo(SDL_SysWMinfo *info) { // NOTE: see above for SDL_GetWMInfo in macros // #if defined(__MORPHOS__)||defined(__APPLE__) - #if defined(__MORPHOS__) +#if defined(__MORPHOS__) return 0; - #else +#else return SDL_GetWMInfo(info); - #endif +#endif } #else int SDL_COMPAT_GetWMInfo(SDL_SysWMinfo *info) @@ -138,17 +169,7 @@ int SDL_COMPAT_GetWMInfo(SDL_SysWMinfo *info) } #endif - -#if SDL_MAJOR_VERSION == 1 -void SDL_COMPAT_WM_SetIcon(SDL_Surface *icon, Uint8 *mask) -{ - SDL_WM_SetIcon(icon, mask); -} -void SDL_COMPAT_WM_SetCaption(const char *title, const char *icon) -{ - SDL_WM_SetCaption(title, icon); -} -#else +// NOTE: same for both SDL versions void SDL_COMPAT_WM_SetIcon(SDL_Surface *icon, Uint8 *mask) { if(g_icon) @@ -157,11 +178,16 @@ void SDL_COMPAT_WM_SetIcon(SDL_Surface *icon, Uint8 *mask) g_icon = NULL; } if(icon) - { g_icon = icon; - } } -void SDL_COMPAT_WM_SetCaption(const char *title, const char *icon) + +#if SDL_MAJOR_VERSION == 1 +void SDL_COMPAT_WM_SetCaption(const char* title, const char* icon) +{ + SDL_WM_SetCaption(title, icon); +} +#else +void SDL_COMPAT_WM_SetCaption(const char* title, const char* icon) { if(g_window) SDL_SetWindowTitle(g_window, title); @@ -177,7 +203,7 @@ SDL_bool SDL_COMPAT_IsAppActive(SDL_Event* event) } SDL_bool SDL_COMPAT_IsAppFocused(SDL_Event* event) { - switch( event->active.type ) + switch(event->active.type) { case SDL_APPINPUTFOCUS: case SDL_APPACTIVE: @@ -189,20 +215,20 @@ SDL_bool SDL_COMPAT_IsAppFocused(SDL_Event* event) #else SDL_bool SDL_COMPAT_IsAppActive(SDL_Event* event) { - /* NOTE: not needed wit SDL 2.0 + /* NOTE: not needed with SDL 2.0 * return (event->window.event == SDL_WINDOWEVENT_FOCUS_GAINED)? SDL_TRUE : SDL_FALSE; */ return SDL_FALSE; } SDL_bool SDL_COMPAT_IsAppFocused(SDL_Event* event) { - /* NOTE: not needed wit SDL 2.0 + /* NOTE: not needed with SDL 2.0 * switch( event->window.event ) * { * case SDL_WINDOWEVENT_FOCUS_GAINED: * case SDL_WINDOWEVENT_ENTER: * return SDL_TRUE; * break; -} */ + } */ return SDL_FALSE; } #endif @@ -234,74 +260,150 @@ int SDL_COMPAT_EnableUNICODE(int enable) } #endif +// NOTE: uncomment to have key codes in monitor mode +// dumped to con and to 'key_dump.txt' file +// #define DEBUG_KEY_DUMP +#ifdef DEBUG_KEY_DUMP +static FILE* fkd = 0; +static const char* skd = "key_dump.txt"; +#define key_dump(x...) \ +{ printf(x); if(!fkd) fkd=fopen(skd, "a"); \ + if(fkd) fprintf(fkd,x); } +#endif + #if SDL_MAJOR_VERSION == 1 -SDL_COMPAT_KEY SDL_COMPAT_GetKeysymUnicode(SDL_KEYSYM keysym) -{ +SDL_COMPAT_KEY SDL_COMPAT_GetKeysymUnicode(SDL_COMPAT_KEYSYM keysym) +{ + // FIXME +#ifdef DEBUG_KEY_DUMP + char c = 0x7f & keysym.sym; + c = (c < ' ')? ' ' : c; + key_dump("SDL : GetKeysymUnicode: " + "c=|%c| scancode=$%.4X, sym=$%.4X, mod=$%.4X, unicode=$%.4X -> unicode=$%.4X\n", + c, keysym.scancode, keysym.sym, keysym.mod, keysym.unicode, keysym.unicode); +#endif + // FIXME + return keysym.unicode; } -SDL_COMPAT_KEY SDL_COMPAT_TranslateUnicode(SDL_KEYSYM keysym) +SDL_COMPAT_KEY SDL_COMPAT_TranslateUnicode(SDL_COMPAT_KEYSYM keysym) { + // FIXME +#ifdef DEBUG_KEY_DUMP + char c = 0x7f & keysym.sym; + c = (c < ' ')? ' ' : c; + key_dump("SDL : TranslateUnicode: " + "c=|%c| scancode=$%.4X, sym=$%.4X, mod=$%.4X, unicode=$%.4X -> unicode=$%.4X\n", + c, keysym.scancode, keysym.sym, keysym.mod, keysym.unicode, keysym.unicode); +#endif + // FIXME return keysym.unicode; } #else -SDL_COMPAT_KEY SDL_COMPAT_TranslateUnicode(SDL_KEYSYM keysym) +SDL_COMPAT_KEY SDL_COMPAT_GetKeysymUnicode(SDL_COMPAT_KEYSYM keysym) +{ + // FIXME +#ifdef DEBUG_KEY_DUMP + char c = 0x7f & keysym.sym; + c = (c < ' ')? ' ' : c; + key_dump("SDL2: GetKeysymUnicode: " + "c=|%c| scancode=$%.4X, sym=$%.4X, mod=$%.4X, unicode=----- -> keysym.sym=$%.4X\n", + c, keysym.scancode, keysym.sym, keysym.mod, keysym.sym); +#endif + // FIXME + return keysym.sym; +} +SDL_COMPAT_KEY SDL_COMPAT_TranslateUnicode(SDL_COMPAT_KEYSYM keysym) { + // FIXME + SDL_COMPAT_KEY sym_out = keysym.sym; +#ifdef DEBUG_KEY_DUMP + SDL_COMPAT_KEY sym_in = keysym.sym; +#endif + // FIXME if(keysym.mod & KMOD_SHIFT) { switch(keysym.sym) { - case '0': - return ')'; - case '1': - return '!'; - case '2': - return '@'; - case '3': - return '#'; - case '4': - return '$'; - case '5': - return '%'; - case '6': - return '^'; - case '7': - return '&'; - case '8': - return '*'; - case '9': - return '('; - case ';': - return ':'; - case '\'': - return '"'; - case '\\': - return '|'; - case ',': - return '<'; - case '.': - return '>'; - case '/': - return '?'; - case '`': - return '~'; - case '-': - return '_'; - case '=': - return '+'; - case '[': - return '{'; - case ']': - return '}'; + case '0' : + sym_out = ')'; + break; + case '1' : + sym_out = '!'; + break; + case '2' : + sym_out = '@'; + break; + case '3' : + sym_out = '#'; + break; + case '4' : + sym_out = '$'; + break; + case '5' : + sym_out = '%'; + break; + case '6' : + sym_out = '^'; + break; + case '7' : + sym_out = '&'; + break; + case '8' : + sym_out = '*'; + break; + case '9' : + sym_out = '('; + break; + case ';' : + sym_out = ':'; + break; + case '\'' : + sym_out = '"'; + break; + case '\\' : + sym_out = '|'; + break; + case ',' : + sym_out = '<'; + break; + case '.' : + sym_out = '>'; + break; + case '/' : + sym_out = '?'; + break; + case '`' : + sym_out = '~'; + break; + case '-' : + sym_out = '_'; + break; + case '=' : + sym_out = '+'; + break; + case '[' : + sym_out = '{'; + break; + case ']' : + sym_out = '}'; + break; default: - keysym.sym = toupper(keysym.sym); + sym_out = keysym.sym = toupper(keysym.sym); break; } } - return keysym.sym; -} -SDL_COMPAT_KEY SDL_COMPAT_GetKeysymUnicode(SDL_KEYSYM keysym) -{ - return keysym.sym; + // FIXME +#ifdef DEBUG_KEY_DUMP + char c = 0x7f & keysym.sym; + c = (c < ' ')? ' ' : c; + key_dump("SDL2: TranslateUnicode: " + "c=|%c| scancode=$%.4X, sym=$%.4X, mod=$%.4X, unicode=----- -> keysym.sym=$%.4X\n", + c, keysym.scancode, sym_in, keysym.mod, sym_out); +#endif + // FIXME + + return sym_out; } #endif @@ -366,6 +468,12 @@ int SDL_COMPAT_WM_ToggleFullScreen(SDL_Surface *surface) #if SDL_MAJOR_VERSION == 1 SDL_Surface* SDL_COMPAT_SetVideoMode(int width, int height, int bitsperpixel, Uint32 flags) { + FreeResources(); + + // NOTE: SDL_WM_SetIcon function must be called before the first call to SDL_SetVideoMode. + if(g_icon) + SDL_WM_SetIcon(g_icon, NULL); + return SDL_SetVideoMode(width, height, bitsperpixel, flags); } #else @@ -377,31 +485,40 @@ SDL_Surface* SDL_COMPAT_SetVideoMode(int width, int height, int bitsperpixel, Ui FreeResources(); - // When leaving fullscreen mode, X and Y coordinates should be recentered relative to the display. - if (flags ^ SDL_WINDOW_FULLSCREEN) { - g_lastx = SDL_WINDOWPOS_CENTERED; - g_lasty = SDL_WINDOWPOS_CENTERED; + // When leaving fullscreen mode, X and Y coordinates + // should be recentered relative to the display. + if(!(flags & SDL_WINDOW_FULLSCREEN)) + { + g_lastx = SDL_WINDOWPOS_CENTERED; + g_lasty = SDL_WINDOWPOS_CENTERED; } +#ifndef __ANDROID__ g_window = SDL_CreateWindow("oricutron", g_lastx, g_lasty, g_width, g_height, flags); - if (g_icon) - { +#else + g_window = SDL_CreateWindow("oricutron", SDL_WINDOWPOS_UNDEFINED,SDL_WINDOWPOS_UNDEFINED, + 0, 0, SDL_WINDOW_FULLSCREEN_DESKTOP); +#endif + if(g_icon) SDL_SetWindowIcon(g_window, g_icon); - // ...and the surface containing the icon pixel data is no longer required. - SDL_FreeSurface(g_icon); - } if(flags & SDL_WINDOW_OPENGL) { g_screen = SDL_GetWindowSurface(g_window); g_glcontext = SDL_GL_CreateContext(g_window); + + SDL_GL_SetSwapInterval(1); } else { g_screen = SDL_CreateRGBSurface(0, g_width, g_height, g_bpp, RMASK, GMASK, BMASK, AMASK); g_renderer = SDL_CreateRenderer(g_window, -1, 0); +#ifdef __ANDROID__ + SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "best");//"linear"); + SDL_RenderSetLogicalSize(g_renderer, g_width, g_height); +#endif g_texture = SDL_CreateTexture(g_renderer, SDL_PIXELFORMAT_ABGR8888, SDL_TEXTUREACCESS_STREAMING, @@ -437,18 +554,18 @@ void SDL_COMPAT_SetEventFilter(SDL_EventFilter filter) } #endif -#if SDL_MAJOR_VERSION == 1 -void SDL_COMPAT_Quit(void) -{ - SDL_Quit(); -} -#else -void SDL_COMPAT_Quit(void) +// NOTE: same for both SDL versions +void SDL_COMPAT_Quit(SDL_bool freeall) { FreeResources(); + if(g_icon && freeall) + { + // ...and the surface containing the icon pixel data is no longer required. + SDL_FreeSurface(g_icon); + g_icon = NULL; + } SDL_Quit(); } -#endif #ifdef __OPENGL_AVAILABLE__ #if SDL_MAJOR_VERSION == 1 @@ -469,10 +586,10 @@ SDL_Surface * flipVert(SDL_Surface* sfc) { int line; SDL_Surface* result = SDL_CreateRGBSurface(sfc->flags, sfc->w, sfc->h, - sfc->format->BytesPerPixel * 8, sfc->format->Rmask, sfc->format->Gmask, - sfc->format->Bmask, sfc->format->Amask); + sfc->format->BytesPerPixel * 8, sfc->format->Rmask, sfc->format->Gmask, + sfc->format->Bmask, sfc->format->Amask); - if (result) + if(result) { Uint8* pixels = (Uint8*) sfc->pixels; Uint8* rpixels = (Uint8*) result->pixels; @@ -490,7 +607,7 @@ SDL_Surface * flipVert(SDL_Surface* sfc) return result; } #if SDL_MAJOR_VERSION == 1 -void SDL_COMPAT_TakeScreenshot(char *fname) +void SDL_COMPAT_TakeScreenshot(char* fname) { SDL_Surface *g_screen = SDL_GetVideoSurface(); @@ -519,7 +636,7 @@ void SDL_COMPAT_TakeScreenshot(char *fname) SDL_SaveBMP(g_screen, fname); } #else -void SDL_COMPAT_TakeScreenshot(char *fname) +void SDL_COMPAT_TakeScreenshot(char* fname) { // 24 Bits // SDL_Surface *surf = SDL_CreateRGBSurface(SDL_SWSURFACE, g_width, g_height, 24, RMASK, BMASK, GMASK, 0); @@ -527,7 +644,7 @@ void SDL_COMPAT_TakeScreenshot(char *fname) // 32 Bits SDL_Surface *surf = SDL_CreateRGBSurface(SDL_SWSURFACE, g_width, g_height, g_bpp, RMASK, GMASK, BMASK, AMASK); - if (surf == NULL) + if(surf == NULL) return; // 24 Bits @@ -545,14 +662,37 @@ void SDL_COMPAT_TakeScreenshot(char *fname) #endif #else #if SDL_MAJOR_VERSION == 1 -void SDL_COMPAT_TakeScreenshot(char *fname) +void SDL_COMPAT_TakeScreenshot(char* fname) { SDL_SaveBMP(SDL_GetVideoSurface(), fname); } #else -void SDL_COMPAT_TakeScreenshot(char *fname) +void SDL_COMPAT_TakeScreenshot(char* fname) { SDL_SaveBMP(g_screen, fname); } #endif #endif + +#if SDL_MAJOR_VERSION == 1 +const char* SDL_COMPAT_JoystickName(SDL_Joystick *joystick) +{ + return NULL; +} +#else +const char* SDL_COMPAT_JoystickName(SDL_Joystick *joystick) +{ + return SDL_JoystickName(joystick); +} +#endif + +// This is an ugly hack for OSX will be removed +#ifdef __APPLE__ +int32_t __isPlatformVersionAtLeast(int32_t Major, int32_t Minor, int32_t Subminor) +{ + (void) Major; + (void) Minor; + (void) Subminor; + return SDL_TRUE; +} +#endif diff --git a/system_sdl.h b/system_sdl.h index ff507d7c..241291d0 100644 --- a/system_sdl.h +++ b/system_sdl.h @@ -72,10 +72,10 @@ #define _MAKE_BE16(X) #endif -/* SDL compatability definitions and macroses */ +/* SDL compatibility definitions and macros */ #if SDL_MAJOR_VERSION == 1 typedef Uint16 SDL_COMPAT_KEY; /* Used in 8912.c */ -typedef SDL_keysym SDL_KEYSYM; +typedef SDL_keysym SDL_COMPAT_KEYSYM; typedef SDL_VideoInfo SDL_COMPAT_VideoInfo; #define SDL_COMPAT_HWSURFACE SDL_HWSURFACE @@ -93,7 +93,7 @@ typedef SDL_VideoInfo SDL_COMPAT_VideoInfo; #else typedef Uint32 SDL_COMPAT_KEY; /* Used in 8912.c */ -typedef SDL_Keysym SDL_KEYSYM; +typedef SDL_Keysym SDL_COMPAT_KEYSYM; typedef SDL_RendererInfo SDL_COMPAT_VideoInfo; #define SDL_COMPAT_HWSURFACE 0 /* FIXME */ @@ -126,32 +126,43 @@ typedef SDL_RendererInfo SDL_COMPAT_VideoInfo; #define SDLK_PRINT SDLK_PRINTSCREEN #endif -/* SDL compatability protos */ +/* SDL compatibility protos */ #ifdef WANT_WMINFO int SDL_COMPAT_GetWMInfo(SDL_SysWMinfo *info); #endif +int SDL_COMPAT_Init(Uint32 flags); void SDL_COMPAT_WM_SetIcon(SDL_Surface *icon, Uint8 *mask); -void SDL_COMPAT_WM_SetCaption(const char *title, const char *icon); +void SDL_COMPAT_WM_SetCaption(const char* title, const char* icon); SDL_bool SDL_COMPAT_IsAppActive(SDL_Event* event); SDL_bool SDL_COMPAT_IsAppFocused(SDL_Event* event); int SDL_COMPAT_EnableKeyRepeat(int delay, int interval); int SDL_COMPAT_EnableUNICODE(int enable); -SDL_COMPAT_KEY SDL_COMPAT_GetKeysymUnicode(SDL_KEYSYM keysym); -SDL_COMPAT_KEY SDL_COMPAT_TranslateUnicode(SDL_KEYSYM keysym); +SDL_COMPAT_KEY SDL_COMPAT_GetKeysymUnicode(SDL_COMPAT_KEYSYM keysym); +SDL_COMPAT_KEY SDL_COMPAT_TranslateUnicode(SDL_COMPAT_KEYSYM keysym); int SDL_COMPAT_Flip(SDL_Surface* screen); int SDL_COMPAT_GetBitsPerPixel(void); int SDL_COMPAT_WM_ToggleFullScreen(SDL_Surface *surface); SDL_Surface* SDL_COMPAT_SetVideoMode(int width, int height, int bitsperpixel, Uint32 flags); int SDL_COMPAT_SetPalette(SDL_Surface *surface, int flags, SDL_Color *colors, int firstcolor, int ncolors); void SDL_COMPAT_SetEventFilter(SDL_EventFilter filter); -void SDL_COMPAT_Quit(void); -void SDL_COMPAT_TakeScreenshot(char *fname); +void SDL_COMPAT_Quit(SDL_bool freeall); +void SDL_COMPAT_TakeScreenshot(char* fname); +const char* SDL_COMPAT_JoystickName(SDL_Joystick *joystick); #ifdef __OPENGL_AVAILABLE__ void SDL_COMPAT_GL_SwapBuffers(void); #endif -void error_printf( char *fmt, ... ); + +#ifdef __ANDROID__ +#include +#define LOG_TAG "Oricutron" +#define debug_printf(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__) +#define error_printf(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__) +#else +#define debug_printf(...) fprintf(stdout,__VA_ARGS__) +void error_printf(char* fmt, ...); +#endif #endif /* ORICUTRON_SYSTEM_SDL_H */ diff --git a/tape.c b/tape.c index 76db3097..032d5d2f 100644 --- a/tape.c +++ b/tape.c @@ -36,6 +36,10 @@ #include "tape.h" #include "msgbox.h" +#ifdef WWW +#include +#endif + extern char tapefile[], tapepath[]; extern SDL_bool refreshtape; char tmptapename[4096]; @@ -43,30 +47,39 @@ extern char filetmp[]; // Pop-up the name of the currently inserted tape // image file (or an eject symbol if no tape image). -void tape_popup( struct machine *oric ) +void tape_popup(struct machine *oric) { char tmp[40]; - if( !oric->tapename[0] ) + if(!oric->tapename[0]) { // Eject symbol - do_popup( oric, "\x0f\x10\x13" ); + do_popup(oric, "\x0f\x10\x13"); return; } // Tape image name - sprintf( tmp, "\x0f\x10""%c %-16s", oric->tapemotor ? 18 : 17, oric->tapename ); - do_popup( oric, tmp ); + sprintf(tmp, "\x0f\x10""%c %-16s", oric->tapemotor ? 18 : 17, oric->tapename); + do_popup(oric, tmp); } -void toggletapecap( struct machine *oric, struct osdmenuitem *mitem, int dummy ) +void toggletapecap(struct machine *oric, struct osdmenuitem *mitem, int dummy) { char ortheader[] = { 'O', 'R', 'T', 0 }; // Oric Raw Tape, Version 0 /* If capturing, stop */ - if( oric->tapecap ) + if(oric->tapecap) { - fclose( oric->tapecap ); + fclose(oric->tapecap); +#ifdef WWW + // sync from memory state to persisted + EM_ASM( + FS.syncfs(function(err) + { + assert(!err); + }); + ); +#endif oric->tapecap = NULL; mitem->name = "Save tape output..."; refreshtape = SDL_TRUE; @@ -74,36 +87,36 @@ void toggletapecap( struct machine *oric, struct osdmenuitem *mitem, int dummy ) } /* Otherwise, prompt for the file to capture */ - if( !filerequester( oric, "Capture tape output", tapepath, tmptapename, FR_TAPESAVEORT ) ) + if(!filerequester(oric, "Capture tape output", tapepath, tmptapename, FR_TAPESAVEORT)) { // Never mind return; } - if( tmptapename[0] == 0 ) return; + if(tmptapename[0] == 0) return; /* If it ends in ".tap", we need to change it to ".ort", because we're capturing real signals here folks! */ - if( (strlen(tmptapename)>3) && (strcasecmp(&tmptapename[strlen(tmptapename)-4], ".tap")==0) ) + if((strlen(tmptapename)>3) && (strcasecmp(&tmptapename[strlen(tmptapename)-4], ".tap")==0)) tmptapename[strlen(tmptapename)-4] = 0; /* Add .ort extension, if necessary */ - if( (strlen(tmptapename)<4) || (strcasecmp(&tmptapename[strlen(tmptapename)-4], ".ort")!=0) ) + if((strlen(tmptapename)<4) || (strcasecmp(&tmptapename[strlen(tmptapename)-4], ".ort")!=0)) strncat(tmptapename, ".ort", 4095); tmptapename[4095] = 0; - joinpath( tapepath, tmptapename ); + joinpath(tapepath, tmptapename); /* Open the file */ - oric->tapecap = fopen( filetmp, "wb" ); - if( !oric->tapecap ) + oric->tapecap = fopen(filetmp, "wb"); + if(!oric->tapecap) { /* Oh well */ - msgbox( oric, MSGBOX_OK, "Unable to create file" ); + msgbox(oric, MSGBOX_OK, "Unable to create file"); return; } /* Write header */ - fwrite( ortheader, 4, 1, oric->tapecap); + fwrite(ortheader, 4, 1, oric->tapecap); /* Counter reset */ oric->tapecapcount = -1; @@ -123,31 +136,31 @@ void toggletapecap( struct machine *oric, struct osdmenuitem *mitem, int dummy ) ** Only call it when you think you're at a tape leader since it doesn't do many ** sanity checks. */ -void tape_setup_header( struct machine *oric ) +void tape_setup_header(struct machine *oric) { int i; oric->tapedupbytes = 0; oric->tapehdrend = 0; - if( oric->tapebuf[oric->tapeoffs] != 0x16 ) + if(oric->tapebuf[oric->tapeoffs] != 0x16) return; /* Does it look like a header? */ - for( i=0; oric->tapebuf[oric->tapeoffs+i]==0x16; i++ ) + for(i=0; oric->tapebuf[oric->tapeoffs+i]==0x16; i++) { - if( (oric->tapeoffs+i) >= oric->tapelen ) + if((oric->tapeoffs+i) >= oric->tapelen) return; } - if( ( i < 3 ) || ( oric->tapebuf[oric->tapeoffs+i] != 0x24 ) ) + if((i < 3) || (oric->tapebuf[oric->tapeoffs+i] != 0x24)) return; i++; - if( (oric->tapeoffs+i+9) >= oric->tapelen ) + if((oric->tapeoffs+i+9) >= oric->tapelen) return; i+=9; - while( oric->tapebuf[oric->tapeoffs+i] != 0 ) + while(oric->tapebuf[oric->tapeoffs+i] != 0) { - if( (oric->tapeoffs+i) >= oric->tapelen ) + if((oric->tapeoffs+i) >= oric->tapelen) return; i++; } @@ -158,46 +171,46 @@ void tape_setup_header( struct machine *oric ) } -void tape_orbchange( struct via *via ) +void tape_orbchange(struct via *via) { struct machine *oric = via->oric; unsigned char buffer[4], tapebit, bufwrite; unsigned int count; /* Capturing tape output? */ - if( !oric->tapecap ) return; + if(!oric->tapecap) return; /* Saving a tap section? */ - if( oric->tapecap == oric->tsavf ) return; + if(oric->tapecap == oric->tsavf) return; tapebit = (via->orb & via->ddrb) >> 7; - if( tapebit == oric->tapecaplastbit ) return; + if(tapebit == oric->tapecaplastbit) return; oric->tapecaplastbit = tapebit; /* Were we waiting for the first toggle? */ - if( oric->tapecapcount < 0 ) + if(oric->tapecapcount < 0) { /* Well, we found it */ oric->tapecapcount = 0; - fputc( tapebit, oric->tapecap ); + fputc(tapebit, oric->tapecap); return; } count = (oric->tapecapcount>>1); - if( count < 0xfc ) + if(count < 0xfc) { buffer[0] = count; bufwrite = 1; } - else if( count < 0x100 ) + else if(count < 0x100) { buffer[0] = 0xfc; buffer[1] = count; bufwrite = 2; } - else if( count < 0x10000 ) + else if(count < 0x10000) { buffer[0] = 0xfd; buffer[1] = (count>>8)&0xff; @@ -212,30 +225,30 @@ void tape_orbchange( struct via *via ) bufwrite = 3; } - fwrite( buffer, bufwrite, 1, oric->tapecap ); + fwrite(buffer, bufwrite, 1, oric->tapecap); oric->tapecapcount = 0; } // Set the tape motor on or off -void tape_setmotor( struct machine *oric, SDL_bool motoron ) +void tape_setmotor(struct machine *oric, SDL_bool motoron) { - if( motoron == oric->tapemotor ) + if(motoron == oric->tapemotor) return; // Refresh the tape status icon in the status bar refreshtape = SDL_TRUE; // "Real" tape emulation? - if( ( !oric->tapeturbo ) || ( !oric->pch_tt_available ) ) + if((!oric->tapeturbo) || (!oric->pch_tt_available)) { - if( ( !oric->rawtape ) || ( oric->tapeoffs < oric->nonrawend ) ) + if((!oric->rawtape) || (oric->tapeoffs < oric->nonrawend)) { // If we're stopping part way through a byte, just move // the current position on to the start of the next byte - if( !motoron ) + if(!motoron) { - if( oric->tapebit > 0 ) + if(oric->tapebit > 0) oric->tapeoffs++; oric->tapebit = 0; } @@ -244,10 +257,10 @@ void tape_setmotor( struct machine *oric, SDL_bool motoron ) // is at a sync header, generate a bunch of dummy // sync bytes. This makes the Oric Atmos welcome tape // work without turbo tape enabled, for example. - if( ( motoron ) && - ( oric->tapebuf ) && - ( oric->tapeoffs < oric->tapelen ) && - ( oric->tapebuf[oric->tapeoffs] == 0x16 ) ) + if((motoron) && + (oric->tapebuf) && + (oric->tapeoffs < oric->tapelen) && + (oric->tapebuf[oric->tapeoffs] == 0x16)) { tape_setup_header(oric); } @@ -256,43 +269,43 @@ void tape_setmotor( struct machine *oric, SDL_bool motoron ) // Set the new status and do a popup oric->tapemotor = motoron; - if( oric->tapename[0] ) tape_popup( oric ); + if(oric->tapename[0]) tape_popup(oric); } // Free up the current tape image -void tape_eject( struct machine *oric ) +void tape_eject(struct machine *oric) { - if( oric->tapebuf ) free( oric->tapebuf ); + if(oric->tapebuf) free(oric->tapebuf); oric->tapebuf = NULL; oric->tapelen = 0; oric->tapename[0] = 0; - tape_popup( oric ); + tape_popup(oric); refreshtape = SDL_TRUE; } -void tape_next_raw_count( struct machine *oric ) +void tape_next_raw_count(struct machine *oric) { unsigned int n; int nonrawend; - if( oric->tapeoffs >= oric->tapelen ) + if(oric->tapeoffs >= oric->tapelen) { - if( oric->nonrawend != oric->tapelen ) + if(oric->nonrawend != oric->tapelen) oric->tapehitend = 3; return; } n = oric->tapebuf[oric->tapeoffs++]; - if (n < 0xfc) + if(n < 0xfc) { oric->tapecount = n<<1; return; } - switch (n) + switch(n) { case 0xff: // non-raw section - if( oric->tapeoffs >= (oric->tapelen-1) ) + if(oric->tapeoffs >= (oric->tapelen-1)) { oric->tapeoffs = oric->tapelen; oric->tapehitend = 3; @@ -300,7 +313,7 @@ void tape_next_raw_count( struct machine *oric ) } nonrawend = ((oric->tapebuf[oric->tapeoffs]<<8)|oric->tapebuf[oric->tapeoffs+1]) + oric->tapeoffs+2; - if( nonrawend > oric->tapelen ) + if(nonrawend > oric->tapelen) { oric->tapeoffs = oric->tapelen; oric->tapehitend = 3; @@ -312,11 +325,11 @@ void tape_next_raw_count( struct machine *oric ) oric->tapebit = 0; oric->tapecount = 2; oric->tapeout = 0; - tape_setup_header( oric ); + tape_setup_header(oric); return; case 0xfc: - if( oric->tapeoffs >= oric->tapelen ) + if(oric->tapeoffs >= oric->tapelen) { oric->tapehitend = 3; return; @@ -326,7 +339,7 @@ void tape_next_raw_count( struct machine *oric ) return; case 0xfd: - if( oric->tapeoffs >= (oric->tapelen-1) ) + if(oric->tapeoffs >= (oric->tapelen-1)) { oric->tapeoffs = oric->tapelen; oric->tapehitend = 3; @@ -344,16 +357,16 @@ void tape_next_raw_count( struct machine *oric ) } // Rewind to the start of the tape -void tape_rewind( struct machine *oric ) +void tape_rewind(struct machine *oric) { oric->nonrawend = 0; - if( oric->rawtape ) + if(oric->rawtape) { oric->tapeout = oric->tapebuf[4]; - via_write_CB1( &oric->via, oric->tapeout ); + via_write_CB1(&oric->via, oric->tapeout); oric->tapeoffs = 5; - tape_next_raw_count( oric ); + tape_next_raw_count(oric); } else { @@ -363,8 +376,8 @@ void tape_rewind( struct machine *oric ) oric->tapeout = 0; oric->tapedupbytes = 0; - if( oric->tapebuf ) - tape_setup_header( oric ); + if(oric->tapebuf) + tape_setup_header(oric); } oric->tapehitend = 0; oric->tapedelay = 0; @@ -374,22 +387,22 @@ void tape_rewind( struct machine *oric ) // This is used by the "tapsections" function. It returns the next time // value from an ort buffer, or -1 for invalid (or if an existing tapsection // is found) -static int next_ort_value( unsigned char *ortdata, int *offset, int end, SDL_bool *anytapsec ) +static int next_ort_value(unsigned char* ortdata, int* offset, int end, SDL_bool *anytapsec) { int val=0, skip; - while ((*offset) < end) + while((*offset) < end) { - switch (ortdata[*offset]) + switch(ortdata[*offset]) { case 0xfc: - if ((*offset) >= (end-1)) return 0; + if((*offset) >= (end-1)) return 0; val = ortdata[(*offset)+1]; (*offset) += 2; return val; case 0xfd: - if ((*offset) >= (end-2)) return 0; + if((*offset) >= (end-2)) return 0; val = (ortdata[(*offset)+1]<<8)|ortdata[(*offset)+2]; (*offset) += 3; return val; @@ -398,10 +411,10 @@ static int next_ort_value( unsigned char *ortdata, int *offset, int end, SDL_boo return 0; case 0xff: - if ((*offset) >= (end-2)) return 0; + if((*offset) >= (end-2)) return 0; skip = (ortdata[(*offset)+1]<<8)|ortdata[(*offset)+2]; (*offset)+=3; - if ((*offset) >= (end-skip)) return 0; + if((*offset) >= (end-skip)) return 0; (*offset)+=skip; (*anytapsec) = SDL_TRUE; break; @@ -428,14 +441,14 @@ enum static int validbyte(int accum) { int i, parity = 0; - if ((accum&3)!=1) return 0; - for (i=4; i!=0x800; i<<=1) - if (accum&i) parity ^= 1; + if((accum&3)!=1) return 0; + for(i=4; i!=0x800; i<<=1) + if(accum&i) parity ^= 1; return parity; } // This converts oric standard encoded waveforms to decoded TAP sections -static int tapsections( unsigned char *ortbuf, int ortbuflen, unsigned char *scratch, SDL_bool slow ) +static int tapsections(unsigned char* ortbuf, int ortbuflen, unsigned char* scratch, SDL_bool slow) { int ort_offs, tapebit, ort_val, cyccount; int accum, state, thisbit, leaderstart=0, leadercount=0; @@ -450,20 +463,20 @@ static int tapsections( unsigned char *ortbuf, int ortbuflen, unsigned char *scr accum = 0; bitcount = 0; - for (i=0; i<20; i++) + for(i=0; i<20; i++) last_offsets[i] = 5; // Loop through the ORT data - while (ort_offs < ortbuflen) + while(ort_offs < ortbuflen) { // Shuffle the offset array - for (i=0; i<19; i++) + for(i=0; i<19; i++) last_offsets[i] = last_offsets[i+1]; last_offsets[19] = ort_offs; ort_val = next_ort_value(ortbuf, &ort_offs, ortbuflen, &anytapsec); // Invalid ORT data? - if (ort_val < 1) return ortbuflen; + if(ort_val < 1) return ortbuflen; // Count these cycles cyccount += ort_val; @@ -472,24 +485,24 @@ static int tapsections( unsigned char *ortbuf, int ortbuflen, unsigned char *scr tapebit ^= 1; // Rising edge? - if (tapebit) + if(tapebit) { // smaller than 100? filter it out - if (cyccount < 100) + if(cyccount < 100) continue; // Convert to 1/0 thisbit = TIME_TO_BIT(cyccount); // Seen a value that is outside the bounds of Oric standard encoding? - if (thisbit == -1) + if(thisbit == -1) { -// if ((state != TAPSEC_STATE_SEARCH) || (slow0s>0) || (slow1s>0)) -// { -// if (cyccount < TAPE_DECODE_1_MIN) printf("%d is too fast\n", cyccount); -// if (cyccount > TAPE_DECODE_0_MAX) printf("%d is too slow\n", cyccount); -// fflush(stdout); -// } + // if ((state != TAPSEC_STATE_SEARCH) || (slow0s>0) || (slow1s>0)) + // { + // if (cyccount < TAPE_DECODE_1_MIN) printf("%d is too fast\n", cyccount); + // if (cyccount > TAPE_DECODE_0_MAX) printf("%d is too slow\n", cyccount); + // fflush(stdout); + // } state = TAPSEC_STATE_SEARCH; cyccount = 0; accum = 0; @@ -499,16 +512,16 @@ static int tapsections( unsigned char *ortbuf, int ortbuflen, unsigned char *scr else { // Slow mode? - if (slow) + if(slow) { - if (thisbit==1) + if(thisbit==1) { slow1s++; slow0s=0; - if (slow1s != 2) + if(slow1s != 2) { - if (slow1s >= 8) + if(slow1s >= 8) slow1s = 0; cyccount=0; continue; @@ -519,9 +532,9 @@ static int tapsections( unsigned char *ortbuf, int ortbuflen, unsigned char *scr slow0s++; slow1s=0; - if (slow0s != 2) + if(slow0s != 2) { - if (slow0s >= 4) + if(slow0s >= 4) slow0s = 0; cyccount=0; continue; @@ -533,43 +546,43 @@ static int tapsections( unsigned char *ortbuf, int ortbuflen, unsigned char *scr accum = (accum>>1) | (thisbit<<10); // What are we doing? - switch (state) + switch(state) { case TAPSEC_STATE_SEARCH: // Look for 0x058 (0x16 encoded with start bit and parity) - if ((accum&0x7fe) == 0x58) + if((accum&0x7fe) == 0x58) { -// printf("Seen 0x16 @ %d\n", ort_offs); -// fflush(stdout); + // printf("Seen 0x16 @ %d\n", ort_offs); + // fflush(stdout); leaderstart = last_offsets[8]; leadercount = 1; state = TAPSEC_STATE_LEADER; bitcount = 0; } - else if (validbyte(accum)) + else if(validbyte(accum)) { -// printf("Saw %02X @ %d\n", (accum>>2)&0xff, ort_offs); -// fflush(stdout); + // printf("Saw %02X @ %d\n", (accum>>2)&0xff, ort_offs); + // fflush(stdout); } break; case TAPSEC_STATE_LEADER: bitcount = (bitcount+1)%14; - if ((bitcount==13)&&validbyte(accum)) bitcount = 0; - if (!bitcount) + if((bitcount==13)&&validbyte(accum)) bitcount = 0; + if(!bitcount) { -// printf("Byte @ %d is %03x\n", ort_offs, accum&0x7fe); -// fflush(stdout); - if ((accum&0x7fe) != 0x58) + // printf("Byte @ %d is %03x\n", ort_offs, accum&0x7fe); + // fflush(stdout); + if((accum&0x7fe) != 0x58) { -// printf("Which is NOT 0x58 :-(\n"); + // printf("Which is NOT 0x58 :-(\n"); state = TAPSEC_STATE_SEARCH; cyccount = 0; break; } leadercount++; - if (leadercount==4) + if(leadercount==4) { state = TAPSEC_STATE_FINDHEADER; break; @@ -579,15 +592,15 @@ static int tapsections( unsigned char *ortbuf, int ortbuflen, unsigned char *scr case TAPSEC_STATE_FINDHEADER: bitcount = (bitcount+1)%14; - if ((bitcount==13)&&validbyte(accum)) bitcount = 0; - if (!bitcount) + if((bitcount==13)&&validbyte(accum)) bitcount = 0; + if(!bitcount) { -// printf("Byte @ %d is %03x\n", ort_offs, accum&0x7fe); -// fflush(stdout); - if ((accum&0x7fe) == 0x490) // 0x24 fully encoded + // printf("Byte @ %d is %03x\n", ort_offs, accum&0x7fe); + // fflush(stdout); + if((accum&0x7fe) == 0x490) // 0x24 fully encoded { -// printf("At the header...\n"); -// fflush(stdout); + // printf("At the header...\n"); + // fflush(stdout); scratch[0] = 0x16; scratch[1] = 0x16; scratch[2] = 0x16; @@ -600,23 +613,23 @@ static int tapsections( unsigned char *ortbuf, int ortbuflen, unsigned char *scr case TAPSEC_STATE_HEADER: bitcount = (bitcount+1)%14; - if ((bitcount==13)&&validbyte(accum)) bitcount = 0; - if (!bitcount) + if((bitcount==13)&&validbyte(accum)) bitcount = 0; + if(!bitcount) { -// printf("Byte @ %d is %03x (%02X)\n", ort_offs, accum&0x7fe, (accum>>2)&0xff); -// fflush(stdout); + // printf("Byte @ %d is %03x (%02X)\n", ort_offs, accum&0x7fe, (accum>>2)&0xff); + // fflush(stdout); scratch[tapbytes++] = (accum>>2)&0xff; - if (tapbytes == 13) + if(tapbytes == 13) { int load_start, load_end; load_start = (scratch[10]<<8)|scratch[11]; load_end = (scratch[ 8]<<8)|scratch[ 9]; -// printf("Load start = %04X, Load end = %04X\n", load_start, load_end); -// fflush(stdout); + // printf("Load start = %04X, Load end = %04X\n", load_start, load_end); + // fflush(stdout); - if (load_end <= load_start) + if(load_end <= load_start) { state = TAPSEC_STATE_SEARCH; cyccount = 0; @@ -626,21 +639,21 @@ static int tapsections( unsigned char *ortbuf, int ortbuflen, unsigned char *scr data_bytes = (load_end-load_start)+1; state = TAPSEC_STATE_FILENAME; -// printf("Lets try and load %d bytes!\n", data_bytes); -// fflush(stdout); + // printf("Lets try and load %d bytes!\n", data_bytes); + // fflush(stdout); } } break; case TAPSEC_STATE_FILENAME: bitcount = (bitcount+1)%14; - if ((bitcount==13)&&validbyte(accum)) bitcount = 0; - if (!bitcount) + if((bitcount==13)&&validbyte(accum)) bitcount = 0; + if(!bitcount) { -// printf("Filename byte = %03x (%02x) %c\n", accum&0x7fe, (accum>>2)&0xff, (accum>>2)&0xff); -// fflush(stdout); + // printf("Filename byte = %03x (%02x) %c\n", accum&0x7fe, (accum>>2)&0xff, (accum>>2)&0xff); + // fflush(stdout); scratch[tapbytes++] = (accum>>2)&0xff; - if (scratch[tapbytes-1] == 0) + if(scratch[tapbytes-1] == 0) { state = TAPSEC_STATE_FINDDATA; } @@ -649,10 +662,10 @@ static int tapsections( unsigned char *ortbuf, int ortbuflen, unsigned char *scr case TAPSEC_STATE_FINDDATA: // Look for a valid byte (start bits, valid parity) - if (validbyte(accum)) + if(validbyte(accum)) { -// printf("Data starts @ %d\n", ort_offs); -// fflush(stdout); + // printf("Data starts @ %d\n", ort_offs); + // fflush(stdout); scratch[tapbytes++] = (accum>>2)&0xff; data_bytes--; bitcount=0; @@ -662,25 +675,25 @@ static int tapsections( unsigned char *ortbuf, int ortbuflen, unsigned char *scr case TAPSEC_STATE_DATA: bitcount = (bitcount+1)%14; - if ((bitcount==13)&&validbyte(accum)) bitcount = 0; - if (!bitcount) + if((bitcount==13)&&validbyte(accum)) bitcount = 0; + if(!bitcount) { scratch[tapbytes++] = (accum>>2)&0xff; data_bytes--; -// printf("%d to go..\n", data_bytes); -// fflush(stdout); + // printf("%d to go..\n", data_bytes); + // fflush(stdout); // ?? - if (data_bytes < 0) + if(data_bytes < 0) { state = TAPSEC_STATE_SEARCH; break; } - if (data_bytes > 0) + if(data_bytes > 0) break; - if ((!anytapsec) && (leaderstart < 512)) + if((!anytapsec) && (leaderstart < 512)) leaderstart = 5; // Got a whole standard oric tap section! @@ -696,8 +709,8 @@ static int tapsections( unsigned char *ortbuf, int ortbuflen, unsigned char *scr accum = 0; anytapsec = SDL_TRUE; -// printf("Back to scanning...\n"); -// fflush(stdout); + // printf("Back to scanning...\n"); + // fflush(stdout); } break; } @@ -714,7 +727,7 @@ static int tapsections( unsigned char *ortbuf, int ortbuflen, unsigned char *scr // file (either 8 or 16bit), and returns it as a signed value. No scaling // is performed, so it returns -128 to 127 for 8bit wavs, and -32768 to // 32767 for 16bit wavs. -static inline signed short getsmp(unsigned char *buf, SDL_bool is8bit) +static inline signed short getsmp(unsigned char* buf, SDL_bool is8bit) { return is8bit ? ((short)*buf)-128 : (short)((buf[1]<<8)|buf[0]); } @@ -724,13 +737,13 @@ static inline signed short getsmp(unsigned char *buf, SDL_bool is8bit) // any DC offset in the recording. It also calls "tapsections" to convert // any standard oric tape format waveforms it finds into non-raw "tap" // style sections to enable turbo loading of those parts. -SDL_bool wav_convert( struct machine *oric ) +SDL_bool wav_convert(struct machine *oric) { // Chunk pointers - unsigned char *p=oric->tapebuf, *data=NULL, *ortbuf=NULL; + unsigned char* p=oric->tapebuf, *data=NULL, *ortbuf=NULL; unsigned int i, j, k, l, chunklen, bps=0, freq=0, smpdelta=0, datalen=0, ortlen; signed int smaxl, sminl, smaxr, sminr, dcoffs=0, dcoffsav; - signed int *lastsmps = NULL; + signed int* lastsmps = NULL; signed short smp=0; // Cycles per sample double cps, count, pcount; @@ -738,50 +751,56 @@ SDL_bool wav_convert( struct machine *oric ) // Basic validation i = 12; - while ((!fmtseen) || (!data)) + while((!fmtseen) || (!data)) { // Run out of data? - if (i >= (oric->tapelen-8)) return SDL_FALSE; + if(i >= (oric->tapelen-8)) return SDL_FALSE; // Length of this chunk chunklen = (p[i+7]<<24)|(p[i+6]<<16)|(p[i+5]<<8)|p[i+4]; // Sane length? - if ((i+chunklen+8) > oric->tapelen) + if((i+chunklen+8) > oric->tapelen) return SDL_FALSE; // Format chunk? - if (memcmp(&p[i], "fmt ", 4) == 0) + if(memcmp(&p[i], "fmt ", 4) == 0) { // PCM? - if ((chunklen != 16) || (((p[i+9]<<8)|p[i+8])!=1)) + if((chunklen != 16) || (((p[i+9]<<8)|p[i+8])!=1)) return SDL_FALSE; // Channels - switch ((p[i+11]<<8)|(p[i+10])) + switch((p[i+11]<<8)|(p[i+10])) { - case 1: stereo = SDL_FALSE; break; - case 2: stereo = SDL_TRUE; break; - default: return SDL_FALSE; break; + case 1: + stereo = SDL_FALSE; + break; + case 2: + stereo = SDL_TRUE; + break; + default: + return SDL_FALSE; + break; } // Frequency freq = (p[i+15]<<24)|(p[i+14]<<16)|(p[i+13]<<8)|p[i+12]; - if( !freq ) return SDL_FALSE; + if(!freq) return SDL_FALSE; // Sample delta smpdelta = (p[i+21]<<16)|p[i+20]; // Bits per sample bps = (p[i+23]<<16)|p[i+22]; - if ((bps!=8)&&(bps!=16)) return SDL_FALSE; + if((bps!=8)&&(bps!=16)) return SDL_FALSE; // Bytes per sample bps /= 8; fmtseen = SDL_TRUE; } - else if (memcmp(&p[i], "data", 4) == 0) + else if(memcmp(&p[i], "data", 4) == 0) { data = &p[i+8]; datalen = chunklen; @@ -791,29 +810,29 @@ SDL_bool wav_convert( struct machine *oric ) i += chunklen+8; } -// printf("wavsize = %d\n", datalen); + // printf("wavsize = %d\n", datalen); smaxl = -70000; sminl = 70000; smaxr = -70000; sminr = 70000; - for (i=0; i smaxl) smaxl = smp; + if(smp < sminl) sminl = smp; + if(smp > smaxl) smaxl = smp; - if (stereo) + if(stereo) { smp = getsmp(&data[i+bps], bps==1); - if (smp < sminr) sminr = smp; - if (smp > smaxr) smaxr = smp; + if(smp < sminr) sminr = smp; + if(smp > smaxr) smaxr = smp; } } // Use the loudest channel - if ((stereo) && ((smaxr-sminr)>(smaxl-sminl))) + if((stereo) && ((smaxr-sminr)>(smaxl-sminl))) { useright = SDL_TRUE; } @@ -823,49 +842,49 @@ SDL_bool wav_convert( struct machine *oric ) } dcoffsav = freq / 700; - if (dcoffsav) + if(dcoffsav) { lastsmps = malloc(dcoffsav * sizeof(int)); - if (lastsmps) memset(lastsmps, 0, dcoffsav * sizeof(int)); + if(lastsmps) memset(lastsmps, 0, dcoffsav * sizeof(int)); } dcoffsav--; // Now convert to a 1/0 squarewave j = 0; - for (i=0; i smaxl) smaxl = lastsmps[k]; + if(lastsmps[k] < sminl) sminl = lastsmps[k]; + if(lastsmps[k] > smaxl) smaxl = lastsmps[k]; } dcoffs = ((smaxl-sminl)/2)+sminl; } - if (j >= oric->tapelen) + if(j >= oric->tapelen) { -// printf("Oh dear\n"); -// fflush(stdout); + // printf("Oh dear\n"); + // fflush(stdout); break; } oric->tapebuf[j++] = (smp>dcoffs) ? 1 : 0; } -// printf("ortsize = %d\n", j); -// fflush(stdout); + // printf("ortsize = %d\n", j); + // fflush(stdout); // Calculate cycles per sample cps = 500000 / ((double)freq); // .ORT is 500khz @@ -875,24 +894,24 @@ SDL_bool wav_convert( struct machine *oric ) i = oric->tapebuf[0]; count = 0.0f; pcount = 0.0f; - for (k=1; ktapebuf[k] != i) + if(oric->tapebuf[k] != i) { i = oric->tapebuf[k]; - if (((int)count) < 1) + if(((int)count) < 1) { // Just a spike? - if (ortlen>5) ortlen--; + if(ortlen>5) ortlen--; count += pcount; } - else if (((int)count) < 0xfc) + else if(((int)count) < 0xfc) { ortlen++; pcount = count; count = 0.0f; } - else if (((int)count) < 0x100) + else if(((int)count) < 0x100) { ortlen+=2; pcount = count; @@ -908,10 +927,10 @@ SDL_bool wav_convert( struct machine *oric ) count+=cps; } - free( lastsmps ); + free(lastsmps); // Allocate a buffer for the converted data ortbuf = malloc(ortlen); - if (!ortbuf) return SDL_FALSE; + if(!ortbuf) return SDL_FALSE; // Write the header memcpy(ortbuf, "ORT\0", 4); @@ -922,27 +941,27 @@ SDL_bool wav_convert( struct machine *oric ) count = 0.0f; pcount = 0.0f; l = 5; - for (k=1; ktapebuf[k] != i) + if(oric->tapebuf[k] != i) { i = oric->tapebuf[k]; - if (((int)count) < 1) + if(((int)count) < 1) { // Just a spike. Cancel the last swap. - if (l==5) + if(l==5) ortbuf[4] = i; else l--; count += pcount; } - else if (((int)count) < 0xfc) + else if(((int)count) < 0xfc) { ortbuf[l++] = count; pcount = count; count = 0.0f; } - else if (((int)count) < 0x100) + else if(((int)count) < 0x100) { ortbuf[l++] = 0xfc; ortbuf[l++] = count; @@ -975,67 +994,67 @@ SDL_bool wav_convert( struct machine *oric ) } // Insert a new tape image -SDL_bool tape_load_tap( struct machine *oric, char *fname ) +SDL_bool tape_load_tap(struct machine *oric, char* fname) { FILE *f; // First make sure the image file exists - f = fopen( fname, "rb" ); - if( !f ) return SDL_FALSE; + f = fopen(fname, "rb"); + if(!f) return SDL_FALSE; // Eject any old image - tape_eject( oric ); + tape_eject(oric); // Get the image size - fseek( f, 0, SEEK_END ); - oric->tapelen = (int)ftell( f ); - fseek( f, 0, SEEK_SET ); + fseek(f, 0, SEEK_END); + oric->tapelen = (int)ftell(f); + fseek(f, 0, SEEK_SET); - if( oric->tapelen <= 4 ) // Even worth loading it? + if(oric->tapelen <= 4) // Even worth loading it? { - fclose( f ); + fclose(f); return SDL_FALSE; } // Allocate memory for the tape image and read it in - oric->tapebuf = malloc( oric->tapelen+1 ); - if( !oric->tapebuf ) + oric->tapebuf = malloc(oric->tapelen+1); + if(!oric->tapebuf) { - fclose( f ); + fclose(f); oric->tapelen = 0; return SDL_FALSE; } - if( fread( &oric->tapebuf[0], oric->tapelen, 1, f ) != 1 ) + if(fread(&oric->tapebuf[0], oric->tapelen, 1, f) != 1) { - fclose( f ); - tape_eject( oric ); + fclose(f); + tape_eject(oric); return SDL_FALSE; } - fclose( f ); + fclose(f); // WAV - if ((oric->tapelen >= 36) && + if((oric->tapelen >= 36) && (memcmp(oric->tapebuf, "RIFF", 4) == 0) && (memcmp(oric->tapebuf+8, "WAVE", 4) == 0)) { - if (!wav_convert( oric )) + if(!wav_convert(oric)) { - msgbox( oric, MSGBOX_OK, "Invalid wav file" ); - tape_eject( oric ); + msgbox(oric, MSGBOX_OK, "Invalid wav file"); + tape_eject(oric); return SDL_FALSE; } oric->rawtape = SDL_TRUE; } // ORT - else if (memcmp(oric->tapebuf, "ORT\0", 4) == 0) + else if(memcmp(oric->tapebuf, "ORT\0", 4) == 0) { oric->rawtape = SDL_TRUE; } // TAP - else if (memcmp(oric->tapebuf, "\x16\x16\x16", 3) == 0) + else if(memcmp(oric->tapebuf, "\x16\x16\x16", 3) == 0) { oric->rawtape = SDL_FALSE; @@ -1046,271 +1065,282 @@ SDL_bool tape_load_tap( struct machine *oric, char *fname ) // ??? else { - tape_eject( oric ); - msgbox( oric, MSGBOX_OK, "Unrecognised tape format" ); + tape_eject(oric); + msgbox(oric, MSGBOX_OK, "Unrecognised tape format"); return SDL_FALSE; } // Rewind the tape - tape_rewind( oric ); + tape_rewind(oric); // Make a displayable version of the image filename - if( strlen( fname ) > 31 ) + if(strlen(fname) > 31) { - strncpy( oric->tapename, &fname[strlen(fname)-31], 32 ); + strncpy(oric->tapename, &fname[strlen(fname)-31], 32); oric->tapename[0] = 22; - } else { - strncpy( oric->tapename, fname, 32 ); + } + else + { + strncpy(oric->tapename, fname, 32); } oric->tapename[31] = 0; // Show it in the popup - tape_popup( oric ); + tape_popup(oric); return SDL_TRUE; } -void tape_autoinsert( struct machine *oric ) +void tape_autoinsert(struct machine *oric) { - char *odir; + char* odir; int i; SDL_bool tape_found; - if( strncmp( (char *)&oric->mem[oric->pch_fd_getname_addr], oric->lasttapefile, 16 ) == 0 ) + if(strncmp((char*)&oric->mem[oric->pch_fd_getname_addr], oric->lasttapefile, 16) == 0) oric->mem[oric->pch_fd_getname_addr] = 0; // Try and load the tape image - strcpy( tapefile, oric->lasttapefile ); + strcpy(tapefile, oric->lasttapefile); i = (int)strlen(tapefile); - odir = getcwd( NULL, 0 ); - chdir( tapepath ); - tape_found = tape_load_tap( oric, tapefile ); - if( !tape_found ) + odir = getcwd(NULL, 0); + chdir(tapepath); + tape_found = tape_load_tap(oric, tapefile); + if(!tape_found) { // Try appending .tap - strcpy( &tapefile[i], ".tap" ); - tape_found = tape_load_tap( oric, tapefile ); + strcpy(&tapefile[i], ".tap"); + tape_found = tape_load_tap(oric, tapefile); } - if( !tape_found ) + if(!tape_found) { // Try appending .ort - strcpy( &tapefile[i], ".ort" ); - tape_load_tap( oric, tapefile ); + strcpy(&tapefile[i], ".ort"); + tape_load_tap(oric, tapefile); } - if( oric->tapebuf ) + if(oric->tapebuf) { // We already inserted this one. Don't re-insert it when we get to the end. */ oric->lasttapefile[0] = 0; } - chdir( odir ); - free( odir ); + chdir(odir); + free(odir); } -void tape_stop_savepatch( struct machine *oric ) +void tape_stop_savepatch(struct machine *oric) { - if( !oric->tsavf ) return; + if(!oric->tsavf) return; - if( oric->tsavf == oric->tapecap ) + if(oric->tsavf == oric->tapecap) { unsigned char bufdata[2]; - fseek( oric->tsavf, oric->tapecapsavoffs, SEEK_SET ); + fseek(oric->tsavf, oric->tapecapsavoffs, SEEK_SET); bufdata[0] = (oric->tapecapsavbytes>>8)&0xff; bufdata[1] = oric->tapecapsavbytes&0xff; - fwrite( bufdata, 2, 1, oric->tsavf ); + fwrite(bufdata, 2, 1, oric->tsavf); oric->tapecapsavoffs = 0; oric->tapecapsavbytes = 0; } else { - fclose( oric->tsavf ); + fclose(oric->tsavf); +#ifdef WWW + // sync from memory state to persisted + EM_ASM( + FS.syncfs(function(err) + { + assert(!err); + }); + ); +#endif } oric->tsavf = NULL; } // Do the tape patches (must be done after every m6502 setcycles) -void tape_patches( struct machine *oric ) +void tape_patches(struct machine *oric) { Sint32 i, j; - setromon( oric) ; + setromon(oric) ; - if( oric->romon ) + if(oric->romon) { - if( oric->pch_fd_available ) + if(oric->pch_fd_available) { // Patch CLOAD to insert a tape image specified. // Unfortunately the way the ROM works means we // only have up to 16 chars. - if( ( oric->cpu.calcpc == oric->pch_fd_cload_getname_pc ) || - ( oric->cpu.calcpc == oric->pch_fd_recall_getname_pc ) ) + if((oric->cpu.calcpc == oric->pch_fd_cload_getname_pc) || + (oric->cpu.calcpc == oric->pch_fd_recall_getname_pc)) { // Read in the filename from RAM - for( i=0; i<16; i++ ) + for(i=0; i<16; i++) { - j = oric->cpu.read( &oric->cpu, oric->pch_fd_getname_addr+i ); - if( !j ) break; + j = oric->cpu.read(&oric->cpu, oric->pch_fd_getname_addr+i); + if(!j) break; oric->lasttapefile[i] = j; } oric->lasttapefile[i] = 0; - if( ( oric->cpu.read( &oric->cpu, oric->pch_fd_getname_addr ) != 0 ) && - ( oric->autoinsert ) ) + if((oric->cpu.read(&oric->cpu, oric->pch_fd_getname_addr) != 0) && + (oric->autoinsert)) { // Only do this if there is no tape inserted, or we're at the // end of the current tape, or the filename ends in .TAP, .ORT or .WAV - if( ( !oric->tapebuf ) || - ( oric->tapeoffs >= oric->tapelen -1 ) || - ( ( i > 3 ) && ( strcasecmp( &oric->lasttapefile[i-4], ".tap" ) == 0 ) ) || - ( ( i > 3 ) && ( strcasecmp( &oric->lasttapefile[i-4], ".ort" ) == 0 ) ) || - ( ( i > 3 ) && ( strcasecmp( &oric->lasttapefile[i-4], ".wav" ) == 0 ) ) ) + if((!oric->tapebuf) || + (oric->tapeoffs >= oric->tapelen -1) || + ((i > 3) && (strcasecmp(&oric->lasttapefile[i-4], ".tap") == 0)) || + ((i > 3) && (strcasecmp(&oric->lasttapefile[i-4], ".ort") == 0)) || + ((i > 3) && (strcasecmp(&oric->lasttapefile[i-4], ".wav") == 0))) { - tape_autoinsert( oric ); - oric->cpu.write( &oric->cpu, oric->pch_fd_getname_addr, 0 ); + tape_autoinsert(oric); + oric->cpu.write(&oric->cpu, oric->pch_fd_getname_addr, 0); } } } - else if( ( ( oric->cpu.calcpc == oric->pch_fd_csave_getname_pc ) || - ( oric->cpu.calcpc == oric->pch_fd_store_getname_pc ) ) && - ( ( !oric->tapecap ) || ( oric->tapeturbo ) ) ) + else if(((oric->cpu.calcpc == oric->pch_fd_csave_getname_pc) || + (oric->cpu.calcpc == oric->pch_fd_store_getname_pc)) && + ((!oric->tapecap) || (oric->tapeturbo))) { // Did we miss the end of a previous one? - if( oric->tsavf ) - tape_stop_savepatch( oric ); + if(oric->tsavf) + tape_stop_savepatch(oric); // If we're doing tape capture, we can just use that - if( oric->tapecap ) + if(oric->tapecap) { oric->tsavf = oric->tapecap; - if( oric->tapecapcount < 0 ) - fputc( 0, oric->tapecap ); - fputc( 0xff, oric->tapecap ); + if(oric->tapecapcount < 0) + fputc(0, oric->tapecap); + fputc(0xff, oric->tapecap); oric->tapecapsavoffs = (int)ftell(oric->tapecap); - fputc( 0x00, oric->tapecap ); - fputc( 0x00, oric->tapecap ); + fputc(0x00, oric->tapecap); + fputc(0x00, oric->tapecap); oric->tapecapsavbytes = 0; } else { - char *odir = NULL; + char* odir = NULL; // Read in the filename from RAM - for( i=0; i<16; i++ ) + for(i=0; i<16; i++) { - j = oric->cpu.read( &oric->cpu, oric->pch_fd_getname_addr+i ); - if( !j ) break; + j = oric->cpu.read(&oric->cpu, oric->pch_fd_getname_addr+i); + if(!j) break; tmptapename[i] = j; } tmptapename[i] = 0; // If no name, prompt for one - if( tmptapename[0] == 0 ) + if(tmptapename[0] == 0) { - if( !filerequester( oric, "Save to tape", tapepath, tmptapename, FR_TAPESAVETAP ) ) + if(!filerequester(oric, "Save to tape", tapepath, tmptapename, FR_TAPESAVETAP)) tmptapename[0] = 0; } // If there is one, append .TAP - if( tmptapename[0] ) + if(tmptapename[0]) { - if( (strlen(tmptapename) < 4) || (strcasecmp(&tmptapename[strlen(tmptapename)-4], ".tap") != 0) ) + if((strlen(tmptapename) < 4) || (strcasecmp(&tmptapename[strlen(tmptapename)-4], ".tap") != 0)) { - if (strlen(tmptapename)+5tsavf = fopen(tmptapename, "wb"); - chdir( odir ); - free( odir ); + chdir(odir); + free(odir); } } } - else if( ( oric->cpu.calcpc == oric->pch_tt_csave_end_pc ) || - ( oric->cpu.calcpc == oric->pch_tt_store_end_pc ) ) + else if((oric->cpu.calcpc == oric->pch_tt_csave_end_pc) || + (oric->cpu.calcpc == oric->pch_tt_store_end_pc)) { SDL_bool justtap = (oric->tsavf != oric->tapecap); - tape_stop_savepatch( oric ); - if( justtap ) + tape_stop_savepatch(oric); + if(justtap) { // filetmp defined in gui.c as filetmp[4096+512+4] - snprintf( filetmp, 4096+512+4-1, "\x0f\x10 Saved to %s", tmptapename ); + snprintf(filetmp, 4096+512+4-1, "\x0f\x10 Saved to %s", tmptapename); filetmp[31] = 0; - if (strlen(tmptapename) > 20) + if(strlen(tmptapename) > 20) { filetmp[30] = '\x16'; } - do_popup( oric, filetmp ); + do_popup(oric, filetmp); } tmptapename[0] = 0; } } - if( ( oric->pch_tt_save_available ) && ( ( !oric->tapecap ) || ( oric->tapeturbo ) ) ) + if((oric->pch_tt_save_available) && ((!oric->tapecap) || (oric->tapeturbo))) { - if( oric->cpu.calcpc == oric->pch_tt_putbyte_pc ) + if(oric->cpu.calcpc == oric->pch_tt_putbyte_pc) { - if( oric->tsavf ) + if(oric->tsavf) { - fputc( oric->cpu.a, oric->tsavf ); - if( oric->tsavf == oric->tapecap ) + fputc(oric->cpu.a, oric->tsavf); + if(oric->tsavf == oric->tapecap) oric->tapecapsavbytes++; } oric->cpu.calcpc = oric->pch_tt_putbyte_end_pc; - oric->cpu.calcop = oric->cpu.read( &oric->cpu, oric->cpu.calcpc ); + oric->cpu.calcop = oric->cpu.read(&oric->cpu, oric->cpu.calcpc); } - else if( oric->cpu.calcpc == oric->pch_tt_writeleader_pc ) + else if(oric->cpu.calcpc == oric->pch_tt_writeleader_pc) { - if( oric->tsavf ) + if(oric->tsavf) { unsigned char leader[] = { 0x16, 0x16, 0x16, 0x16 }; - fwrite( leader, 4, 1, oric->tsavf ); - if( oric->tsavf == oric->tapecap ) + fwrite(leader, 4, 1, oric->tsavf); + if(oric->tsavf == oric->tapecap) oric->tapecapsavbytes += 4; } oric->cpu.calcpc = oric->pch_tt_writeleader_end_pc; - oric->cpu.calcop = oric->cpu.read( &oric->cpu, oric->cpu.calcpc ); + oric->cpu.calcop = oric->cpu.read(&oric->cpu, oric->cpu.calcpc); } } } -// Only do turbotape past this point! + // Only do turbotape past this point! // No tape? Motor off? - if( ( !oric->tapebuf ) || ( !oric->tapemotor ) ) + if((!oric->tapebuf) || (!oric->tapemotor)) { - if( ( oric->pch_tt_available ) && ( oric->tapeturbo ) && ( oric->romon ) && ( oric->cpu.calcpc == oric->pch_tt_getsync_pc ) ) + if((oric->pch_tt_available) && (oric->tapeturbo) && (oric->romon) && (oric->cpu.calcpc == oric->pch_tt_getsync_pc)) oric->tapeturbo_syncstack = oric->cpu.sp; return; } - if( ( oric->tapeturbo_forceoff ) && ( oric->pch_tt_available ) && ( oric->romon ) && ( oric->cpu.calcpc == oric->pch_tt_getsync_end_pc ) ) + if((oric->tapeturbo_forceoff) && (oric->pch_tt_available) && (oric->romon) && (oric->cpu.calcpc == oric->pch_tt_getsync_end_pc)) oric->tapeturbo_forceoff = SDL_FALSE; // Don't do turbotape if we have a raw tape // Turbotape can't work with rawtape. TODO: Auto enable warpspeed when CLOADing/CSAVEing rawtape - if(( oric->rawtape ) && ( oric->tapeoffs >= oric->nonrawend )) return; + if((oric->rawtape) && (oric->tapeoffs >= oric->nonrawend)) return; - if(( !oric->tapebuf ) || ( oric->tapeoffs >= oric->tapelen )) return; + if((!oric->tapebuf) || (oric->tapeoffs >= oric->tapelen)) return; // Maybe do turbotape - if( ( oric->pch_tt_available ) && ( oric->tapeturbo ) && ( !oric->tapeturbo_forceoff ) && ( oric->romon ) ) + if((oric->pch_tt_available) && (oric->tapeturbo) && (!oric->tapeturbo_forceoff) && (oric->romon)) { SDL_bool dosyncpatch; dosyncpatch = SDL_FALSE; - if( oric->cpu.calcpc == oric->pch_tt_getsync_loop_pc ) + if(oric->cpu.calcpc == oric->pch_tt_getsync_loop_pc) { // Cassette sync was called when there was no valid // tape to sync, so the normal cassette sync hack failed @@ -1319,7 +1349,7 @@ void tape_patches( struct machine *oric ) // sync routine. // Did we spot the entry into the cassette sync routine? - if( oric->tapeturbo_syncstack == -1 ) + if(oric->tapeturbo_syncstack == -1) { // No. Give up. oric->tapeturbo_forceoff = SDL_TRUE; @@ -1332,10 +1362,10 @@ void tape_patches( struct machine *oric ) dosyncpatch = SDL_TRUE; } - if( ( oric->cpu.calcpc == oric->pch_tt_getsync_pc ) || ( dosyncpatch ) ) + if((oric->cpu.calcpc == oric->pch_tt_getsync_pc) || (dosyncpatch)) { // Currently at a sync byte? - if( oric->tapebuf[oric->tapeoffs] != 0x16 ) + if(oric->tapebuf[oric->tapeoffs] != 0x16) { // Find the next sync byte do @@ -1343,12 +1373,13 @@ void tape_patches( struct machine *oric ) oric->tapeoffs++; // Give up at end of image - if( oric->tapeoffs >= oric->tapelen ) + if(oric->tapeoffs >= oric->tapelen) { refreshtape = SDL_TRUE; return; } - } while( oric->tapebuf[oric->tapeoffs] != 0x16 ); + } + while(oric->tapebuf[oric->tapeoffs] != 0x16); } // "Jump" to the end of the cassette sync routine @@ -1357,7 +1388,7 @@ void tape_patches( struct machine *oric ) return; } - if( oric->cpu.calcpc == oric->pch_tt_readbyte_pc ) + if(oric->cpu.calcpc == oric->pch_tt_readbyte_pc) { // Read the next byte directly into A oric->cpu.a = oric->tapebuf[oric->tapeoffs++]; @@ -1367,24 +1398,22 @@ void tape_patches( struct machine *oric ) oric->cpu.f_c = oric->pch_tt_readbyte_setcarry ? 1 : 0; // Simulate the effects of the read byte routine - if( oric->pch_tt_readbyte_storebyte_addr != -1 ) oric->cpu.write( &oric->cpu, oric->pch_tt_readbyte_storebyte_addr, oric->cpu.a ); - if( oric->pch_tt_readbyte_storezero_addr != -1 ) oric->cpu.write( &oric->cpu, oric->pch_tt_readbyte_storezero_addr, 0x00 ); + if(oric->pch_tt_readbyte_storebyte_addr != -1) oric->cpu.write(&oric->cpu, oric->pch_tt_readbyte_storebyte_addr, oric->cpu.a); + if(oric->pch_tt_readbyte_storezero_addr != -1) oric->cpu.write(&oric->cpu, oric->pch_tt_readbyte_storezero_addr, 0x00); // Jump to the end of the read byte routine oric->cpu.calcpc = oric->pch_tt_readbyte_end_pc; - oric->cpu.calcop = oric->cpu.read( &oric->cpu, oric->cpu.calcpc ); - if( oric->tapeoffs >= oric->tapelen ) refreshtape = SDL_TRUE; + oric->cpu.calcop = oric->cpu.read(&oric->cpu, oric->cpu.calcpc); + if(oric->tapeoffs >= oric->tapelen) refreshtape = SDL_TRUE; } } } // Emulate the specified cpu-cycles time for the tape -void tape_ticktock( struct machine *oric, int cycles ) +void tape_ticktock(struct machine *oric, int cycles) { - Sint32 j; - // Update the counter since last PB7 toggle - if( ( oric->tapecap ) && ( oric->tapecapcount != -1 ) ) + if((oric->tapecap) && (oric->tapecapcount != -1)) oric->tapecapcount += cycles; // The VSync hack is triggered in the video emulation @@ -1397,46 +1426,46 @@ void tape_ticktock( struct machine *oric, int cycles ) // If the VSync hack is active, we pull CB1 low // while the above counter is active and it's value // is less 260. - if( oric->vsynchack ) + if(oric->vsynchack) { - j = (0 == oric->vsync || 260 < oric->vsync); - if( oric->via.cb1 != j ) - via_write_CB1( &oric->via, j ); + unsigned char j = (0 == oric->vsync || 260 < oric->vsync); + if(oric->via.cb1 != j) + via_write_CB1(&oric->via, j); } - if( oric->vsync > 0 ) + if(oric->vsync > 0) { oric->vsync -= cycles; - if( oric->vsync < 0 ) + if(oric->vsync < 0) oric->vsync = 0; } // No tape? Motor off? - if( ( !oric->tapebuf ) || ( !oric->tapemotor ) ) + if((!oric->tapebuf) || (!oric->tapemotor)) return; // Tape offset outside the tape image limits? - if( ( oric->tapeoffs < 0 ) || ( oric->tapeoffs >= oric->tapelen ) ) + if((oric->tapeoffs < 0) || (oric->tapeoffs >= oric->tapelen)) { - if( oric->tapehitend > 2 ) + if(oric->tapehitend > 2) { // Try to autoinsert a tape image - if( ( oric->lasttapefile[0] ) && ( oric->autoinsert ) ) + if((oric->lasttapefile[0]) && (oric->autoinsert)) { - tape_autoinsert( oric ); + tape_autoinsert(oric); oric->lasttapefile[0] = 0; } } } // Abort if turbotape is on - if( ( oric->pch_tt_available ) && ( oric->tapeturbo ) && ( !oric->tapeturbo_forceoff ) && ( oric->romon ) && ( !oric->rawtape ) ) + if((oric->pch_tt_available) && (oric->tapeturbo) && (!oric->tapeturbo_forceoff) && (oric->romon) && (!oric->rawtape)) return; - if( oric->tapehitend > 2 ) + if(oric->tapehitend > 2) return; - if( ( oric->tapehdrend != 0 ) && ( oric->tapeoffs == oric->tapehdrend ) ) + if((oric->tapehdrend != 0) && (oric->tapeoffs == oric->tapehdrend)) { oric->tapedelay = 1281; oric->tapehdrend = 0; @@ -1444,13 +1473,13 @@ void tape_ticktock( struct machine *oric, int cycles ) // No turbotape. Do "real" tape emulation. // Count down the cycle counter - if( oric->tapecount > cycles ) + if(oric->tapecount > cycles) { oric->tapecount -= cycles; - if( oric->tapedelay > 0 ) + if(oric->tapedelay > 0) { oric->tapedelay -= cycles; - if( oric->tapedelay < 0 ) + if(oric->tapedelay < 0) oric->tapedelay = 1; } return; @@ -1458,18 +1487,18 @@ void tape_ticktock( struct machine *oric, int cycles ) // Toggle the tape input oric->tapeout ^= 1; - if( !oric->vsynchack ) + if(!oric->vsynchack) { // Update the audio if tape noise is enabled - if( oric->tapenoise ) + if(oric->tapenoise) { - ay_lockaudio( &oric->ay ); // Gets unlocked at the end of each frame - if( oric->ay.do_logcycle_reset ) + ay_lockaudio(&oric->ay); // Gets unlocked at the end of each frame + if(oric->ay.do_logcycle_reset) { oric->ay.logcycle = oric->ay.newlogcycle; oric->ay.do_logcycle_reset = SDL_FALSE; } - if( oric->ay.tlogged < TAPELOG_SIZE ) + if(oric->ay.tlogged < TAPELOG_SIZE) { oric->ay.tapelog[oric->ay.tlogged ].cycle = oric->ay.logcycle; oric->ay.tapelog[oric->ay.tlogged++].val = oric->tapeout; @@ -1477,15 +1506,15 @@ void tape_ticktock( struct machine *oric, int cycles ) } // Put tape signal onto CB1 - via_write_CB1( &oric->via, oric->tapeout ); + via_write_CB1(&oric->via, oric->tapeout); } - if( oric->tapedelay > 0 ) + if(oric->tapedelay > 0) { oric->tapedelay -= cycles; - if( oric->tapedelay <= 0) + if(oric->tapedelay <= 0) { - if( oric->tapebit == 1 ) + if(oric->tapebit == 1) oric->tapedelay = 1; else oric->tapedelay = 0; @@ -1494,12 +1523,16 @@ void tape_ticktock( struct machine *oric, int cycles ) return; } - if( oric->tapeoffs >= oric->tapelen ) + if(oric->tapeoffs >= oric->tapelen) { - switch( oric->tapehitend ) + switch(oric->tapehitend) { - case 0: oric->tapecount = TAPE_1_PULSE; break; - case 1: oric->tapecount = 0x36*2; break; + case 0: + oric->tapecount = TAPE_1_PULSE; + break; + case 1: + oric->tapecount = 0x36*2; + break; } oric->tapehitend++; refreshtape = SDL_TRUE; @@ -1507,13 +1540,13 @@ void tape_ticktock( struct machine *oric, int cycles ) } // Raw tape - if( oric->rawtape ) + if(oric->rawtape) { // In a non-raw section? - if( oric->tapeoffs >= oric->nonrawend ) + if(oric->tapeoffs >= oric->nonrawend) { - tape_next_raw_count( oric ); - if( oric->tapehitend > 2 ) + tape_next_raw_count(oric); + if(oric->tapehitend > 2) refreshtape = SDL_TRUE; return; } @@ -1521,9 +1554,9 @@ void tape_ticktock( struct machine *oric, int cycles ) // .TAP real tape simulation // Tape signal rising edge - if( oric->tapeout ) + if(oric->tapeout) { - switch( oric->tapebit ) + switch(oric->tapebit) { case 0: // Start of a new byte. Send a 1 pulse oric->tapetime = TAPE_1_PULSE; @@ -1535,17 +1568,19 @@ void tape_ticktock( struct machine *oric, int cycles ) break; default: // For bit numbers 2 to 9, send actual byte bits 0 to 7 - if( oric->tapebuf[oric->tapeoffs]&(1<<(oric->tapebit-2)) ) + if(oric->tapebuf[oric->tapeoffs]&(1<<(oric->tapebit-2))) { oric->tapetime = TAPE_1_PULSE; oric->tapeparity ^= 1; - } else { + } + else + { oric->tapetime = TAPE_0_PULSE; } break; case 10: // Then a parity bit - if( oric->tapeparity ) + if(oric->tapeparity) oric->tapetime = TAPE_1_PULSE; else oric->tapetime = TAPE_0_PULSE; @@ -1560,9 +1595,9 @@ void tape_ticktock( struct machine *oric, int cycles ) // Move on to the next bit oric->tapebit = (oric->tapebit+1)%14; - if( !oric->tapebit ) + if(!oric->tapebit) { - if( oric->tapedupbytes > 0 ) + if(oric->tapedupbytes > 0) oric->tapedupbytes--; else oric->tapeoffs++; diff --git a/tape.h b/tape.h index 13ac6571..c656c92d 100644 --- a/tape.h +++ b/tape.h @@ -28,12 +28,12 @@ #define TIME_TO_BIT(t) ((tvid_textattrs & 1 ) + if(oric->vid_textattrs & 1) { oric->vid_ch_data = &oric->vid_ch_base[128*8]; - } else { + } + else + { oric->vid_ch_data = oric->vid_ch_base; } } // Decode an oric video attribute -static inline void ula_decode_attr( struct machine *oric, int attr, int y ) +static inline void ula_decode_attr(struct machine *oric, int attr, int y) { - switch( attr & 0x18 ) + switch(attr & 0x18) { case 0x00: // Foreground colour oric->vid_fg_col = attr & 0x07; @@ -64,8 +66,8 @@ static inline void ula_decode_attr( struct machine *oric, int attr, int y ) case 0x08: // Text attribute oric->vid_textattrs = attr & 0x07; oric->vid_blinkmask = attr & 0x04 ? 0x00 : 0x3f; - ula_refresh_charset( oric ); - if( oric->vid_textattrs & 0x02 ) + ula_refresh_charset(oric); + if(oric->vid_textattrs & 0x02) oric->vid_chline = (y>>1) & 0x07; else oric->vid_chline = y & 0x07; @@ -81,21 +83,23 @@ static inline void ula_decode_attr( struct machine *oric, int attr, int y ) oric->vid_mode = attr & 0x07; // Set up pointers for new mode - if( oric->vid_mode & 4 ) + if(oric->vid_mode & 4) { oric->vid_addr = oric->vidbases[0]; oric->vid_ch_base = &oric->mem[oric->vidbases[1]]; - } else { + } + else + { oric->vid_addr = oric->vidbases[2]; oric->vid_ch_base = &oric->mem[oric->vidbases[3]]; } - ula_refresh_charset( oric ); + ula_refresh_charset(oric); break; } } -static inline void ula_raster_default( struct machine *oric ) +static inline void ula_raster_default(struct machine *oric) { oric->vid_fg_col = 7; oric->vid_textattrs = 0; @@ -103,20 +107,20 @@ static inline void ula_raster_default( struct machine *oric ) oric->vid_bg_col = 0; oric->vid_bitptr = (Uint16 *)(&bittab[(oric->vid_fg_col<<12) | (oric->vid_bg_col<<9)]); oric->vid_inv_bitptr = (Uint16 *)(&bittab[((oric->vid_fg_col^7)<<12) | ((oric->vid_bg_col^7)<<9)]); - ula_refresh_charset( oric ); + ula_refresh_charset(oric); } -void ula_powerup_default( struct machine *oric ) +void ula_powerup_default(struct machine *oric) { - ula_decode_attr( oric, 0x1a, 0 ); + ula_decode_attr(oric, 0x1a, 0); } // Render a 6x1 block -static void ula_render_block( struct machine *oric, SDL_bool inverted, int data, int y ) +static void ula_render_block(struct machine *oric, SDL_bool inverted, int data, int y) { Uint16 *ptr; - if( inverted ) + if(inverted) { ptr = oric->vid_inv_bitptr + (data<<2); } @@ -125,17 +129,20 @@ static void ula_render_block( struct machine *oric, SDL_bool inverted, int data, ptr = oric->vid_bitptr + (data<<2); } - *((Uint16 *)oric->scrpt) = *(ptr++); oric->scrpt+=2; - *((Uint16 *)oric->scrpt) = *(ptr++); oric->scrpt+=2; - *((Uint16 *)oric->scrpt) = *(ptr++); oric->scrpt+=2; + *((Uint16 *)oric->scrpt) = *(ptr++); + oric->scrpt+=2; + *((Uint16 *)oric->scrpt) = *(ptr++); + oric->scrpt+=2; + *((Uint16 *)oric->scrpt) = *(ptr++); + oric->scrpt+=2; } -static void ula_render_block_checkdirty( struct machine *oric, SDL_bool inverted, int data, int y ) +static void ula_render_block_checkdirty(struct machine *oric, SDL_bool inverted, int data, int y) { Uint16 *ptr; int i; - if( inverted ) + if(inverted) { ptr = oric->vid_inv_bitptr + (data<<2); } @@ -144,9 +151,9 @@ static void ula_render_block_checkdirty( struct machine *oric, SDL_bool inverted ptr = oric->vid_bitptr + (data<<2); } - for( i=0; i<3; i++) + for(i=0; i<3; i++) { - if (*((Uint16 *)oric->scrpt) != *ptr) + if(*((Uint16 *)oric->scrpt) != *ptr) { *((Uint16 *)oric->scrpt) = *ptr; oric->vid_dirty[y] = SDL_TRUE; @@ -158,7 +165,7 @@ static void ula_render_block_checkdirty( struct machine *oric, SDL_bool inverted } // Render current screen (used by the monitor) -void ula_renderscreen( struct machine *oric ) +void ula_renderscreen(struct machine *oric) { Uint8 *scrpt, *rptr; int b, y, c, cy, bitmask; @@ -166,68 +173,80 @@ void ula_renderscreen( struct machine *oric ) scrpt = oric->scrpt; oric->scrpt = oric->scr; - for( y=0; y<224; y++) + for(y=0; y<224; y++) { cy = (y>>3) * 40; // Always start each scanline with white on black - ula_raster_default( oric ); + ula_raster_default(oric); oric->vid_chline = y & 0x07; - if( y < 200 ) + if(y < 200) { - if( oric->vid_mode & 0x04 ) // HIRES? + if(oric->vid_mode & 0x04) // HIRES? { hires = SDL_TRUE; rptr = &oric->mem[oric->vid_addr + y*40 -1]; - } else { + } + else + { hires = SDL_FALSE; rptr = &oric->mem[oric->vid_addr + cy -1]; } - } else { + } + else + { hires = SDL_FALSE; rptr = &oric->mem[oric->vidbases[2] + cy -1]; // bb80 = bf68 - (200/8*40) } bitmask = (oric->frames&0x10)?0x3f:oric->vid_blinkmask; - for( b=0; b<40; b++ ) + for(b=0; b<40; b++) { c = *(++rptr); /* if bits 6 and 5 are zero, the byte contains a serial attribute */ - if( ( c & 0x60 ) == 0 ) + if((c & 0x60) == 0) { - ula_decode_attr( oric, c, y ); - ula_render_block( oric, (c & 0x80)!=0, 0, y ); - if( y < 200 ) + ula_decode_attr(oric, c, y); + ula_render_block(oric, (c & 0x80)!=0, 0, y); + if(y < 200) { - if( oric->vid_mode & 0x04 ) // HIRES? + if(oric->vid_mode & 0x04) // HIRES? { hires = SDL_TRUE; rptr = &oric->mem[oric->vid_addr + b + y*40]; - } else { + } + else + { hires = SDL_FALSE; rptr = &oric->mem[oric->vid_addr + b + cy]; } - } else { + } + else + { hires = SDL_FALSE; rptr = &oric->mem[oric->vidbases[2] + b + cy]; // bb80 = bf68 - (200/8*40) } bitmask = (oric->frames&0x10)?0x3f:oric->vid_blinkmask; - } else { - if( hires ) + } + else + { + if(hires) + { + ula_render_block(oric, (c & 0x80)!=0, c & bitmask, y); + } + else { - ula_render_block( oric, (c & 0x80)!=0, c & bitmask, y ); - } else { int ch_ix, ch_dat; ch_ix = c & 0x7f; - ch_dat = oric->vid_ch_data[ (ch_ix<<3) | oric->vid_chline ] & bitmask; + ch_dat = oric->vid_ch_data[(ch_ix<<3) | oric->vid_chline ] & bitmask; - ula_render_block( oric, (c & 0x80)!=0, ch_dat, y ); + ula_render_block(oric, (c & 0x80)!=0, ch_dat, y); } } } @@ -236,7 +255,7 @@ void ula_renderscreen( struct machine *oric ) } // Draw one rasterline -SDL_bool ula_doraster( struct machine *oric ) +SDL_bool ula_doraster(struct machine *oric) { int b, c, bitmask; SDL_bool hires, needrender; @@ -246,28 +265,28 @@ SDL_bool ula_doraster( struct machine *oric ) needrender = SDL_FALSE; oric->vid_raster++; - if( oric->vid_raster == oric->vid_maxrast ) + if(oric->vid_raster == oric->vid_maxrast) { - if( vidcap ) + if(vidcap) { // If we're recording with sound, and they do warp speed, // stop writing frames to the AVI, since it'll just get out of sync. - if ( ( !vidcap->dosnd ) || ( !warpspeed ) ) + if((!vidcap->dosnd) || (!warpspeed)) { // If the oric refresh rate and AVI refresh rate match, just output every frame - if( vidcap->is50hz == oric->vid_freq ) + if(vidcap->is50hz == oric->vid_freq) { - ay_lockaudio( &oric->ay ); // Gets unlocked at the end of each frame - avi_addframe( &vidcap, oric->scr ); + ay_lockaudio(&oric->ay); // Gets unlocked at the end of each frame + avi_addframe(&vidcap, oric->scr); } // Check for 60hz oric & 50 hz AVI - else if( vidcap->is50hz ) + else if(vidcap->is50hz) { // In this case we need to throw away every sixth frame - if( (vidcap->frameadjust%6) != 5 ) + if((vidcap->frameadjust%6) != 5) { - ay_lockaudio( &oric->ay ); // Gets unlocked at the end of each frame - avi_addframe( &vidcap, oric->scr ); + ay_lockaudio(&oric->ay); // Gets unlocked at the end of each frame + avi_addframe(&vidcap, oric->scr); } vidcap->frameadjust++; @@ -276,11 +295,11 @@ SDL_bool ula_doraster( struct machine *oric ) else { // In this case we need to duplicate every fifth frame - ay_lockaudio( &oric->ay ); // Gets unlocked at the end of each frame - avi_addframe( &vidcap, oric->scr ); + ay_lockaudio(&oric->ay); // Gets unlocked at the end of each frame + avi_addframe(&vidcap, oric->scr); - if( (vidcap->frameadjust%5) == 4 ) - avi_addframe( &vidcap, oric->scr ); + if((vidcap->frameadjust%5) == 4) + avi_addframe(&vidcap, oric->scr); vidcap->frameadjust++; } @@ -288,7 +307,7 @@ SDL_bool ula_doraster( struct machine *oric ) } oric->vid_raster = 0; - + // store current T1 counter oric->vid_offset = oric->via.t1c/64; @@ -316,7 +335,7 @@ SDL_bool ula_doraster( struct machine *oric ) needrender = SDL_TRUE; oric->frames++; - if( oric->vid_freq != (oric->vid_mode&2) ) + if(oric->vid_freq != (oric->vid_mode&2)) { oric->vid_freq = oric->vid_mode&2; @@ -329,14 +348,16 @@ SDL_bool ula_doraster( struct machine *oric ) // NTSC = 60Hz = 1,000,000/60 = 16667 cpu cycles/frame // 264 scanlines/frame, so 16667/260 = ~64 cpu cycles / scanline - if( oric->vid_freq ) + if(oric->vid_freq) { // PAL50 - T1 period 19966 oric->cyclesperraster = 64; oric->vid_maxrast = 308 + 4; /* VSync */ oric->vid_start = (oric->vid_maxrast - 224) /2; oric->vid_end = oric->vid_start + 224; - } else { + } + else + { // NTSC - T1 period 16894 oric->cyclesperraster = 64; oric->vid_maxrast = 260 + 4; /* VSync */ @@ -347,8 +368,8 @@ SDL_bool ula_doraster( struct machine *oric ) } // Are we on a visible rasterline? - if( ( oric->vid_raster < oric->vid_start ) || - ( oric->vid_raster >= oric->vid_end ) ) return needrender; + if((oric->vid_raster < oric->vid_start) || + (oric->vid_raster >= oric->vid_end)) return needrender; y = oric->vid_raster - oric->vid_start; oric->scrpt = &oric->scr[y*240]; @@ -356,67 +377,79 @@ SDL_bool ula_doraster( struct machine *oric ) cy = (y>>3) * 40; // Always start each scanline with white on black - ula_raster_default( oric ); + ula_raster_default(oric); oric->vid_chline = y & 0x07; // warpspeed does frameskipping, so lines may still be dirty oric->vid_block_func = oric->vid_dirty[y] ? ula_render_block : ula_render_block_checkdirty; - if( y < 200 ) + if(y < 200) { - if( oric->vid_mode & 0x04 ) // HIRES? + if(oric->vid_mode & 0x04) // HIRES? { hires = SDL_TRUE; rptr = &oric->mem[oric->vid_addr + y*40 -1]; - } else { + } + else + { hires = SDL_FALSE; rptr = &oric->mem[oric->vid_addr + cy -1]; } - } else { + } + else + { hires = SDL_FALSE; rptr = &oric->mem[oric->vidbases[2] + cy -1]; // bb80 = bf68 - (200/8*40) } bitmask = (oric->frames&0x10)?0x3f:oric->vid_blinkmask; - for( b=0; b<40; b++ ) + for(b=0; b<40; b++) { c = *(++rptr); /* if bits 6 and 5 are zero, the byte contains a serial attribute */ - if( ( c & 0x60 ) == 0 ) + if((c & 0x60) == 0) { - ula_decode_attr( oric, c, y ); - oric->vid_block_func( oric, (c & 0x80)!=0, 0, y ); - if( y < 200 ) + ula_decode_attr(oric, c, y); + oric->vid_block_func(oric, (c & 0x80)!=0, 0, y); + if(y < 200) { - if( oric->vid_mode & 0x04 ) // HIRES? + if(oric->vid_mode & 0x04) // HIRES? { hires = SDL_TRUE; rptr = &oric->mem[oric->vid_addr + b + y*40]; - } else { + } + else + { hires = SDL_FALSE; rptr = &oric->mem[oric->vid_addr + b + cy]; } - } else { - if (hires) + } + else + { + if(hires) { hires = SDL_FALSE; rptr = &oric->mem[oric->vidbases[2] + b + cy]; // bb80 = bf68 - (200/8*40) } } bitmask = (oric->frames&0x10)?0x3f:oric->vid_blinkmask; - } else { - if( hires ) + } + else + { + if(hires) + { + oric->vid_block_func(oric, (c & 0x80)!=0, c & bitmask, y); + } + else { - oric->vid_block_func( oric, (c & 0x80)!=0, c & bitmask, y ); - } else { int ch_ix, ch_dat; ch_ix = c & 0x7f; - ch_dat = oric->vid_ch_data[ (ch_ix<<3) | oric->vid_chline ] & bitmask; + ch_dat = oric->vid_ch_data[(ch_ix<<3) | oric->vid_chline ] & bitmask; - oric->vid_block_func( oric, (c & 0x80)!=0, ch_dat, y ); + oric->vid_block_func(oric, (c & 0x80)!=0, ch_dat, y); } } } @@ -424,17 +457,17 @@ SDL_bool ula_doraster( struct machine *oric ) return needrender; } -void ula_set_dirty( struct machine *oric ) +void ula_set_dirty(struct machine *oric) { int i; - for( i=0; i<224; i++ ) + for(i=0; i<224; i++) { oric->vid_dirty[i] = SDL_TRUE; } } -void preinit_ula( struct machine *oric ) +void preinit_ula(struct machine *oric) { oric->scr = NULL; oric->aratio = SDL_TRUE; @@ -443,26 +476,26 @@ void preinit_ula( struct machine *oric ) oric->palghost = SDL_TRUE; } -SDL_bool init_ula( struct machine *oric ) +SDL_bool init_ula(struct machine *oric) { int fg, bg, bits, offs, mask; - oric->scr = (Uint8 *)malloc( 240*224 ); - if( !oric->scr ) return SDL_FALSE; + oric->scr = (Uint8 *)malloc(240*224); + if(!oric->scr) return SDL_FALSE; memset(oric->scr, 0, 240*224); - ula_set_dirty( oric ); + ula_set_dirty(oric); /* Precalc all 6 bit combinations for all colour combinations */ - for( fg=0; fg<8; fg++ ) + for(fg=0; fg<8; fg++) { - for( bg=0; bg<8; bg++ ) + for(bg=0; bg<8; bg++) { - for( bits=0; bits<64; bits++) + for(bits=0; bits<64; bits++) { // FFFBBBbbbbbb000 offs = (fg<<12)|(bg<<9)|(bits<<3); - for( mask=0x20; mask; mask>>=1 ) + for(mask=0x20; mask; mask>>=1) { bittab[offs++] = (bits&mask) ? fg : bg; } @@ -473,8 +506,8 @@ SDL_bool init_ula( struct machine *oric ) return SDL_TRUE; } -void shut_ula( struct machine *oric ) +void shut_ula(struct machine *oric) { - if( oric->scr ) free( oric->scr ); + if(oric->scr) free(oric->scr); oric->scr = NULL; } diff --git a/ula.h b/ula.h index eb50a219..7200482c 100644 --- a/ula.h +++ b/ula.h @@ -19,10 +19,10 @@ ** Oric video ULA */ -void preinit_ula( struct machine *oric ); -SDL_bool init_ula( struct machine *oric ); -void shut_ula( struct machine *oric ); -SDL_bool ula_doraster( struct machine *oric ); -void ula_powerup_default( struct machine *oric ); -void ula_renderscreen( struct machine *oric ); -void ula_set_dirty( struct machine *oric ); +void preinit_ula(struct machine *oric); +SDL_bool init_ula(struct machine *oric); +void shut_ula(struct machine *oric); +SDL_bool ula_doraster(struct machine *oric); +void ula_powerup_default(struct machine *oric); +void ula_renderscreen(struct machine *oric); +void ula_set_dirty(struct machine *oric); diff --git a/via.c b/via.c index 46fffb6a..9054fb52 100644 --- a/via.c +++ b/via.c @@ -43,74 +43,76 @@ // do the response from the printer, the // other to close the printer_out.txt filehandle // after the printer is idle for a while. -void lprintchar( struct machine *oric, char c ) +void lprintchar(struct machine *oric, char c) { - if( oric->printenable ) + if(oric->printenable) { // Filter out chars that are probably not meant for the printer - if( ( !oric->printfilter ) || ( c == 9 ) || ( c == 10 ) || ( c == 13 ) || ( c == 17 ) || - ( c == 18 ) || ( c == 27 ) || (( c >= 32 ) && ( c <= 127 )) ) + if((!oric->printfilter) || (c == 9) || (c == 10) || (c == 13) || (c == 17) || + (c == 18) || (c == 27) || ((c >= 32) && (c <= 127))) { // If the printer handle isn't currently open, // open it and do a popup to tell the user. - if( !oric->prf ) + if(!oric->prf) { - oric->prf = fopen( "printer_out.txt", "a" ); - if( !oric->prf ) + oric->prf = fopen("printer_out.txt", "a"); + if(!oric->prf) { - do_popup( oric, "Printing failed :-(" ); + do_popup(oric, "Printing failed :-("); return; } - do_popup( oric, "Printing to 'printer_out.txt'" ); + do_popup(oric, "Printing to 'printer_out.txt'"); } // Put the char to the file, set up the timers - fputc( c, oric->prf ); + fputc(c, oric->prf); oric->prclose = 64*312*50*5; } // emulate ack signal oric->prclock = 40; - via_write_CA1( &oric->via, 1 ); + via_write_CA1(&oric->via, 1); } } // Update the CPU IRQ flags depending on the state of the VIA -static inline void via_check_irq( struct via *v ) +static inline void via_check_irq(struct via *v) { - if( ( v->ier & v->ifr )&0x7f ) + if((v->ier & v->ifr)&0x7f) { v->oric->cpu.irq |= v->irqbit; v->ifr |= 0x80; - } else { + } + else + { v->oric->cpu.irq &= ~v->irqbit; v->ifr &= 0x7f; } } // Set a bit in the IFR -static inline void via_set_irq( struct via *v, unsigned char bit ) +static inline void via_set_irq(struct via *v, unsigned char bit) { v->ifr |= bit; - if( ( v->ier & v->ifr )&0x7f ) + if((v->ier & v->ifr)&0x7f) v->ifr |= 0x80; - if( ( v->ier & bit ) == 0 ) return; + if((v->ier & bit) == 0) return; v->oric->cpu.irq |= v->irqbit; } // Clear a bit in the IFR -static inline void via_clr_irq( struct via *v, unsigned char bit ) +static inline void via_clr_irq(struct via *v, unsigned char bit) { - if( bit & VIRQF_CA1 ) + if(bit & VIRQF_CA1) v->iral = v->ira; - if( bit & VIRQF_CA2 ) + if(bit & VIRQF_CA2) v->irbl = v->irb; v->ifr &= ~bit; - if( (( v->ier & v->ifr )&0x7f) == 0 ) + if(((v->ier & v->ifr)&0x7f) == 0) { v->oric->cpu.irq &= ~v->irqbit; v->ifr &= 0x7f; @@ -118,63 +120,63 @@ static inline void via_clr_irq( struct via *v, unsigned char bit ) } -void via_main_w_iorb( struct via *v, unsigned char oldorb ) +void via_main_w_iorb(struct via *v, unsigned char oldorb) { // Look for negative edge on printer strobe - if( ( (oldorb&v->ddrb&0x10) != 0 ) && - ( (v->orb&v->ddrb&0x10) == 0 ) ) + if(((oldorb&v->ddrb&0x10) != 0) && + ((v->orb&v->ddrb&0x10) == 0)) { - lprintchar( v->oric, v->ora ); + lprintchar(v->oric, v->ora); } - tape_setmotor( v->oric, (v->orb&v->ddrb&0x40) != 0 ); + tape_setmotor(v->oric, (v->orb&v->ddrb&0x40) != 0); - if( (v->pcr&PCRF_CB2CON) == 0x80 ) - ay_set_bdir( &v->oric->ay, 0 ); + if((v->pcr&PCRF_CB2CON) == 0x80) + ay_set_bdir(&v->oric->ay, 0); - ay_update_keybits( &v->oric->ay ); + ay_update_keybits(&v->oric->ay); } -void via_main_w_iora( struct via *v ) +void via_main_w_iora(struct via *v) { - if( (v->pcr&PCRF_CA2CON) == 0x08 ) - ay_set_bc1( &v->oric->ay, 0 ); + if((v->pcr&PCRF_CA2CON) == 0x08) + ay_set_bc1(&v->oric->ay, 0); - ay_modeset( &v->oric->ay ); - joy_buildmask( v->oric ); + ay_modeset(&v->oric->ay); + joy_buildmask(v->oric); } -void via_main_w_iora2( struct via *v ) +void via_main_w_iora2(struct via *v) { - ay_modeset( &v->oric->ay ); - joy_buildmask( v->oric ); + ay_modeset(&v->oric->ay); + joy_buildmask(v->oric); } -void via_main_w_ddra( struct via *v ) +void via_main_w_ddra(struct via *v) { - joy_buildmask( v->oric ); + joy_buildmask(v->oric); } -void via_main_w_ddrb( struct via *v ) +void via_main_w_ddrb(struct via *v) { - joy_buildmask( v->oric ); - ay_update_keybits( &v->oric->ay ); + joy_buildmask(v->oric); + ay_update_keybits(&v->oric->ay); } -void via_main_w_pcr( struct via *v ) +void via_main_w_pcr(struct via *v) { SDL_bool updateay = SDL_FALSE; - switch( v->pcr & PCRF_CA2CON ) + switch(v->pcr & PCRF_CA2CON) { case 0x0c: updateay = SDL_TRUE; break; } -// if( (v->acr&ACRF_SRCON) == 0 ) + // if( (v->acr&ACRF_SRCON) == 0 ) { - switch( v->pcr & PCRF_CB2CON ) + switch(v->pcr & PCRF_CB2CON) { case 0xc0: case 0xe0: @@ -183,167 +185,167 @@ void via_main_w_pcr( struct via *v ) } } - if( updateay ) ay_set_bcmode( &v->oric->ay, v->ca2, v->cb2 ); + if(updateay) ay_set_bcmode(&v->oric->ay, v->ca2, v->cb2); } -void via_main_w_ca2ext( struct via *v ) +void via_main_w_ca2ext(struct via *v) { - switch( v->pcr & PCRF_CA2CON ) + switch(v->pcr & PCRF_CA2CON) { - case 0x00: // Interrupt on negative transision - case 0x02: // Independant negative transition + case 0x00: // Interrupt on negative transition + case 0x02: // Independent negative transition case 0x04: // Interrupt on positive transition - case 0x06: // Independant positive transition - ay_set_bc1( &v->oric->ay, v->ca2 ); + case 0x06: // Independent positive transition + ay_set_bc1(&v->oric->ay, v->ca2); break; - // 0x08, 0x0a, 0x0c, 0x0e: output modes. Nothing to do :) + // 0x08, 0x0a, 0x0c, 0x0e: output modes. Nothing to do :) } } -void via_main_w_cb2ext( struct via *v ) +void via_main_w_cb2ext(struct via *v) { - switch( v->pcr & PCRF_CB2CON ) + switch(v->pcr & PCRF_CB2CON) { case 0x00: case 0x20: case 0x40: case 0x60: - ay_set_bdir( &v->oric->ay, v->cb2 ); + ay_set_bdir(&v->oric->ay, v->cb2); break; } } -void via_main_r_iora( struct via *v ) +void via_main_r_iora(struct via *v) { - ay_modeset( &v->oric->ay ); - if( (v->pcr&PCRF_CA2CON) == 0x08 ) - ay_set_bc1( &v->oric->ay, 0 ); + ay_modeset(&v->oric->ay); + if((v->pcr&PCRF_CA2CON) == 0x08) + ay_set_bc1(&v->oric->ay, 0); } -void via_main_r_iora2( struct via *v ) +void via_main_r_iora2(struct via *v) { - ay_modeset( &v->oric->ay ); + ay_modeset(&v->oric->ay); } -void via_main_r_iorb( struct via *v ) +void via_main_r_iorb(struct via *v) { - if( (v->pcr&PCRF_CB2CON) == 0x80 ) - ay_set_bdir( &v->oric->ay, 0 ); + if((v->pcr&PCRF_CB2CON) == 0x80) + ay_set_bdir(&v->oric->ay, 0); } -void via_main_ca2pulsed( struct via *v ) +void via_main_ca2pulsed(struct via *v) { - ay_set_bc1( &v->oric->ay, 1 ); + ay_set_bc1(&v->oric->ay, 1); } -void via_main_cb2pulsed( struct via *v ) +void via_main_cb2pulsed(struct via *v) { - ay_set_bdir( &v->oric->ay, v->cb2 ); + ay_set_bdir(&v->oric->ay, v->cb2); } // Telestrat VIA2 -void via_tele_w_iorb( struct via *v, unsigned char oldorb ) +void via_tele_w_iorb(struct via *v, unsigned char oldorb) { - joy_buildmask( v->oric ); + joy_buildmask(v->oric); } -void via_tele_w_iora( struct via *v ) +void via_tele_w_iora(struct via *v) { int invddra = (v->ddra&7)^7; v->oric->tele_currbank = (v->oric->tele_currbank&invddra)|(v->ora&v->ddra&0x07); v->oric->tele_banktype = v->oric->tele_bank[v->oric->tele_currbank].type; v->oric->rom = v->oric->tele_bank[v->oric->tele_currbank].ptr; - joy_buildmask( v->oric ); + joy_buildmask(v->oric); } -void via_tele_w_iora2( struct via *v ) +void via_tele_w_iora2(struct via *v) { int invddra = (v->ddra&7)^7; v->oric->tele_currbank = (v->oric->tele_currbank&invddra)|(v->ora&v->ddra&0x07); v->oric->tele_banktype = v->oric->tele_bank[v->oric->tele_currbank].type; v->oric->rom = v->oric->tele_bank[v->oric->tele_currbank].ptr; - joy_buildmask( v->oric ); + joy_buildmask(v->oric); } -void via_tele_w_ddra( struct via *v ) +void via_tele_w_ddra(struct via *v) { int invddra = (v->ddra&7)^7; v->oric->tele_currbank = (v->oric->tele_currbank&invddra)|(v->ora&v->ddra&0x07); v->oric->tele_banktype = v->oric->tele_bank[v->oric->tele_currbank].type; v->oric->rom = v->oric->tele_bank[v->oric->tele_currbank].ptr; - joy_buildmask( v->oric ); + joy_buildmask(v->oric); } -void via_tele_w_ddrb( struct via *v ) +void via_tele_w_ddrb(struct via *v) { - joy_buildmask( v->oric ); + joy_buildmask(v->oric); } // Read ports from external device -unsigned char via_read_porta( struct via *v ) +unsigned char via_read_porta(struct via *v) { return v->ora & v->ddra; } -unsigned char via_read_portb( struct via *v ) +unsigned char via_read_portb(struct via *v) { return v->orb & v->ddrb; } // Write ports from external device -void via_main_write_porta( struct via *v, unsigned char mask, unsigned char data ) +void via_main_write_porta(struct via *v, unsigned char mask, unsigned char data) { v->ira = (v->ira&~mask)|(data&mask); - if( (!(v->acr&ACRF_PALATCH)) || - (!(v->ifr&VIRQF_CA1)) ) + if((!(v->acr&ACRF_PALATCH)) || + (!(v->ifr&VIRQF_CA1))) v->iral = v->ira; } -void via_tele_write_porta( struct via *v, unsigned char mask, unsigned char data ) +void via_tele_write_porta(struct via *v, unsigned char mask, unsigned char data) { v->ira = (v->ira&~mask)|(data&mask); - if( (!(v->acr&ACRF_PALATCH)) || - (!(v->ifr&VIRQF_CA1)) ) + if((!(v->acr&ACRF_PALATCH)) || + (!(v->ifr&VIRQF_CA1))) v->iral = v->ira; } -void via_write_portb( struct via *v, unsigned char mask, unsigned char data ) +void via_write_portb(struct via *v, unsigned char mask, unsigned char data) { unsigned char lastpb6; lastpb6 = v->irb&0x40; v->irb = (v->irb&~mask)|(data&mask); - if( (!(v->acr&ACRF_PBLATCH)) || - (!(v->acr&VIRQF_CB1)) ) + if((!(v->acr&ACRF_PBLATCH)) || + (!(v->acr&VIRQF_CB1))) v->irbl = v->irb; - // Is timer 2 counting PB6 negative transisions? - if( ( v->acr & ACRF_T2CON ) == 0 ) return; + // Is timer 2 counting PB6 negative transitions? + if((v->acr & ACRF_T2CON) == 0) return; // Was there a negative transition? - if( ( !lastpb6 ) || ( v->irb&0x40 ) ) return; + if((!lastpb6) || (v->irb&0x40)) return; // Count it v->t2c--; - if( v->t2run ) + if(v->t2run) { - if( v->t2c == 0 ) + if(v->t2c == 0) { - via_set_irq( v, VIRQF_T2 ); + via_set_irq(v, VIRQF_T2); v->t2run = SDL_FALSE; } } } // Init/Reset VIA -void via_init( struct via *v, struct machine *oric, int viatype ) +void via_init(struct via *v, struct machine *oric, int viatype) { v->orb = 0; v->ora = 0; @@ -379,7 +381,7 @@ void via_init( struct via *v, struct machine *oric, int viatype ) v->cb2pulse = SDL_FALSE; v->oric = oric; - switch( viatype ) + switch(viatype) { case VIA_MAIN: v->w_iorb = via_main_w_iorb; @@ -430,73 +432,73 @@ void via_init( struct via *v, struct machine *oric, int viatype ) } // Move timers on etc. -void via_clock( struct via *v, unsigned int cycles ) +void via_clock(struct via *v, unsigned int cycles) { unsigned int crem; // Move on the tape emulation - tape_ticktock( v->oric, cycles ); + tape_ticktock(v->oric, cycles); - if( !cycles ) return; + if(!cycles) return; // Simulate the feedback from the printer - if( v->oric->prclock > 0 ) + if(v->oric->prclock > 0) { v->oric->prclock -= cycles; - if( v->oric->prclock <= 0 ) + if(v->oric->prclock <= 0) { v->oric->prclock = 0; - if( v->oric->printenable ) - via_write_CA1( v, 0 ); + if(v->oric->printenable) + via_write_CA1(v, 0); } } // This is just a timer to close the // "printer_out.txt" filehandle if the // oric printer is idle for a while - if( v->oric->prclose > 0 ) + if(v->oric->prclose > 0) { v->oric->prclose -= cycles; - if( v->oric->prclose <= 0 ) + if(v->oric->prclose <= 0) { v->oric->prclose = 0; - if( v->oric->prf ) - fclose( v->oric->prf ); + if(v->oric->prf) + fclose(v->oric->prf); v->oric->prf = NULL; } } - if( v->ca2pulse ) + if(v->ca2pulse) { v->ca2 = 1; - if( v->ca2pulsed ) v->ca2pulsed( v ); + if(v->ca2pulsed) v->ca2pulsed(v); v->ca2pulse = SDL_FALSE; } - if( v->cb2pulse ) + if(v->cb2pulse) { -// if( (v->acr&ACRF_SRCON) == 0 ) + // if( (v->acr&ACRF_SRCON) == 0 ) { v->cb2 = 1; - if( v->cb2pulsed ) v->cb2pulsed( v ); + if(v->cb2pulsed) v->cb2pulsed(v); } v->cb2pulse = SDL_FALSE; } // Timer 1 tick-tock - switch( v->acr&ACRF_T1CON ) + switch(v->acr&ACRF_T1CON) { case 0x00: // One-shot, no output case 0x80: // One-shot, PB7 low while counting - if( v->t1run ) // Doing the one-shot still? + if(v->t1run) // Doing the one-shot still? { - if( cycles > v->t1c ) // Going to end the timer run? + if(cycles > v->t1c) // Going to end the timer run? { - via_set_irq( v, VIRQF_T1 ); - if( v->acr&0x80 ) + via_set_irq(v, VIRQF_T1); + if(v->acr&0x80) { v->orb |= 0x80; // PB7 high now that the timer has finished - if (v->orbchange) v->orbchange( v ); + if(v->orbchange) v->orbchange(v); } v->t1run = SDL_FALSE; } @@ -508,25 +510,25 @@ void via_clock( struct via *v, unsigned int cycles ) case 0xc0: // Continuous, output on PB7 crem = cycles; - if( v->t1reload ) + if(v->t1reload) { crem--; v->t1c = (v->t1l_h<<8)|v->t1l_l; // Reload timer v->t1reload = SDL_FALSE; } - while( crem > v->t1c ) + while(crem > v->t1c) { crem -= (v->t1c+1); // Clock down to 0xffff v->t1c = 0xffff; - via_set_irq( v, VIRQF_T1 ); - if( v->acr&0x80 ) + via_set_irq(v, VIRQF_T1); + if(v->acr&0x80) { v->orb ^= 0x80; // PB7 low now that the timer has finished - if( v->orbchange ) v->orbchange( v ); + if(v->orbchange) v->orbchange(v); } - if( !crem ) + if(!crem) { v->t1reload = SDL_TRUE; break; @@ -541,46 +543,46 @@ void via_clock( struct via *v, unsigned int cycles ) } // Timer 2 tick-tock - if( ( v->acr & ACRF_T2CON ) == 0 ) + if((v->acr & ACRF_T2CON) == 0) { - crem = cycles; - if( v->t2reload ) - { - crem--; - v->t2reload = 0; - } + crem = cycles; + if(v->t2reload) + { + crem--; + v->t2reload = 0; + } // Timer 2 is one-shot - if( v->t2run ) + if(v->t2run) { - if( crem > v->t2c ) + if(crem > v->t2c) { - via_set_irq( v, VIRQF_T2 ); + via_set_irq(v, VIRQF_T2); v->t2run = SDL_FALSE; } } v->t2c -= crem; } - switch( v->acr & ACRF_SRCON ) + switch(v->acr & ACRF_SRCON) { case 0x00: // Disabled case 0x04: // Shift in under T2 control (not implemented) case 0x08: // Shift in under O2 control (not implemented) case 0x0c: // Shift in under control of external clock (not implemented) case 0x1c: // Shift out under control of external clock (not implemented) - if( v->ifr&VIRQF_SR ) - via_clr_irq( v, VIRQF_SR ); + if(v->ifr&VIRQF_SR) + via_clr_irq(v, VIRQF_SR); v->srcount = 0; v->srtrigger = SDL_FALSE; break; case 0x10: // Shift out free-running at T2 rate - if( !v->srtrigger ) break; + if(!v->srtrigger) break; // Count down the SR timer v->srtime -= cycles; - while( v->srtime <= 0 ) + while(v->srtime <= 0) { // SR timer elapsed! Reload it v->srtime += v->t2l_l+1; @@ -589,11 +591,11 @@ void via_clock( struct via *v, unsigned int cycles ) v->cb1 ^= 1; // Need to change cb2? - if( !v->cb1 ) + if(!v->cb1) { v->cb2 = (v->sr & 0x80) ? 1 : 0; v->sr = (v->sr<<1)|v->cb2; - if( v->cb2shifted ) v->cb2shifted( v ); + if(v->cb2shifted) v->cb2shifted(v); v->srcount = (v->srcount+1)%8; } @@ -601,12 +603,12 @@ void via_clock( struct via *v, unsigned int cycles ) break; case 0x14: // Shift out under T2 control - if( !v->srtrigger ) break; - if( v->srcount == 8 ) break; + if(!v->srtrigger) break; + if(v->srcount == 8) break; // Count down the SR timer v->srtime -= cycles; - while( v->srtime <= 0 ) + while(v->srtime <= 0) { // SR timer elapsed! Reload it v->srtime += v->t2l_l+1; @@ -615,16 +617,16 @@ void via_clock( struct via *v, unsigned int cycles ) v->cb1 ^= 1; // Need to change cb2? - if( !v->cb1 ) + if(!v->cb1) { v->cb2 = (v->sr & 0x80) ? 1 : 0; v->sr = (v->sr<<1)|v->cb2; - if( v->cb2shifted ) v->cb2shifted( v ); + if(v->cb2shifted) v->cb2shifted(v); v->srcount++; - if( v->srcount == 8 ) + if(v->srcount == 8) { - via_set_irq( v, VIRQF_SR ); + via_set_irq(v, VIRQF_SR); v->srtime = 0; v->srtrigger = SDL_FALSE; break; @@ -634,23 +636,23 @@ void via_clock( struct via *v, unsigned int cycles ) break; case 0x18: // Shift out under O2 control - if( !v->srtrigger ) break; - if( v->srcount == 8 ) break; + if(!v->srtrigger) break; + if(v->srcount == 8) break; // Toggle the clock! v->cb1 ^= 1; // Need to change cb2? - if( !v->cb1 ) + if(!v->cb1) { v->cb2 = (v->sr & 0x80) ? 1 : 0; v->sr = (v->sr<<1)|v->cb2; - if( v->cb2shifted ) v->cb2shifted( v ); + if(v->cb2shifted) v->cb2shifted(v); v->srcount++; - if( v->srcount == 8 ) + if(v->srcount == 8) { - via_set_irq( v, VIRQF_SR ); + via_set_irq(v, VIRQF_SR); v->srtrigger = SDL_FALSE; } } @@ -659,43 +661,44 @@ void via_clock( struct via *v, unsigned int cycles ) } // Write VIA from CPU -void via_write( struct via *v, int offset, unsigned char data ) +void via_write(struct via *v, int offset, unsigned char data) { unsigned char tmp; offset &= 0xf; - switch( offset ) + switch(offset) { case VIA_IORB: tmp = v->orb; v->orb = data; - via_clr_irq( v, VIRQF_CB1 ); - switch( v->pcr & PCRF_CB2CON ) + via_clr_irq(v, VIRQF_CB1); + switch(v->pcr & PCRF_CB2CON) { case 0x00: case 0x40: - via_clr_irq( v, VIRQF_CB2 ); + via_clr_irq(v, VIRQF_CB2); break; case 0xa0: v->cb2pulse = SDL_TRUE; case 0x80: -// if( (v->acr&ACRF_SRCON) != 0 ) - v->cb2 = 0; + // if( (v->acr&ACRF_SRCON) != 0 ) + v->cb2 = 0; break; } - if( v->w_iorb ) v->w_iorb( v, tmp ); - if( v->orbchange ) v->orbchange( v ); + if(v->w_iorb) v->w_iorb(v, tmp); + if(v->orbchange) v->orbchange(v); + ay_soundloop(&v->oric->ay, tmp, data); break; case VIA_IORA: v->ora = data; - via_clr_irq( v, VIRQF_CA1 ); - switch( v->pcr & PCRF_CA2CON ) + via_clr_irq(v, VIRQF_CA1); + switch(v->pcr & PCRF_CA2CON) { case 0x00: case 0x04: - via_clr_irq( v, VIRQF_CA2 ); + via_clr_irq(v, VIRQF_CA2); break; case 0x0a: @@ -704,26 +707,26 @@ void via_write( struct via *v, int offset, unsigned char data ) v->ca2 = 0; break; } - if( v->w_iora ) v->w_iora( v ); + if(v->w_iora) v->w_iora(v); break; case VIA_DDRB: v->ddrb = data; - if( v->w_ddrb ) v->w_ddrb( v ); + if(v->w_ddrb) v->w_ddrb(v); break; case VIA_DDRA: v->ddra = data; - if( v->w_ddra ) v->w_ddra( v ); + if(v->w_ddra) v->w_ddra(v); break; case VIA_T1C_H: v->t1l_h = data; v->t1c = (v->t1l_h<<8)|v->t1l_l; v->t1reload = 1; - via_clr_irq( v, VIRQF_T1 ); + via_clr_irq(v, VIRQF_T1); v->t1run = SDL_TRUE; - if( (v->acr&ACRF_T1CON) == 0x80 ) + if((v->acr&ACRF_T1CON) == 0x80) { v->orb &= 0x7f; - if( v->orbchange ) v->orbchange( v ); + if(v->orbchange) v->orbchange(v); } break; case VIA_T1C_L: @@ -732,7 +735,7 @@ void via_write( struct via *v, int offset, unsigned char data ) break; case VIA_T1L_H: v->t1l_h = data; - via_clr_irq( v, VIRQF_T1 ); + via_clr_irq(v, VIRQF_T1); break; case VIA_T2C_L: v->t2l_l = data; @@ -740,8 +743,8 @@ void via_write( struct via *v, int offset, unsigned char data ) case VIA_T2C_H: v->t2l_h = data; v->t2c = (v->t2l_h<<8)|v->t2l_l; - v->t2reload = 1; - via_clr_irq( v, VIRQF_T2 ); + v->t2reload = 1; + via_clr_irq(v, VIRQF_T2); v->t2run = SDL_TRUE; break; case VIA_SR: @@ -749,31 +752,31 @@ void via_write( struct via *v, int offset, unsigned char data ) v->srcount = 0; v->srtime = 0; v->srtrigger = SDL_TRUE; - via_clr_irq( v, VIRQF_SR ); + via_clr_irq(v, VIRQF_SR); break; case VIA_ACR: // Disabling SR? -/* - if( ( (v->acr&ACRF_SRCON) != 0 ) && - ( (data&ACRF_SRCON) == 0 ) ) - { - switch( v->pcr & PCRF_CB2CON ) - { - case 0xc0: - v->cb2 = 0; - v->cb2pulse = SDL_FALSE; - break; - - case 0xe0: - v->cb2 = 1; - break; - } - ay_set_bcmode( &v->oric->ay, v->ca2, v->cb2 ); - } -*/ + /* + if( ( (v->acr&ACRF_SRCON) != 0 ) && + ( (data&ACRF_SRCON) == 0 ) ) + { + switch( v->pcr & PCRF_CB2CON ) + { + case 0xc0: + v->cb2 = 0; + v->cb2pulse = SDL_FALSE; + break; + + case 0xe0: + v->cb2 = 1; + break; + } + ay_set_bcmode( &v->oric->ay, v->ca2, v->cb2 ); + } + */ v->acr = data; - if( ( ( data & ACRF_T1CON ) != 0x40 ) && - ( ( data & ACRF_T1CON ) != 0xc0 ) ) + if(((data & ACRF_T1CON) != 0x40) && + ((data & ACRF_T1CON) != 0xc0)) v->t1reload = SDL_FALSE; break; case 0x40: // Continuous, no output @@ -781,7 +784,7 @@ void via_write( struct via *v, int offset, unsigned char data ) break; case VIA_PCR: v->pcr = data; - switch( v->pcr & PCRF_CA2CON ) + switch(v->pcr & PCRF_CA2CON) { case 0x0c: v->ca2 = 0; @@ -793,9 +796,9 @@ void via_write( struct via *v, int offset, unsigned char data ) break; } -// if( (v->acr&ACRF_SRCON) == 0 ) + // if( (v->acr&ACRF_SRCON) == 0 ) { - switch( v->pcr & PCRF_CB2CON ) + switch(v->pcr & PCRF_CB2CON) { case 0xc0: v->cb2 = 0; @@ -808,38 +811,38 @@ void via_write( struct via *v, int offset, unsigned char data ) } } - if( v->w_pcr ) v->w_pcr( v ); + if(v->w_pcr) v->w_pcr(v); break; case VIA_IFR: - if( data & VIRQF_CA1 ) v->iral = v->ira; - if( data & VIRQF_CB1 ) v->irbl = v->irb; + if(data & VIRQF_CA1) v->iral = v->ira; + if(data & VIRQF_CB1) v->irbl = v->irb; v->ifr &= (~data)&0x7f; - if( ( v->ier & v->ifr )&0x7f ) + if((v->ier & v->ifr)&0x7f) v->ifr |= 0x80; else v->oric->cpu.irq &= ~v->irqbit; break; case VIA_IER: - if( data & 0x80 ) + if(data & 0x80) v->ier |= (data&0x7f); else v->ier &= ~(data&0x7f); - via_check_irq( v ); + via_check_irq(v); break; case VIA_IORA2: v->ora = data; - if( v->w_iora2 ) v->w_iora2( v ); + if(v->w_iora2) v->w_iora2(v); break; } } // Read without side-effects for monitor -unsigned char via_mon_read( struct via *v, int offset ) +unsigned char via_mon_read(struct via *v, int offset) { offset &= 0xf; - switch( offset ) + switch(offset) { case VIA_IORB: return (v->orb&v->ddrb)|(v->irbl&(~v->ddrb)); @@ -879,39 +882,39 @@ unsigned char via_mon_read( struct via *v, int offset ) } // Read VIA from CPU -unsigned char via_read( struct via *v, int offset ) +unsigned char via_read(struct via *v, int offset) { offset &= 0xf; - switch( offset ) + switch(offset) { case VIA_IORB: - via_clr_irq( v, VIRQF_CB1 ); - switch( v->pcr & PCRF_CB2CON ) + via_clr_irq(v, VIRQF_CB1); + switch(v->pcr & PCRF_CB2CON) { case 0x00: case 0x40: - via_clr_irq( v, VIRQF_CB2 ); + via_clr_irq(v, VIRQF_CB2); break; case 0xa0: v->cb2pulse = SDL_TRUE; case 0x80: -// if( (v->acr&ACRF_SRCON) == 0 ) + // if( (v->acr&ACRF_SRCON) == 0 ) { v->cb2 = 0; } break; } - if( v->r_iorb ) v->r_iorb( v ); + if(v->r_iorb) v->r_iorb(v); return (v->orb&v->ddrb)|(v->irbl&(~v->ddrb)); case VIA_IORA: - via_clr_irq( v, VIRQF_CA1 ); - switch( v->pcr & PCRF_CA2CON ) + via_clr_irq(v, VIRQF_CA1); + switch(v->pcr & PCRF_CA2CON) { case 0x00: case 0x04: - via_clr_irq( v, VIRQF_CA2 ); + via_clr_irq(v, VIRQF_CA2); break; case 0x0a: @@ -920,14 +923,14 @@ unsigned char via_read( struct via *v, int offset ) v->ca2 = 0; break; } - if( v->r_iora ) v->r_iora( v ); + if(v->r_iora) v->r_iora(v); return (v->ora&v->ddra)|(v->iral&(~v->ddra)); case VIA_DDRB: return v->ddrb; case VIA_DDRA: return v->ddra; case VIA_T1C_L: - via_clr_irq( v, VIRQF_T1 ); + via_clr_irq(v, VIRQF_T1); return v->t1c&0xff; case VIA_T1C_H: return v->t1c>>8; @@ -936,7 +939,7 @@ unsigned char via_read( struct via *v, int offset ) case VIA_T1L_H: return v->t1l_h; case VIA_T2C_L: - via_clr_irq( v, VIRQF_T2 ); + via_clr_irq(v, VIRQF_T2); return v->t2c&0xff; case VIA_T2C_H: return v->t2c>>8; @@ -944,7 +947,7 @@ unsigned char via_read( struct via *v, int offset ) v->srcount = 0; v->srtime = 0; v->srtrigger = SDL_TRUE; - via_clr_irq( v, VIRQF_SR ); + via_clr_irq(v, VIRQF_SR); return v->sr; case VIA_ACR: return v->acr; @@ -962,89 +965,93 @@ unsigned char via_read( struct via *v, int offset ) } // For the monitor -void via_mon_write_ifr( struct via *v, unsigned char data ) +void via_mon_write_ifr(struct via *v, unsigned char data) { - if( !( data & VIRQF_CA1 ) ) v->iral = v->ira; - if( !( data & VIRQF_CB1 ) ) v->irbl = v->irb; + if(!(data & VIRQF_CA1)) v->iral = v->ira; + if(!(data & VIRQF_CB1)) v->irbl = v->irb; v->ifr = data&0x7f; - if( ( v->ier & v->ifr )&0x7f ) + if((v->ier & v->ifr)&0x7f) v->ifr |= 0x80; else v->oric->cpu.irq &= ~v->irqbit; } // Write CA1,CA2,CB1,CB2 from external device -void via_write_CA1( struct via *v, unsigned char data ) +void via_write_CA1(struct via *v, unsigned char data) { - if( ( !v->ca1 ) && ( data != 0 ) ) // Positive transition? + if((!v->ca1) && (data != 0)) // Positive transition? + { + if(v->pcr & PCRF_CA1CON) + via_set_irq(v, VIRQF_CA1); + } + else if((v->ca1) && (data == 0)) // Negative transition? { - if( v->pcr & PCRF_CA1CON ) - via_set_irq( v, VIRQF_CA1 ); - } else if( ( v->ca1 ) && ( data == 0 ) ) { // Negative transition? - if( !(v->pcr & PCRF_CA1CON) ) - via_set_irq( v, VIRQF_CA1 ); + if(!(v->pcr & PCRF_CA1CON)) + via_set_irq(v, VIRQF_CA1); } v->ca1 = data != 0; } -void via_write_CA2( struct via *v, unsigned char data ) +void via_write_CA2(struct via *v, unsigned char data) { - switch( v->pcr & PCRF_CA2CON ) + switch(v->pcr & PCRF_CA2CON) { - case 0x00: // Interrupt on negative transision - case 0x02: // Independant negative transition - if( ( v->ca2 ) && ( data == 0 ) ) - via_set_irq( v, VIRQF_CA2 ); + case 0x00: // Interrupt on negative transition + case 0x02: // Independent negative transition + if((v->ca2) && (data == 0)) + via_set_irq(v, VIRQF_CA2); v->ca2 = data != 0; break; case 0x04: // Interrupt on positive transition - case 0x06: // Independant positive transition - if( ( !v->ca2 ) && ( data != 0 ) ) - via_set_irq( v, VIRQF_CA2 ); + case 0x06: // Independent positive transition + if((!v->ca2) && (data != 0)) + via_set_irq(v, VIRQF_CA2); v->ca2 = data != 0; break; - // 0x08, 0x0a, 0x0c, 0x0e: output modes. Nothing to do :) + // 0x08, 0x0a, 0x0c, 0x0e: output modes. Nothing to do :) } - if( v->w_ca2ext ) v->w_ca2ext( v ); + if(v->w_ca2ext) v->w_ca2ext(v); } -void via_write_CB1( struct via *v, unsigned char data ) +void via_write_CB1(struct via *v, unsigned char data) { - if( ( !v->cb1 ) && ( data != 0 ) ) // Positive transition? + if((!v->cb1) && (data != 0)) // Positive transition? + { + if(v->pcr & PCRF_CB1CON) + via_set_irq(v, VIRQF_CB1); + } + else if((v->cb1) && (data == 0)) // Negative transition? { - if( v->pcr & PCRF_CB1CON ) - via_set_irq( v, VIRQF_CB1 ); - } else if( ( v->cb1 ) && ( data == 0 ) ) { // Negative transition? - if( !(v->pcr & PCRF_CB1CON) ) - via_set_irq( v, VIRQF_CB1 ); + if(!(v->pcr & PCRF_CB1CON)) + via_set_irq(v, VIRQF_CB1); } v->cb1 = data != 0; } -void via_write_CB2( struct via *v, unsigned char data ) +void via_write_CB2(struct via *v, unsigned char data) { - switch( v->pcr & PCRF_CB2CON ) + switch(v->pcr & PCRF_CB2CON) { case 0x00: case 0x20: - if( ( v->cb2 ) && ( data == 0 ) ) - via_set_irq( v, VIRQF_CB2 ); + if((v->cb2) && (data == 0)) + via_set_irq(v, VIRQF_CB2); v->cb2 = data != 0; break; case 0x40: case 0x60: - if( ( !v->cb2 ) && ( data != 0 ) ) - via_set_irq( v, VIRQF_CB2 ); + if((!v->cb2) && (data != 0)) + via_set_irq(v, VIRQF_CB2); v->cb2 = data != 0; break; } - if( v->w_cb2ext ) v->w_cb2ext( v ); + if(v->w_cb2ext) v->w_cb2ext(v); } diff --git a/via.h b/via.h index 1fffead1..b23d5a71 100644 --- a/via.h +++ b/via.h @@ -36,7 +36,7 @@ struct via unsigned char t1l_h; unsigned short t1c; unsigned char t2l_l; - unsigned char t2l_h; + unsigned char t2l_h; unsigned short t2c; unsigned char sr; unsigned char acr; @@ -128,32 +128,32 @@ struct via #define VIRQB_T1 6 #define VIRQF_T1 (1<1){thisProgram=process["argv"][1].replace(/\\/g,"/")}arguments_=process["argv"].slice(2);if(typeof module!=="undefined"){module["exports"]=Module}process["on"]("uncaughtException",function(ex){if(!(ex instanceof ExitStatus)){throw ex}});process["on"]("unhandledRejection",abort);quit_=function(status){process["exit"](status)};Module["inspect"]=function(){return"[Emscripten Module object]"}}else if(ENVIRONMENT_IS_SHELL){if(typeof read!="undefined"){read_=function shell_read(f){return read(f)}}readBinary=function readBinary(f){var data;if(typeof readbuffer==="function"){return new Uint8Array(readbuffer(f))}data=read(f,"binary");assert(typeof data==="object");return data};if(typeof scriptArgs!="undefined"){arguments_=scriptArgs}else if(typeof arguments!="undefined"){arguments_=arguments}if(typeof quit==="function"){quit_=function(status){quit(status)}}if(typeof print!=="undefined"){if(typeof console==="undefined")console={};console.log=print;console.warn=console.error=typeof printErr!=="undefined"?printErr:print}}else if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){if(ENVIRONMENT_IS_WORKER){scriptDirectory=self.location.href}else if(typeof document!=="undefined"&&document.currentScript){scriptDirectory=document.currentScript.src}if(scriptDirectory.indexOf("blob:")!==0){scriptDirectory=scriptDirectory.substr(0,scriptDirectory.lastIndexOf("/")+1)}else{scriptDirectory=""}{read_=function shell_read(url){var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.send(null);return xhr.responseText};if(ENVIRONMENT_IS_WORKER){readBinary=function readBinary(url){var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.responseType="arraybuffer";xhr.send(null);return new Uint8Array(xhr.response)}}readAsync=function readAsync(url,onload,onerror){var xhr=new XMLHttpRequest;xhr.open("GET",url,true);xhr.responseType="arraybuffer";xhr.onload=function xhr_onload(){if(xhr.status==200||xhr.status==0&&xhr.response){onload(xhr.response);return}onerror()};xhr.onerror=onerror;xhr.send(null)}}setWindowTitle=function(title){document.title=title}}else{}var out=Module["print"]||console.log.bind(console);var err=Module["printErr"]||console.warn.bind(console);for(key in moduleOverrides){if(moduleOverrides.hasOwnProperty(key)){Module[key]=moduleOverrides[key]}}moduleOverrides=null;if(Module["arguments"])arguments_=Module["arguments"];if(Module["thisProgram"])thisProgram=Module["thisProgram"];if(Module["quit"])quit_=Module["quit"];var STACK_ALIGN=16;function alignMemory(size,factor){if(!factor)factor=STACK_ALIGN;return Math.ceil(size/factor)*factor}function warnOnce(text){if(!warnOnce.shown)warnOnce.shown={};if(!warnOnce.shown[text]){warnOnce.shown[text]=1;err(text)}}var tempRet0=0;var setTempRet0=function(value){tempRet0=value};var wasmBinary;if(Module["wasmBinary"])wasmBinary=Module["wasmBinary"];var noExitRuntime;if(Module["noExitRuntime"])noExitRuntime=Module["noExitRuntime"];if(typeof WebAssembly!=="object"){abort("no native wasm support detected")}function setValue(ptr,value,type,noSafe){type=type||"i8";if(type.charAt(type.length-1)==="*")type="i32";switch(type){case"i1":HEAP8[ptr>>0]=value;break;case"i8":HEAP8[ptr>>0]=value;break;case"i16":HEAP16[ptr>>1]=value;break;case"i32":HEAP32[ptr>>2]=value;break;case"i64":tempI64=[value>>>0,(tempDouble=value,+Math.abs(tempDouble)>=1?tempDouble>0?(Math.min(+Math.floor(tempDouble/4294967296),4294967295)|0)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[ptr>>2]=tempI64[0],HEAP32[ptr+4>>2]=tempI64[1];break;case"float":HEAPF32[ptr>>2]=value;break;case"double":HEAPF64[ptr>>3]=value;break;default:abort("invalid type for setValue: "+type)}}var wasmMemory;var ABORT=false;var EXITSTATUS=0;function assert(condition,text){if(!condition){abort("Assertion failed: "+text)}}function getCFunc(ident){var func=Module["_"+ident];assert(func,"Cannot call unknown function "+ident+", make sure it is exported");return func}function ccall(ident,returnType,argTypes,args,opts){var toC={"string":function(str){var ret=0;if(str!==null&&str!==undefined&&str!==0){var len=(str.length<<2)+1;ret=stackAlloc(len);stringToUTF8(str,ret,len)}return ret},"array":function(arr){var ret=stackAlloc(arr.length);writeArrayToMemory(arr,ret);return ret}};function convertReturnValue(ret){if(returnType==="string")return UTF8ToString(ret);if(returnType==="boolean")return Boolean(ret);return ret}var func=getCFunc(ident);var cArgs=[];var stack=0;if(args){for(var i=0;i0;if(runningAsync&&!prevRunningAsync){return new Promise(function(resolve){Asyncify.asyncFinalizers.push(function(ret){if(stack!==0)stackRestore(stack);resolve(convertReturnValue(ret))})})}ret=convertReturnValue(ret);if(stack!==0)stackRestore(stack);if(opts&&opts.async)return Promise.resolve(ret);return ret}var ALLOC_NORMAL=0;var ALLOC_STACK=1;function allocate(slab,allocator){var ret;if(allocator==ALLOC_STACK){ret=stackAlloc(slab.length)}else{ret=_malloc(slab.length)}if(slab.subarray||slab.slice){HEAPU8.set(slab,ret)}else{HEAPU8.set(new Uint8Array(slab),ret)}return ret}var UTF8Decoder=typeof TextDecoder!=="undefined"?new TextDecoder("utf8"):undefined;function UTF8ArrayToString(heap,idx,maxBytesToRead){var endIdx=idx+maxBytesToRead;var endPtr=idx;while(heap[endPtr]&&!(endPtr>=endIdx))++endPtr;if(endPtr-idx>16&&heap.subarray&&UTF8Decoder){return UTF8Decoder.decode(heap.subarray(idx,endPtr))}else{var str="";while(idx>10,56320|ch&1023)}}}return str}function UTF8ToString(ptr,maxBytesToRead){return ptr?UTF8ArrayToString(HEAPU8,ptr,maxBytesToRead):""}function stringToUTF8Array(str,heap,outIdx,maxBytesToWrite){if(!(maxBytesToWrite>0))return 0;var startIdx=outIdx;var endIdx=outIdx+maxBytesToWrite-1;for(var i=0;i=55296&&u<=57343){var u1=str.charCodeAt(++i);u=65536+((u&1023)<<10)|u1&1023}if(u<=127){if(outIdx>=endIdx)break;heap[outIdx++]=u}else if(u<=2047){if(outIdx+1>=endIdx)break;heap[outIdx++]=192|u>>6;heap[outIdx++]=128|u&63}else if(u<=65535){if(outIdx+2>=endIdx)break;heap[outIdx++]=224|u>>12;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}else{if(outIdx+3>=endIdx)break;heap[outIdx++]=240|u>>18;heap[outIdx++]=128|u>>12&63;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}}heap[outIdx]=0;return outIdx-startIdx}function stringToUTF8(str,outPtr,maxBytesToWrite){return stringToUTF8Array(str,HEAPU8,outPtr,maxBytesToWrite)}function lengthBytesUTF8(str){var len=0;for(var i=0;i=55296&&u<=57343)u=65536+((u&1023)<<10)|str.charCodeAt(++i)&1023;if(u<=127)++len;else if(u<=2047)len+=2;else if(u<=65535)len+=3;else len+=4}return len}function allocateUTF8(str){var size=lengthBytesUTF8(str)+1;var ret=_malloc(size);if(ret)stringToUTF8Array(str,HEAP8,ret,size);return ret}function allocateUTF8OnStack(str){var size=lengthBytesUTF8(str)+1;var ret=stackAlloc(size);stringToUTF8Array(str,HEAP8,ret,size);return ret}function writeArrayToMemory(array,buffer){HEAP8.set(array,buffer)}function writeAsciiToMemory(str,buffer,dontAddNull){for(var i=0;i>0]=str.charCodeAt(i)}if(!dontAddNull)HEAP8[buffer>>0]=0}var WASM_PAGE_SIZE=65536;var buffer,HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;function updateGlobalBufferAndViews(buf){buffer=buf;Module["HEAP8"]=HEAP8=new Int8Array(buf);Module["HEAP16"]=HEAP16=new Int16Array(buf);Module["HEAP32"]=HEAP32=new Int32Array(buf);Module["HEAPU8"]=HEAPU8=new Uint8Array(buf);Module["HEAPU16"]=HEAPU16=new Uint16Array(buf);Module["HEAPU32"]=HEAPU32=new Uint32Array(buf);Module["HEAPF32"]=HEAPF32=new Float32Array(buf);Module["HEAPF64"]=HEAPF64=new Float64Array(buf)}var INITIAL_INITIAL_MEMORY=Module["INITIAL_MEMORY"]||268435456;if(Module["wasmMemory"]){wasmMemory=Module["wasmMemory"]}else{wasmMemory=new WebAssembly.Memory({"initial":INITIAL_INITIAL_MEMORY/WASM_PAGE_SIZE,"maximum":INITIAL_INITIAL_MEMORY/WASM_PAGE_SIZE})}if(wasmMemory){buffer=wasmMemory.buffer}INITIAL_INITIAL_MEMORY=buffer.byteLength;updateGlobalBufferAndViews(buffer);var wasmTable;var __ATPRERUN__=[];var __ATINIT__=[];var __ATMAIN__=[];var __ATEXIT__=[];var __ATPOSTRUN__=[];var runtimeInitialized=false;var runtimeExited=false;function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="function")Module["preRun"]=[Module["preRun"]];while(Module["preRun"].length){addOnPreRun(Module["preRun"].shift())}}callRuntimeCallbacks(__ATPRERUN__)}function initRuntime(){runtimeInitialized=true;if(!Module["noFSInit"]&&!FS.init.initialized)FS.init();TTY.init();callRuntimeCallbacks(__ATINIT__)}function preMain(){FS.ignorePermissions=false;callRuntimeCallbacks(__ATMAIN__)}function exitRuntime(){runtimeExited=true}function postRun(){if(Module["postRun"]){if(typeof Module["postRun"]=="function")Module["postRun"]=[Module["postRun"]];while(Module["postRun"].length){addOnPostRun(Module["postRun"].shift())}}callRuntimeCallbacks(__ATPOSTRUN__)}function addOnPreRun(cb){__ATPRERUN__.unshift(cb)}function addOnPostRun(cb){__ATPOSTRUN__.unshift(cb)}var runDependencies=0;var runDependencyWatcher=null;var dependenciesFulfilled=null;function getUniqueRunDependency(id){return id}function addRunDependency(id){runDependencies++;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}}function removeRunDependency(id){runDependencies--;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}if(runDependencies==0){if(runDependencyWatcher!==null){clearInterval(runDependencyWatcher);runDependencyWatcher=null}if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback()}}}Module["preloadedImages"]={};Module["preloadedAudios"]={};function abort(what){if(Module["onAbort"]){Module["onAbort"](what)}what+="";err(what);ABORT=true;EXITSTATUS=1;what="abort("+what+"). Build with -s ASSERTIONS=1 for more info.";var e=new WebAssembly.RuntimeError(what);throw e}function hasPrefix(str,prefix){return String.prototype.startsWith?str.startsWith(prefix):str.indexOf(prefix)===0}var dataURIPrefix="data:application/octet-stream;base64,";function isDataURI(filename){return hasPrefix(filename,dataURIPrefix)}var fileURIPrefix="file://";function isFileURI(filename){return hasPrefix(filename,fileURIPrefix)}var wasmBinaryFile="Oricutron.wasm";if(!isDataURI(wasmBinaryFile)){wasmBinaryFile=locateFile(wasmBinaryFile)}function getBinary(){try{if(wasmBinary){return new Uint8Array(wasmBinary)}if(readBinary){return readBinary(wasmBinaryFile)}else{throw"both async and sync fetching of the wasm failed"}}catch(err){abort(err)}}function getBinaryPromise(){if(!wasmBinary&&(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER)&&typeof fetch==="function"&&!isFileURI(wasmBinaryFile)){return fetch(wasmBinaryFile,{credentials:"same-origin"}).then(function(response){if(!response["ok"]){throw"failed to load wasm binary file at '"+wasmBinaryFile+"'"}return response["arrayBuffer"]()}).catch(function(){return getBinary()})}return Promise.resolve().then(getBinary)}var wasmOffsetConverter;function WasmOffsetConverter(wasmBytes,wasmModule){var offset=8;var funcidx=0;this.offset_map={};this.func_starts=[];this.name_map={};this.import_functions=0;var buffer=wasmBytes;function unsignedLEB128(){var result=0;var shift=0;do{var byte=buffer[offset++];result+=(byte&127)<0){offset=unsignedLEB128()+offset;offset=unsignedLEB128()+offset;switch(buffer[offset++]){case 0:++funcidx;unsignedLEB128();break;case 1:++offset;skipLimits();break;case 2:skipLimits();break;case 3:offset+=2;break}}this.import_functions=funcidx;break;case 10:var count=unsignedLEB128();while(count-- >0){var size=unsignedLEB128();this.offset_map[funcidx++]=offset;this.func_starts.push(offset);offset+=size}break binary_parse}offset=end}var sections=WebAssembly.Module.customSections(wasmModule,"name");for(var i=0;i0){var index=unsignedLEB128();var length=unsignedLEB128();this.name_map[index]=UTF8ArrayToString(buffer,offset,length);offset+=length}}}WasmOffsetConverter.prototype.convert=function(funcidx,offset){return this.offset_map[funcidx]+offset};WasmOffsetConverter.prototype.getIndex=function(offset){var lo=0;var hi=this.func_starts.length;var mid;while(looffset){hi=mid}else{lo=mid+1}}return lo+this.import_functions-1};WasmOffsetConverter.prototype.isSameFunc=function(offset1,offset2){return this.getIndex(offset1)==this.getIndex(offset2)};WasmOffsetConverter.prototype.getName=function(offset){var index=this.getIndex(offset);return this.name_map[index]||"wasm-function["+index+"]"};function createWasm(){var info={"a":asmLibraryArg};function receiveInstance(instance,module){var exports=instance.exports;exports=Asyncify.instrumentWasmExports(exports);Module["asm"]=exports;wasmTable=Module["asm"]["Kd"];removeRunDependency("wasm-instantiate")}addRunDependency("wasm-instantiate");function receiveInstantiatedSource(output){receiveInstance(output["instance"])}addRunDependency("offset-converter");function instantiateArrayBuffer(receiver){return getBinaryPromise().then(function(binary){var result=WebAssembly.instantiate(binary,info);result.then(function(instance){wasmOffsetConverter=new WasmOffsetConverter(binary,instance.module);removeRunDependency("offset-converter")});return result}).then(receiver,function(reason){err("failed to asynchronously prepare wasm: "+reason);abort(reason)})}function instantiateAsync(){if(!wasmBinary&&typeof WebAssembly.instantiateStreaming==="function"&&!isDataURI(wasmBinaryFile)&&!isFileURI(wasmBinaryFile)&&typeof fetch==="function"){return fetch(wasmBinaryFile,{credentials:"same-origin"}).then(function(response){var result=WebAssembly.instantiateStreaming(response,info);Promise.all([response.clone().arrayBuffer(),result]).then(function(results){wasmOffsetConverter=new WasmOffsetConverter(new Uint8Array(results[0]),results[1].module);removeRunDependency("offset-converter")},function(reason){err("failed to initialize offset-converter: "+reason)});return result.then(receiveInstantiatedSource,function(reason){err("wasm streaming compile failed: "+reason);err("falling back to ArrayBuffer instantiation");return instantiateArrayBuffer(receiveInstantiatedSource)})})}else{return instantiateArrayBuffer(receiveInstantiatedSource)}}if(Module["instantiateWasm"]){try{var exports=Module["instantiateWasm"](info,receiveInstance);exports=Asyncify.instrumentWasmExports(exports);return exports}catch(e){err("Module.instantiateWasm callback failed with error: "+e);return false}}instantiateAsync();return{}}var tempDouble;var tempI64;var ASM_CONSTS={6825:function(){FS.syncfs(function(err){assert(!err)})},9553:function(){FS.syncfs(function(err){assert(!err)})},9731:function(){FS.mkdir("/readwritefs");FS.mount(IDBFS,{},"/readwritefs");FS.syncfs(true,function(err){assert(!err);ccall("www_async_dload","v")})},17593:function(){FS.syncfs(function(err){assert(!err)})},18598:function(){FS.syncfs(function(err){assert(!err)})},19482:function($0){var str=UTF8ToString($0)+"\n\n"+"Abort/Retry/Ignore/AlwaysIgnore? [ariA] :";var reply=window.prompt(str,"i");if(reply===null){reply="i"}return allocate(intArrayFromString(reply),"i8",ALLOC_NORMAL)},56780:function($0,$1,$2){var w=$0;var h=$1;var pixels=$2;if(!Module["SDL2"])Module["SDL2"]={};var SDL2=Module["SDL2"];if(SDL2.ctxCanvas!==Module["canvas"]){SDL2.ctx=Module["createContext"](Module["canvas"],false,true);SDL2.ctxCanvas=Module["canvas"]}if(SDL2.w!==w||SDL2.h!==h||SDL2.imageCtx!==SDL2.ctx){SDL2.image=SDL2.ctx.createImageData(w,h);SDL2.w=w;SDL2.h=h;SDL2.imageCtx=SDL2.ctx}var data=SDL2.image.data;var src=pixels>>2;var dst=0;var num;if(typeof CanvasPixelArray!=="undefined"&&data instanceof CanvasPixelArray){num=data.length;while(dst>8&255;data[dst+2]=val>>16&255;data[dst+3]=255;src++;dst+=4}}else{if(SDL2.data32Data!==data){SDL2.data32=new Int32Array(data.buffer);SDL2.data8=new Uint8Array(data.buffer)}var data32=SDL2.data32;num=data32.length;data32.set(HEAP32.subarray(src,src+num));var data8=SDL2.data8;var i=3;var j=i+4*num;if(num%8==0){while(i>2;var dst=0;var num;if(typeof CanvasPixelArray!=="undefined"&&data instanceof CanvasPixelArray){num=data.length;while(dst>8&255;data[dst+2]=val>>16&255;data[dst+3]=val>>24&255;src++;dst+=4}}else{var data32=new Int32Array(data.buffer);num=data32.length;data32.set(HEAP32.subarray(src,src+num))}ctx.putImageData(image,0,0);var url=hot_x===0&&hot_y===0?"url("+canvas.toDataURL()+"), auto":"url("+canvas.toDataURL()+") "+hot_x+" "+hot_y+", auto";var urlBuf=_malloc(url.length+1);stringToUTF8(url,urlBuf,url.length+1);return urlBuf},59248:function($0){if(Module["canvas"]){Module["canvas"].style["cursor"]=UTF8ToString($0)}return 0},59341:function(){if(Module["canvas"]){Module["canvas"].style["cursor"]="none"}},60566:function(){return screen.width},60593:function(){return screen.height},60621:function(){return window.innerWidth},60653:function(){return window.innerHeight},60731:function($0){if(typeof setWindowTitle!=="undefined"){setWindowTitle(UTF8ToString($0))}return 0},60865:function(){if(typeof AudioContext!=="undefined"){return 1}else if(typeof webkitAudioContext!=="undefined"){return 1}return 0},61031:function(){if(typeof navigator.mediaDevices!=="undefined"&&typeof navigator.mediaDevices.getUserMedia!=="undefined"){return 1}else if(typeof navigator.webkitGetUserMedia!=="undefined"){return 1}return 0},61257:function($0){if(typeof Module["SDL2"]==="undefined"){Module["SDL2"]={}}var SDL2=Module["SDL2"];if(!$0){SDL2.audio={}}else{SDL2.capture={}}if(!SDL2.audioContext){if(typeof AudioContext!=="undefined"){SDL2.audioContext=new AudioContext}else if(typeof webkitAudioContext!=="undefined"){SDL2.audioContext=new webkitAudioContext}if(SDL2.audioContext){autoResumeAudioContext(SDL2.audioContext)}}return SDL2.audioContext===undefined?-1:0},61810:function(){var SDL2=Module["SDL2"];return SDL2.audioContext.sampleRate},61880:function($0,$1,$2,$3){var SDL2=Module["SDL2"];var have_microphone=function(stream){if(SDL2.capture.silenceTimer!==undefined){clearTimeout(SDL2.capture.silenceTimer);SDL2.capture.silenceTimer=undefined}SDL2.capture.mediaStreamNode=SDL2.audioContext.createMediaStreamSource(stream);SDL2.capture.scriptProcessorNode=SDL2.audioContext.createScriptProcessor($1,$0,1);SDL2.capture.scriptProcessorNode.onaudioprocess=function(audioProcessingEvent){if(SDL2===undefined||SDL2.capture===undefined){return}audioProcessingEvent.outputBuffer.getChannelData(0).fill(0);SDL2.capture.currentCaptureBuffer=audioProcessingEvent.inputBuffer;dynCall("vi",$2,[$3])};SDL2.capture.mediaStreamNode.connect(SDL2.capture.scriptProcessorNode);SDL2.capture.scriptProcessorNode.connect(SDL2.audioContext.destination);SDL2.capture.stream=stream};var no_microphone=function(error){};SDL2.capture.silenceBuffer=SDL2.audioContext.createBuffer($0,$1,SDL2.audioContext.sampleRate);SDL2.capture.silenceBuffer.getChannelData(0).fill(0);var silence_callback=function(){SDL2.capture.currentCaptureBuffer=SDL2.capture.silenceBuffer;dynCall("vi",$2,[$3])};SDL2.capture.silenceTimer=setTimeout(silence_callback,$1/SDL2.audioContext.sampleRate*1e3);if(navigator.mediaDevices!==undefined&&navigator.mediaDevices.getUserMedia!==undefined){navigator.mediaDevices.getUserMedia({audio:true,video:false}).then(have_microphone).catch(no_microphone)}else if(navigator.webkitGetUserMedia!==undefined){navigator.webkitGetUserMedia({audio:true,video:false},have_microphone,no_microphone)}},63532:function($0,$1,$2,$3){var SDL2=Module["SDL2"];SDL2.audio.scriptProcessorNode=SDL2.audioContext["createScriptProcessor"]($1,0,$0);SDL2.audio.scriptProcessorNode["onaudioprocess"]=function(e){if(SDL2===undefined||SDL2.audio===undefined){return}SDL2.audio.currentOutputBuffer=e["outputBuffer"];dynCall("vi",$2,[$3])};SDL2.audio.scriptProcessorNode["connect"](SDL2.audioContext["destination"])},63942:function($0,$1){var SDL2=Module["SDL2"];var numChannels=SDL2.capture.currentCaptureBuffer.numberOfChannels;for(var c=0;c>2]}}},65027:function($0){var SDL2=Module["SDL2"];if($0){if(SDL2.capture.silenceTimer!==undefined){clearTimeout(SDL2.capture.silenceTimer)}if(SDL2.capture.stream!==undefined){var tracks=SDL2.capture.stream.getAudioTracks();for(var i=0;i0){var callback=callbacks.shift();if(typeof callback=="function"){callback(Module);continue}var func=callback.func;if(typeof func==="number"){if(callback.arg===undefined){getDynCaller("v",func)()}else{getDynCaller("vi",func)(callback.arg)}}else{func(callback.arg===undefined?null:callback.arg)}}}function demangle(func){return func}function demangleAll(text){var regex=/\b_Z[\w\d_]+/g;return text.replace(regex,function(x){var y=demangle(x);return x===y?x:y+" ["+x+"]"})}function dynCallLegacy(sig,ptr,args){if(args&&args.length){return Module["dynCall_"+sig].apply(null,[ptr].concat(args))}return Module["dynCall_"+sig].call(null,ptr)}function dynCall(sig,ptr,args){return dynCallLegacy(sig,ptr,args)}function getDynCaller(sig,ptr){var argCache=[];return function(){argCache.length=arguments.length;for(var i=0;i=0;i--){var last=parts[i];if(last==="."){parts.splice(i,1)}else if(last===".."){parts.splice(i,1);up++}else if(up){parts.splice(i,1);up--}}if(allowAboveRoot){for(;up;up--){parts.unshift("..")}}return parts},normalize:function(path){var isAbsolute=path.charAt(0)==="/",trailingSlash=path.substr(-1)==="/";path=PATH.normalizeArray(path.split("/").filter(function(p){return!!p}),!isAbsolute).join("/");if(!path&&!isAbsolute){path="."}if(path&&trailingSlash){path+="/"}return(isAbsolute?"/":"")+path},dirname:function(path){var result=PATH.splitPath(path),root=result[0],dir=result[1];if(!root&&!dir){return"."}if(dir){dir=dir.substr(0,dir.length-1)}return root+dir},basename:function(path){if(path==="/")return"/";path=PATH.normalize(path);path=path.replace(/\/$/,"");var lastSlash=path.lastIndexOf("/");if(lastSlash===-1)return path;return path.substr(lastSlash+1)},extname:function(path){return PATH.splitPath(path)[3]},join:function(){var paths=Array.prototype.slice.call(arguments,0);return PATH.normalize(paths.join("/"))},join2:function(l,r){return PATH.normalize(l+"/"+r)}};function setErrNo(value){HEAP32[___errno_location()>>2]=value;return value}function getRandomDevice(){if(typeof crypto==="object"&&typeof crypto["getRandomValues"]==="function"){var randomBuffer=new Uint8Array(1);return function(){crypto.getRandomValues(randomBuffer);return randomBuffer[0]}}else if(ENVIRONMENT_IS_NODE){try{var crypto_module=require("crypto");return function(){return crypto_module["randomBytes"](1)[0]}}catch(e){}}return function(){abort("randomDevice")}}var PATH_FS={resolve:function(){var resolvedPath="",resolvedAbsolute=false;for(var i=arguments.length-1;i>=-1&&!resolvedAbsolute;i--){var path=i>=0?arguments[i]:FS.cwd();if(typeof path!=="string"){throw new TypeError("Arguments to path.resolve must be strings")}else if(!path){return""}resolvedPath=path+"/"+resolvedPath;resolvedAbsolute=path.charAt(0)==="/"}resolvedPath=PATH.normalizeArray(resolvedPath.split("/").filter(function(p){return!!p}),!resolvedAbsolute).join("/");return(resolvedAbsolute?"/":"")+resolvedPath||"."},relative:function(from,to){from=PATH_FS.resolve(from).substr(1);to=PATH_FS.resolve(to).substr(1);function trim(arr){var start=0;for(;start=0;end--){if(arr[end]!=="")break}if(start>end)return[];return arr.slice(start,end-start+1)}var fromParts=trim(from.split("/"));var toParts=trim(to.split("/"));var length=Math.min(fromParts.length,toParts.length);var samePartsLength=length;for(var i=0;i0){result=buf.slice(0,bytesRead).toString("utf-8")}else{result=null}}else if(typeof window!="undefined"&&typeof window.prompt=="function"){result=window.prompt("Input: ");if(result!==null){result+="\n"}}else if(typeof readline=="function"){result=readline();if(result!==null){result+="\n"}}if(!result){return null}tty.input=intArrayFromString(result,true)}return tty.input.shift()},put_char:function(tty,val){if(val===null||val===10){out(UTF8ArrayToString(tty.output,0));tty.output=[]}else{if(val!=0)tty.output.push(val)}},flush:function(tty){if(tty.output&&tty.output.length>0){out(UTF8ArrayToString(tty.output,0));tty.output=[]}}},default_tty1_ops:{put_char:function(tty,val){if(val===null||val===10){err(UTF8ArrayToString(tty.output,0));tty.output=[]}else{if(val!=0)tty.output.push(val)}},flush:function(tty){if(tty.output&&tty.output.length>0){err(UTF8ArrayToString(tty.output,0));tty.output=[]}}}};function mmapAlloc(size){var alignedSize=alignMemory(size,16384);var ptr=_malloc(alignedSize);while(size=newCapacity)return;var CAPACITY_DOUBLING_MAX=1024*1024;newCapacity=Math.max(newCapacity,prevCapacity*(prevCapacity>>0);if(prevCapacity!=0)newCapacity=Math.max(newCapacity,256);var oldContents=node.contents;node.contents=new Uint8Array(newCapacity);if(node.usedBytes>0)node.contents.set(oldContents.subarray(0,node.usedBytes),0);return},resizeFileStorage:function(node,newSize){if(node.usedBytes==newSize)return;if(newSize==0){node.contents=null;node.usedBytes=0;return}if(!node.contents||node.contents.subarray){var oldContents=node.contents;node.contents=new Uint8Array(newSize);if(oldContents){node.contents.set(oldContents.subarray(0,Math.min(newSize,node.usedBytes)))}node.usedBytes=newSize;return}if(!node.contents)node.contents=[];if(node.contents.length>newSize)node.contents.length=newSize;else while(node.contents.length=stream.node.usedBytes)return 0;var size=Math.min(stream.node.usedBytes-position,length);if(size>8&&contents.subarray){buffer.set(contents.subarray(position,position+size),offset)}else{for(var i=0;i0||position+length8){throw new FS.ErrnoError(32)}var parts=PATH.normalizeArray(path.split("/").filter(function(p){return!!p}),false);var current=FS.root;var current_path="/";for(var i=0;i40){throw new FS.ErrnoError(32)}}}}return{path:current_path,node:current}},getPath:function(node){var path;while(true){if(FS.isRoot(node)){var mount=node.mount.mountpoint;if(!path)return mount;return mount[mount.length-1]!=="/"?mount+"/"+path:mount+path}path=path?node.name+"/"+path:node.name;node=node.parent}},hashName:function(parentid,name){var hash=0;for(var i=0;i>>0)%FS.nameTable.length},hashAddNode:function(node){var hash=FS.hashName(node.parent.id,node.name);node.name_next=FS.nameTable[hash];FS.nameTable[hash]=node},hashRemoveNode:function(node){var hash=FS.hashName(node.parent.id,node.name);if(FS.nameTable[hash]===node){FS.nameTable[hash]=node.name_next}else{var current=FS.nameTable[hash];while(current){if(current.name_next===node){current.name_next=node.name_next;break}current=current.name_next}}},lookupNode:function(parent,name){var errCode=FS.mayLookup(parent);if(errCode){throw new FS.ErrnoError(errCode,parent)}var hash=FS.hashName(parent.id,name);for(var node=FS.nameTable[hash];node;node=node.name_next){var nodeName=node.name;if(node.parent.id===parent.id&&nodeName===name){return node}}return FS.lookup(parent,name)},createNode:function(parent,name,mode,rdev){var node=new FS.FSNode(parent,name,mode,rdev);FS.hashAddNode(node);return node},destroyNode:function(node){FS.hashRemoveNode(node)},isRoot:function(node){return node===node.parent},isMountpoint:function(node){return!!node.mounted},isFile:function(mode){return(mode&61440)===32768},isDir:function(mode){return(mode&61440)===16384},isLink:function(mode){return(mode&61440)===40960},isChrdev:function(mode){return(mode&61440)===8192},isBlkdev:function(mode){return(mode&61440)===24576},isFIFO:function(mode){return(mode&61440)===4096},isSocket:function(mode){return(mode&49152)===49152},flagModes:{"r":0,"rs":1052672,"r+":2,"w":577,"wx":705,"xw":705,"w+":578,"wx+":706,"xw+":706,"a":1089,"ax":1217,"xa":1217,"a+":1090,"ax+":1218,"xa+":1218},modeStringToFlags:function(str){var flags=FS.flagModes[str];if(typeof flags==="undefined"){throw new Error("Unknown file open mode: "+str)}return flags},flagsToPermissionString:function(flag){var perms=["r","w","rw"][flag&3];if(flag&512){perms+="w"}return perms},nodePermissions:function(node,perms){if(FS.ignorePermissions){return 0}if(perms.indexOf("r")!==-1&&!(node.mode&292)){return 2}else if(perms.indexOf("w")!==-1&&!(node.mode&146)){return 2}else if(perms.indexOf("x")!==-1&&!(node.mode&73)){return 2}return 0},mayLookup:function(dir){var errCode=FS.nodePermissions(dir,"x");if(errCode)return errCode;if(!dir.node_ops.lookup)return 2;return 0},mayCreate:function(dir,name){try{var node=FS.lookupNode(dir,name);return 20}catch(e){}return FS.nodePermissions(dir,"wx")},mayDelete:function(dir,name,isdir){var node;try{node=FS.lookupNode(dir,name)}catch(e){return e.errno}var errCode=FS.nodePermissions(dir,"wx");if(errCode){return errCode}if(isdir){if(!FS.isDir(node.mode)){return 54}if(FS.isRoot(node)||FS.getPath(node)===FS.cwd()){return 10}}else{if(FS.isDir(node.mode)){return 31}}return 0},mayOpen:function(node,flags){if(!node){return 44}if(FS.isLink(node.mode)){return 32}else if(FS.isDir(node.mode)){if(FS.flagsToPermissionString(flags)!=="r"||flags&512){return 31}}return FS.nodePermissions(node,FS.flagsToPermissionString(flags))},MAX_OPEN_FDS:4096,nextfd:function(fd_start,fd_end){fd_start=fd_start||0;fd_end=fd_end||FS.MAX_OPEN_FDS;for(var fd=fd_start;fd<=fd_end;fd++){if(!FS.streams[fd]){return fd}}throw new FS.ErrnoError(33)},getStream:function(fd){return FS.streams[fd]},createStream:function(stream,fd_start,fd_end){if(!FS.FSStream){FS.FSStream=function(){};FS.FSStream.prototype={object:{get:function(){return this.node},set:function(val){this.node=val}},isRead:{get:function(){return(this.flags&2097155)!==1}},isWrite:{get:function(){return(this.flags&2097155)!==0}},isAppend:{get:function(){return this.flags&1024}}}}var newStream=new FS.FSStream;for(var p in stream){newStream[p]=stream[p]}stream=newStream;var fd=FS.nextfd(fd_start,fd_end);stream.fd=fd;FS.streams[fd]=stream;return stream},closeStream:function(fd){FS.streams[fd]=null},chrdev_stream_ops:{open:function(stream){var device=FS.getDevice(stream.node.rdev);stream.stream_ops=device.stream_ops;if(stream.stream_ops.open){stream.stream_ops.open(stream)}},llseek:function(){throw new FS.ErrnoError(70)}},major:function(dev){return dev>>8},minor:function(dev){return dev&255},makedev:function(ma,mi){return ma<<8|mi},registerDevice:function(dev,ops){FS.devices[dev]={stream_ops:ops}},getDevice:function(dev){return FS.devices[dev]},getMounts:function(mount){var mounts=[];var check=[mount];while(check.length){var m=check.pop();mounts.push(m);check.push.apply(check,m.mounts)}return mounts},syncfs:function(populate,callback){if(typeof populate==="function"){callback=populate;populate=false}FS.syncFSRequests++;if(FS.syncFSRequests>1){err("warning: "+FS.syncFSRequests+" FS.syncfs operations in flight at once, probably just doing extra work")}var mounts=FS.getMounts(FS.root.mount);var completed=0;function doCallback(errCode){FS.syncFSRequests--;return callback(errCode)}function done(errCode){if(errCode){if(!done.errored){done.errored=true;return doCallback(errCode)}return}if(++completed>=mounts.length){doCallback(null)}}mounts.forEach(function(mount){if(!mount.type.syncfs){return done(null)}mount.type.syncfs(mount,populate,done)})},mount:function(type,opts,mountpoint){var root=mountpoint==="/";var pseudo=!mountpoint;var node;if(root&&FS.root){throw new FS.ErrnoError(10)}else if(!root&&!pseudo){var lookup=FS.lookupPath(mountpoint,{follow_mount:false});mountpoint=lookup.path;node=lookup.node;if(FS.isMountpoint(node)){throw new FS.ErrnoError(10)}if(!FS.isDir(node.mode)){throw new FS.ErrnoError(54)}}var mount={type:type,opts:opts,mountpoint:mountpoint,mounts:[]};var mountRoot=type.mount(mount);mountRoot.mount=mount;mount.root=mountRoot;if(root){FS.root=mountRoot}else if(node){node.mounted=mount;if(node.mount){node.mount.mounts.push(mount)}}return mountRoot},unmount:function(mountpoint){var lookup=FS.lookupPath(mountpoint,{follow_mount:false});if(!FS.isMountpoint(lookup.node)){throw new FS.ErrnoError(28)}var node=lookup.node;var mount=node.mounted;var mounts=FS.getMounts(mount);Object.keys(FS.nameTable).forEach(function(hash){var current=FS.nameTable[hash];while(current){var next=current.name_next;if(mounts.indexOf(current.mount)!==-1){FS.destroyNode(current)}current=next}});node.mounted=null;var idx=node.mount.mounts.indexOf(mount);node.mount.mounts.splice(idx,1)},lookup:function(parent,name){return parent.node_ops.lookup(parent,name)},mknod:function(path,mode,dev){var lookup=FS.lookupPath(path,{parent:true});var parent=lookup.node;var name=PATH.basename(path);if(!name||name==="."||name===".."){throw new FS.ErrnoError(28)}var errCode=FS.mayCreate(parent,name);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.mknod){throw new FS.ErrnoError(63)}return parent.node_ops.mknod(parent,name,mode,dev)},create:function(path,mode){mode=mode!==undefined?mode:438;mode&=4095;mode|=32768;return FS.mknod(path,mode,0)},mkdir:function(path,mode){mode=mode!==undefined?mode:511;mode&=511|512;mode|=16384;return FS.mknod(path,mode,0)},mkdirTree:function(path,mode){var dirs=path.split("/");var d="";for(var i=0;ithis.length-1||idx<0){return undefined}var chunkOffset=idx%this.chunkSize;var chunkNum=idx/this.chunkSize|0;return this.getter(chunkNum)[chunkOffset]};LazyUint8Array.prototype.setDataGetter=function LazyUint8Array_setDataGetter(getter){this.getter=getter};LazyUint8Array.prototype.cacheLength=function LazyUint8Array_cacheLength(){var xhr=new XMLHttpRequest;xhr.open("HEAD",url,false);xhr.send(null);if(!(xhr.status>=200&&xhr.status<300||xhr.status===304))throw new Error("Couldn't load "+url+". Status: "+xhr.status);var datalength=Number(xhr.getResponseHeader("Content-length"));var header;var hasByteServing=(header=xhr.getResponseHeader("Accept-Ranges"))&&header==="bytes";var usesGzip=(header=xhr.getResponseHeader("Content-Encoding"))&&header==="gzip";var chunkSize=1024*1024;if(!hasByteServing)chunkSize=datalength;var doXHR=function(from,to){if(from>to)throw new Error("invalid range ("+from+", "+to+") or no bytes requested!");if(to>datalength-1)throw new Error("only "+datalength+" bytes available! programmer error!");var xhr=new XMLHttpRequest;xhr.open("GET",url,false);if(datalength!==chunkSize)xhr.setRequestHeader("Range","bytes="+from+"-"+to);if(typeof Uint8Array!="undefined")xhr.responseType="arraybuffer";if(xhr.overrideMimeType){xhr.overrideMimeType("text/plain; charset=x-user-defined")}xhr.send(null);if(!(xhr.status>=200&&xhr.status<300||xhr.status===304))throw new Error("Couldn't load "+url+". Status: "+xhr.status);if(xhr.response!==undefined){return new Uint8Array(xhr.response||[])}else{return intArrayFromString(xhr.responseText||"",true)}};var lazyArray=this;lazyArray.setDataGetter(function(chunkNum){var start=chunkNum*chunkSize;var end=(chunkNum+1)*chunkSize-1;end=Math.min(end,datalength-1);if(typeof lazyArray.chunks[chunkNum]==="undefined"){lazyArray.chunks[chunkNum]=doXHR(start,end)}if(typeof lazyArray.chunks[chunkNum]==="undefined")throw new Error("doXHR failed!");return lazyArray.chunks[chunkNum]});if(usesGzip||!datalength){chunkSize=datalength=1;datalength=this.getter(0).length;chunkSize=datalength;out("LazyFiles on gzip forces download of the whole file when length is accessed")}this._length=datalength;this._chunkSize=chunkSize;this.lengthKnown=true};if(typeof XMLHttpRequest!=="undefined"){if(!ENVIRONMENT_IS_WORKER)throw"Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc";var lazyArray=new LazyUint8Array;Object.defineProperties(lazyArray,{length:{get:function(){if(!this.lengthKnown){this.cacheLength()}return this._length}},chunkSize:{get:function(){if(!this.lengthKnown){this.cacheLength()}return this._chunkSize}}});var properties={isDevice:false,contents:lazyArray}}else{var properties={isDevice:false,url:url}}var node=FS.createFile(parent,name,properties,canRead,canWrite);if(properties.contents){node.contents=properties.contents}else if(properties.url){node.contents=null;node.url=properties.url}Object.defineProperties(node,{usedBytes:{get:function(){return this.contents.length}}});var stream_ops={};var keys=Object.keys(node.stream_ops);keys.forEach(function(key){var fn=node.stream_ops[key];stream_ops[key]=function forceLoadLazyFile(){if(!FS.forceLoadFile(node)){throw new FS.ErrnoError(29)}return fn.apply(null,arguments)}});stream_ops.read=function stream_ops_read(stream,buffer,offset,length,position){if(!FS.forceLoadFile(node)){throw new FS.ErrnoError(29)}var contents=stream.node.contents;if(position>=contents.length)return 0;var size=Math.min(contents.length-position,length);if(contents.slice){for(var i=0;i>2]=stat.dev;HEAP32[buf+4>>2]=0;HEAP32[buf+8>>2]=stat.ino;HEAP32[buf+12>>2]=stat.mode;HEAP32[buf+16>>2]=stat.nlink;HEAP32[buf+20>>2]=stat.uid;HEAP32[buf+24>>2]=stat.gid;HEAP32[buf+28>>2]=stat.rdev;HEAP32[buf+32>>2]=0;tempI64=[stat.size>>>0,(tempDouble=stat.size,+Math.abs(tempDouble)>=1?tempDouble>0?(Math.min(+Math.floor(tempDouble/4294967296),4294967295)|0)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[buf+40>>2]=tempI64[0],HEAP32[buf+44>>2]=tempI64[1];HEAP32[buf+48>>2]=4096;HEAP32[buf+52>>2]=stat.blocks;HEAP32[buf+56>>2]=stat.atime.getTime()/1e3|0;HEAP32[buf+60>>2]=0;HEAP32[buf+64>>2]=stat.mtime.getTime()/1e3|0;HEAP32[buf+68>>2]=0;HEAP32[buf+72>>2]=stat.ctime.getTime()/1e3|0;HEAP32[buf+76>>2]=0;tempI64=[stat.ino>>>0,(tempDouble=stat.ino,+Math.abs(tempDouble)>=1?tempDouble>0?(Math.min(+Math.floor(tempDouble/4294967296),4294967295)|0)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[buf+80>>2]=tempI64[0],HEAP32[buf+84>>2]=tempI64[1];return 0},doMsync:function(addr,stream,len,flags,offset){var buffer=HEAPU8.slice(addr,addr+len);FS.msync(stream,buffer,offset,len,flags)},doMkdir:function(path,mode){path=PATH.normalize(path);if(path[path.length-1]==="/")path=path.substr(0,path.length-1);FS.mkdir(path,mode,0);return 0},doMknod:function(path,mode,dev){switch(mode&61440){case 32768:case 8192:case 24576:case 4096:case 49152:break;default:return-28}FS.mknod(path,mode,dev);return 0},doReadlink:function(path,buf,bufsize){if(bufsize<=0)return-28;var ret=FS.readlink(path);var len=Math.min(bufsize,lengthBytesUTF8(ret));var endChar=HEAP8[buf+len];stringToUTF8(ret,buf,bufsize+1);HEAP8[buf+len]=endChar;return len},doAccess:function(path,amode){if(amode&~7){return-28}var node;var lookup=FS.lookupPath(path,{follow:true});node=lookup.node;if(!node){return-44}var perms="";if(amode&4)perms+="r";if(amode&2)perms+="w";if(amode&1)perms+="x";if(perms&&FS.nodePermissions(node,perms)){return-2}return 0},doDup:function(path,flags,suggestFD){var suggest=FS.getStream(suggestFD);if(suggest)FS.close(suggest);return FS.open(path,flags,0,suggestFD,suggestFD).fd},doReadv:function(stream,iov,iovcnt,offset){var ret=0;for(var i=0;i>2];var len=HEAP32[iov+(i*8+4)>>2];var curr=FS.read(stream,HEAP8,ptr,len,offset);if(curr<0)return-1;ret+=curr;if(curr>2];var len=HEAP32[iov+(i*8+4)>>2];var curr=FS.write(stream,HEAP8,ptr,len,offset);if(curr<0)return-1;ret+=curr}return ret},varargs:undefined,get:function(){SYSCALLS.varargs+=4;var ret=HEAP32[SYSCALLS.varargs-4>>2];return ret},getStr:function(ptr){var ret=UTF8ToString(ptr);return ret},getStreamFromFD:function(fd){var stream=FS.getStream(fd);if(!stream)throw new FS.ErrnoError(8);return stream},get64:function(low,high){return low}};function ___sys_chdir(path){try{path=SYSCALLS.getStr(path);FS.chdir(path);return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}function ___sys_fcntl64(fd,cmd,varargs){SYSCALLS.varargs=varargs;try{var stream=SYSCALLS.getStreamFromFD(fd);switch(cmd){case 0:{var arg=SYSCALLS.get();if(arg<0){return-28}var newStream;newStream=FS.open(stream.path,stream.flags,0,arg);return newStream.fd}case 1:case 2:return 0;case 3:return stream.flags;case 4:{var arg=SYSCALLS.get();stream.flags|=arg;return 0}case 12:{var arg=SYSCALLS.get();var offset=0;HEAP16[arg+offset>>1]=2;return 0}case 13:case 14:return 0;case 16:case 8:return-28;case 9:setErrNo(28);return-1;default:{return-28}}}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}function ___sys_fstat64(fd,buf){try{var stream=SYSCALLS.getStreamFromFD(fd);return SYSCALLS.doStat(FS.stat,stream.path,buf)}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}function ___sys_getcwd(buf,size){try{if(size===0)return-28;var cwd=FS.cwd();var cwdLengthInBytes=lengthBytesUTF8(cwd);if(size>>0,(tempDouble=id,+Math.abs(tempDouble)>=1?tempDouble>0?(Math.min(+Math.floor(tempDouble/4294967296),4294967295)|0)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[dirp+pos>>2]=tempI64[0],HEAP32[dirp+pos+4>>2]=tempI64[1];tempI64=[(idx+1)*struct_size>>>0,(tempDouble=(idx+1)*struct_size,+Math.abs(tempDouble)>=1?tempDouble>0?(Math.min(+Math.floor(tempDouble/4294967296),4294967295)|0)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[dirp+pos+8>>2]=tempI64[0],HEAP32[dirp+pos+12>>2]=tempI64[1];HEAP16[dirp+pos+16>>1]=280;HEAP8[dirp+pos+18>>0]=type;stringToUTF8(name,dirp+pos+19,256);pos+=struct_size;idx+=1}FS.llseek(stream,idx*struct_size,0);return pos}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}function ___sys_ioctl(fd,op,varargs){SYSCALLS.varargs=varargs;try{var stream=SYSCALLS.getStreamFromFD(fd);switch(op){case 21509:case 21505:{if(!stream.tty)return-59;return 0}case 21510:case 21511:case 21512:case 21506:case 21507:case 21508:{if(!stream.tty)return-59;return 0}case 21519:{if(!stream.tty)return-59;var argp=SYSCALLS.get();HEAP32[argp>>2]=0;return 0}case 21520:{if(!stream.tty)return-59;return-28}case 21531:{var argp=SYSCALLS.get();return FS.ioctl(stream,op,argp)}case 21523:{if(!stream.tty)return-59;return 0}case 21524:{if(!stream.tty)return-59;return 0}default:abort("bad ioctl syscall "+op)}}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}function ___sys_mkdir(path,mode){try{path=SYSCALLS.getStr(path);return SYSCALLS.doMkdir(path,mode)}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}function ___sys_open(path,flags,varargs){SYSCALLS.varargs=varargs;try{var pathname=SYSCALLS.getStr(path);var mode=SYSCALLS.get();var stream=FS.open(pathname,flags,mode);return stream.fd}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}function ___sys_readlink(path,buf,bufsize){try{path=SYSCALLS.getStr(path);return SYSCALLS.doReadlink(path,buf,bufsize)}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}function ___sys_rmdir(path){try{path=SYSCALLS.getStr(path);FS.rmdir(path);return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}function ___sys_stat64(path,buf){try{path=SYSCALLS.getStr(path);return SYSCALLS.doStat(FS.stat,path,buf)}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}function ___sys_statfs64(path,size,buf){try{path=SYSCALLS.getStr(path);HEAP32[buf+4>>2]=4096;HEAP32[buf+40>>2]=4096;HEAP32[buf+8>>2]=1e6;HEAP32[buf+12>>2]=5e5;HEAP32[buf+16>>2]=5e5;HEAP32[buf+20>>2]=FS.nextInode;HEAP32[buf+24>>2]=1e6;HEAP32[buf+28>>2]=42;HEAP32[buf+44>>2]=2;HEAP32[buf+36>>2]=255;return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}function ___sys_unlink(path){try{path=SYSCALLS.getStr(path);FS.unlink(path);return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}function __emscripten_fetch_free(id){delete Fetch.xhrs[id-1]}var _emscripten_get_now;if(ENVIRONMENT_IS_NODE){_emscripten_get_now=function(){var t=process["hrtime"]();return t[0]*1e3+t[1]/1e6}}else if(typeof dateNow!=="undefined"){_emscripten_get_now=dateNow}else _emscripten_get_now=function(){return performance.now()};var _emscripten_get_now_is_monotonic=true;function _clock_gettime(clk_id,tp){var now;if(clk_id===0){now=Date.now()}else if((clk_id===1||clk_id===4)&&_emscripten_get_now_is_monotonic){now=_emscripten_get_now()}else{setErrNo(28);return-1}HEAP32[tp>>2]=now/1e3|0;HEAP32[tp+4>>2]=now%1e3*1e3*1e3|0;return 0}function _dlclose(handle){abort("To use dlopen, you need to use Emscripten's linking support, see https://github.com/emscripten-core/emscripten/wiki/Linking")}function _emscripten_set_main_loop_timing(mode,value){Browser.mainLoop.timingMode=mode;Browser.mainLoop.timingValue=value;if(!Browser.mainLoop.func){return 1}if(mode==0){Browser.mainLoop.scheduler=function Browser_mainLoop_scheduler_setTimeout(){var timeUntilNextTick=Math.max(0,Browser.mainLoop.tickStartTime+value-_emscripten_get_now())|0;setTimeout(Browser.mainLoop.runner,timeUntilNextTick)};Browser.mainLoop.method="timeout"}else if(mode==1){Browser.mainLoop.scheduler=function Browser_mainLoop_scheduler_rAF(){Browser.requestAnimationFrame(Browser.mainLoop.runner)};Browser.mainLoop.method="rAF"}else if(mode==2){if(typeof setImmediate==="undefined"){var setImmediates=[];var emscriptenMainLoopMessageId="setimmediate";var Browser_setImmediate_messageHandler=function(event){if(event.data===emscriptenMainLoopMessageId||event.data.target===emscriptenMainLoopMessageId){event.stopPropagation();setImmediates.shift()()}};addEventListener("message",Browser_setImmediate_messageHandler,true);setImmediate=function Browser_emulated_setImmediate(func){setImmediates.push(func);if(ENVIRONMENT_IS_WORKER){if(Module["setImmediates"]===undefined)Module["setImmediates"]=[];Module["setImmediates"].push(func);postMessage({target:emscriptenMainLoopMessageId})}else postMessage(emscriptenMainLoopMessageId,"*")}}Browser.mainLoop.scheduler=function Browser_mainLoop_scheduler_setImmediate(){setImmediate(Browser.mainLoop.runner)};Browser.mainLoop.method="immediate"}return 0}function setMainLoop(browserIterationFunc,fps,simulateInfiniteLoop,arg,noSetTiming){noExitRuntime=true;assert(!Browser.mainLoop.func,"emscripten_set_main_loop: there can only be one main loop function at once: call emscripten_cancel_main_loop to cancel the previous one before setting a new one with different parameters.");Browser.mainLoop.func=browserIterationFunc;Browser.mainLoop.arg=arg;var thisMainLoopId=Browser.mainLoop.currentlyRunningMainloop;Browser.mainLoop.runner=function Browser_mainLoop_runner(){if(ABORT)return;if(Browser.mainLoop.queue.length>0){var start=Date.now();var blocker=Browser.mainLoop.queue.shift();blocker.func(blocker.arg);if(Browser.mainLoop.remainingBlockers){var remaining=Browser.mainLoop.remainingBlockers;var next=remaining%1==0?remaining-1:Math.floor(remaining);if(blocker.counted){Browser.mainLoop.remainingBlockers=next}else{next=next+.5;Browser.mainLoop.remainingBlockers=(8*remaining+next)/9}}console.log('main loop blocker "'+blocker.name+'" took '+(Date.now()-start)+" ms");Browser.mainLoop.updateStatus();if(thisMainLoopId1&&Browser.mainLoop.currentFrameNumber%Browser.mainLoop.timingValue!=0){Browser.mainLoop.scheduler();return}else if(Browser.mainLoop.timingMode==0){Browser.mainLoop.tickStartTime=_emscripten_get_now()}Browser.mainLoop.runIter(browserIterationFunc);if(thisMainLoopId0)_emscripten_set_main_loop_timing(0,1e3/fps);else _emscripten_set_main_loop_timing(1,1);Browser.mainLoop.scheduler()}if(simulateInfiniteLoop){throw"unwind"}}var Browser={mainLoop:{scheduler:null,method:"",currentlyRunningMainloop:0,func:null,arg:0,timingMode:0,timingValue:0,currentFrameNumber:0,queue:[],pause:function(){Browser.mainLoop.scheduler=null;Browser.mainLoop.currentlyRunningMainloop++},resume:function(){Browser.mainLoop.currentlyRunningMainloop++;var timingMode=Browser.mainLoop.timingMode;var timingValue=Browser.mainLoop.timingValue;var func=Browser.mainLoop.func;Browser.mainLoop.func=null;setMainLoop(func,0,false,Browser.mainLoop.arg,true);_emscripten_set_main_loop_timing(timingMode,timingValue);Browser.mainLoop.scheduler()},updateStatus:function(){if(Module["setStatus"]){var message=Module["statusMessage"]||"Please wait...";var remaining=Browser.mainLoop.remainingBlockers;var expected=Browser.mainLoop.expectedBlockers;if(remaining){if(remaining=6){var curr=leftchar>>leftbits-6&63;leftbits-=6;ret+=BASE[curr]}}if(leftbits==2){ret+=BASE[(leftchar&3)<<4];ret+=PAD+PAD}else if(leftbits==4){ret+=BASE[(leftchar&15)<<2];ret+=PAD}return ret}audio.src="data:audio/x-"+name.substr(-3)+";base64,"+encode64(byteArray);finish(audio)};audio.src=url;Browser.safeSetTimeout(function(){finish(audio)},1e4)}else{return fail()}};Module["preloadPlugins"].push(audioPlugin);function pointerLockChange(){Browser.pointerLock=document["pointerLockElement"]===Module["canvas"]||document["mozPointerLockElement"]===Module["canvas"]||document["webkitPointerLockElement"]===Module["canvas"]||document["msPointerLockElement"]===Module["canvas"]}var canvas=Module["canvas"];if(canvas){canvas.requestPointerLock=canvas["requestPointerLock"]||canvas["mozRequestPointerLock"]||canvas["webkitRequestPointerLock"]||canvas["msRequestPointerLock"]||function(){};canvas.exitPointerLock=document["exitPointerLock"]||document["mozExitPointerLock"]||document["webkitExitPointerLock"]||document["msExitPointerLock"]||function(){};canvas.exitPointerLock=canvas.exitPointerLock.bind(document);document.addEventListener("pointerlockchange",pointerLockChange,false);document.addEventListener("mozpointerlockchange",pointerLockChange,false);document.addEventListener("webkitpointerlockchange",pointerLockChange,false);document.addEventListener("mspointerlockchange",pointerLockChange,false);if(Module["elementPointerLock"]){canvas.addEventListener("click",function(ev){if(!Browser.pointerLock&&Module["canvas"].requestPointerLock){Module["canvas"].requestPointerLock();ev.preventDefault()}},false)}}},createContext:function(canvas,useWebGL,setInModule,webGLContextAttributes){if(useWebGL&&Module.ctx&&canvas==Module.canvas)return Module.ctx;var ctx;var contextHandle;if(useWebGL){var contextAttributes={antialias:false,alpha:false,majorVersion:1};if(webGLContextAttributes){for(var attribute in webGLContextAttributes){contextAttributes[attribute]=webGLContextAttributes[attribute]}}if(typeof GL!=="undefined"){contextHandle=GL.createContext(canvas,contextAttributes);if(contextHandle){ctx=GL.getContext(contextHandle).GLctx}}}else{ctx=canvas.getContext("2d")}if(!ctx)return null;if(setInModule){if(!useWebGL)assert(typeof GLctx==="undefined","cannot set in module if GLctx is used, but we are a non-GL context that would replace it");Module.ctx=ctx;if(useWebGL)GL.makeContextCurrent(contextHandle);Module.useWebGL=useWebGL;Browser.moduleContextCreatedCallbacks.forEach(function(callback){callback()});Browser.init()}return ctx},destroyContext:function(canvas,useWebGL,setInModule){},fullscreenHandlersInstalled:false,lockPointer:undefined,resizeCanvas:undefined,requestFullscreen:function(lockPointer,resizeCanvas){Browser.lockPointer=lockPointer;Browser.resizeCanvas=resizeCanvas;if(typeof Browser.lockPointer==="undefined")Browser.lockPointer=true;if(typeof Browser.resizeCanvas==="undefined")Browser.resizeCanvas=false;var canvas=Module["canvas"];function fullscreenChange(){Browser.isFullscreen=false;var canvasContainer=canvas.parentNode;if((document["fullscreenElement"]||document["mozFullScreenElement"]||document["msFullscreenElement"]||document["webkitFullscreenElement"]||document["webkitCurrentFullScreenElement"])===canvasContainer){canvas.exitFullscreen=Browser.exitFullscreen;if(Browser.lockPointer)canvas.requestPointerLock();Browser.isFullscreen=true;if(Browser.resizeCanvas){Browser.setFullscreenCanvasSize()}else{Browser.updateCanvasDimensions(canvas)}}else{canvasContainer.parentNode.insertBefore(canvas,canvasContainer);canvasContainer.parentNode.removeChild(canvasContainer);if(Browser.resizeCanvas){Browser.setWindowedCanvasSize()}else{Browser.updateCanvasDimensions(canvas)}}if(Module["onFullScreen"])Module["onFullScreen"](Browser.isFullscreen);if(Module["onFullscreen"])Module["onFullscreen"](Browser.isFullscreen)}if(!Browser.fullscreenHandlersInstalled){Browser.fullscreenHandlersInstalled=true;document.addEventListener("fullscreenchange",fullscreenChange,false);document.addEventListener("mozfullscreenchange",fullscreenChange,false);document.addEventListener("webkitfullscreenchange",fullscreenChange,false);document.addEventListener("MSFullscreenChange",fullscreenChange,false)}var canvasContainer=document.createElement("div");canvas.parentNode.insertBefore(canvasContainer,canvas);canvasContainer.appendChild(canvas);canvasContainer.requestFullscreen=canvasContainer["requestFullscreen"]||canvasContainer["mozRequestFullScreen"]||canvasContainer["msRequestFullscreen"]||(canvasContainer["webkitRequestFullscreen"]?function(){canvasContainer["webkitRequestFullscreen"](Element["ALLOW_KEYBOARD_INPUT"])}:null)||(canvasContainer["webkitRequestFullScreen"]?function(){canvasContainer["webkitRequestFullScreen"](Element["ALLOW_KEYBOARD_INPUT"])}:null);canvasContainer.requestFullscreen()},exitFullscreen:function(){if(!Browser.isFullscreen){return false}var CFS=document["exitFullscreen"]||document["cancelFullScreen"]||document["mozCancelFullScreen"]||document["msExitFullscreen"]||document["webkitCancelFullScreen"]||function(){};CFS.apply(document,[]);return true},nextRAF:0,fakeRequestAnimationFrame:function(func){var now=Date.now();if(Browser.nextRAF===0){Browser.nextRAF=now+1e3/60}else{while(now+2>=Browser.nextRAF){Browser.nextRAF+=1e3/60}}var delay=Math.max(Browser.nextRAF-now,0);setTimeout(func,delay)},requestAnimationFrame:function(func){if(typeof requestAnimationFrame==="function"){requestAnimationFrame(func);return}var RAF=Browser.fakeRequestAnimationFrame;RAF(func)},safeCallback:function(func){return function(){if(!ABORT)return func.apply(null,arguments)}},allowAsyncCallbacks:true,queuedAsyncCallbacks:[],pauseAsyncCallbacks:function(){Browser.allowAsyncCallbacks=false},resumeAsyncCallbacks:function(){Browser.allowAsyncCallbacks=true;if(Browser.queuedAsyncCallbacks.length>0){var callbacks=Browser.queuedAsyncCallbacks;Browser.queuedAsyncCallbacks=[];callbacks.forEach(function(func){func()})}},safeRequestAnimationFrame:function(func){return Browser.requestAnimationFrame(function(){if(ABORT)return;if(Browser.allowAsyncCallbacks){func()}else{Browser.queuedAsyncCallbacks.push(func)}})},safeSetTimeout:function(func,timeout){noExitRuntime=true;return setTimeout(function(){if(ABORT)return;if(Browser.allowAsyncCallbacks){func()}else{Browser.queuedAsyncCallbacks.push(func)}},timeout)},safeSetInterval:function(func,timeout){noExitRuntime=true;return setInterval(function(){if(ABORT)return;if(Browser.allowAsyncCallbacks){func()}},timeout)},getMimetype:function(name){return{"jpg":"image/jpeg","jpeg":"image/jpeg","png":"image/png","bmp":"image/bmp","ogg":"audio/ogg","wav":"audio/wav","mp3":"audio/mpeg"}[name.substr(name.lastIndexOf(".")+1)]},getUserMedia:function(func){if(!window.getUserMedia){window.getUserMedia=navigator["getUserMedia"]||navigator["mozGetUserMedia"]}window.getUserMedia(func)},getMovementX:function(event){return event["movementX"]||event["mozMovementX"]||event["webkitMovementX"]||0},getMovementY:function(event){return event["movementY"]||event["mozMovementY"]||event["webkitMovementY"]||0},getMouseWheelDelta:function(event){var delta=0;switch(event.type){case"DOMMouseScroll":delta=event.detail/3;break;case"mousewheel":delta=event.wheelDelta/120;break;case"wheel":delta=event.deltaY;switch(event.deltaMode){case 0:delta/=100;break;case 1:delta/=3;break;case 2:delta*=80;break;default:throw"unrecognized mouse wheel delta mode: "+event.deltaMode}break;default:throw"unrecognized mouse wheel event: "+event.type}return delta},mouseX:0,mouseY:0,mouseMovementX:0,mouseMovementY:0,touches:{},lastTouches:{},calculateMouseEvent:function(event){if(Browser.pointerLock){if(event.type!="mousemove"&&"mozMovementX"in event){Browser.mouseMovementX=Browser.mouseMovementY=0}else{Browser.mouseMovementX=Browser.getMovementX(event);Browser.mouseMovementY=Browser.getMovementY(event)}if(typeof SDL!="undefined"){Browser.mouseX=SDL.mouseX+Browser.mouseMovementX;Browser.mouseY=SDL.mouseY+Browser.mouseMovementY}else{Browser.mouseX+=Browser.mouseMovementX;Browser.mouseY+=Browser.mouseMovementY}}else{var rect=Module["canvas"].getBoundingClientRect();var cw=Module["canvas"].width;var ch=Module["canvas"].height;var scrollX=typeof window.scrollX!=="undefined"?window.scrollX:window.pageXOffset;var scrollY=typeof window.scrollY!=="undefined"?window.scrollY:window.pageYOffset;if(event.type==="touchstart"||event.type==="touchend"||event.type==="touchmove"){var touch=event.touch;if(touch===undefined){return}var adjustedX=touch.pageX-(scrollX+rect.left);var adjustedY=touch.pageY-(scrollY+rect.top);adjustedX=adjustedX*(cw/rect.width);adjustedY=adjustedY*(ch/rect.height);var coords={x:adjustedX,y:adjustedY};if(event.type==="touchstart"){Browser.lastTouches[touch.identifier]=coords;Browser.touches[touch.identifier]=coords}else if(event.type==="touchend"||event.type==="touchmove"){var last=Browser.touches[touch.identifier];if(!last)last=coords;Browser.lastTouches[touch.identifier]=last;Browser.touches[touch.identifier]=coords}return}var x=event.pageX-(scrollX+rect.left);var y=event.pageY-(scrollY+rect.top);x=x*(cw/rect.width);y=y*(ch/rect.height);Browser.mouseMovementX=x-Browser.mouseX;Browser.mouseMovementY=y-Browser.mouseY;Browser.mouseX=x;Browser.mouseY=y}},asyncLoad:function(url,onload,onerror,noRunDep){var dep=!noRunDep?getUniqueRunDependency("al "+url):"";readAsync(url,function(arrayBuffer){assert(arrayBuffer,'Loading data file "'+url+'" failed (no arrayBuffer).');onload(new Uint8Array(arrayBuffer));if(dep)removeRunDependency(dep)},function(event){if(onerror){onerror()}else{throw'Loading data file "'+url+'" failed.'}});if(dep)addRunDependency(dep)},resizeListeners:[],updateResizeListeners:function(){var canvas=Module["canvas"];Browser.resizeListeners.forEach(function(listener){listener(canvas.width,canvas.height)})},setCanvasSize:function(width,height,noUpdates){var canvas=Module["canvas"];Browser.updateCanvasDimensions(canvas,width,height);if(!noUpdates)Browser.updateResizeListeners()},windowedWidth:0,windowedHeight:0,setFullscreenCanvasSize:function(){if(typeof SDL!="undefined"){var flags=HEAPU32[SDL.screen>>2];flags=flags|8388608;HEAP32[SDL.screen>>2]=flags}Browser.updateCanvasDimensions(Module["canvas"]);Browser.updateResizeListeners()},setWindowedCanvasSize:function(){if(typeof SDL!="undefined"){var flags=HEAPU32[SDL.screen>>2];flags=flags&~8388608;HEAP32[SDL.screen>>2]=flags}Browser.updateCanvasDimensions(Module["canvas"]);Browser.updateResizeListeners()},updateCanvasDimensions:function(canvas,wNative,hNative){if(wNative&&hNative){canvas.widthNative=wNative;canvas.heightNative=hNative}else{wNative=canvas.widthNative;hNative=canvas.heightNative}var w=wNative;var h=hNative;if(Module["forcedAspectRatio"]&&Module["forcedAspectRatio"]>0){if(w/h>2];if(param==12321){var alphaSize=HEAP32[attribList+4>>2];EGL.contextAttributes.alpha=alphaSize>0}else if(param==12325){var depthSize=HEAP32[attribList+4>>2];EGL.contextAttributes.depth=depthSize>0}else if(param==12326){var stencilSize=HEAP32[attribList+4>>2];EGL.contextAttributes.stencil=stencilSize>0}else if(param==12337){var samples=HEAP32[attribList+4>>2];EGL.contextAttributes.antialias=samples>0}else if(param==12338){var samples=HEAP32[attribList+4>>2];EGL.contextAttributes.antialias=samples==1}else if(param==12544){var requestedPriority=HEAP32[attribList+4>>2];EGL.contextAttributes.lowLatency=requestedPriority!=12547}else if(param==12344){break}attribList+=8}}if((!config||!config_size)&&!numConfigs){EGL.setErrorCode(12300);return 0}if(numConfigs){HEAP32[numConfigs>>2]=1}if(config&&config_size>0){HEAP32[config>>2]=62002}EGL.setErrorCode(12288);return 1}};function _eglBindAPI(api){if(api==12448){EGL.setErrorCode(12288);return 1}else{EGL.setErrorCode(12300);return 0}}function _eglChooseConfig(display,attrib_list,configs,config_size,numConfigs){return EGL.chooseConfig(display,attrib_list,configs,config_size,numConfigs)}function __webgl_enable_ANGLE_instanced_arrays(ctx){var ext=ctx.getExtension("ANGLE_instanced_arrays");if(ext){ctx["vertexAttribDivisor"]=function(index,divisor){ext["vertexAttribDivisorANGLE"](index,divisor)};ctx["drawArraysInstanced"]=function(mode,first,count,primcount){ext["drawArraysInstancedANGLE"](mode,first,count,primcount)};ctx["drawElementsInstanced"]=function(mode,count,type,indices,primcount){ext["drawElementsInstancedANGLE"](mode,count,type,indices,primcount)};return 1}}function __webgl_enable_OES_vertex_array_object(ctx){var ext=ctx.getExtension("OES_vertex_array_object");if(ext){ctx["createVertexArray"]=function(){return ext["createVertexArrayOES"]()};ctx["deleteVertexArray"]=function(vao){ext["deleteVertexArrayOES"](vao)};ctx["bindVertexArray"]=function(vao){ext["bindVertexArrayOES"](vao)};ctx["isVertexArray"]=function(vao){return ext["isVertexArrayOES"](vao)};return 1}}function __webgl_enable_WEBGL_draw_buffers(ctx){var ext=ctx.getExtension("WEBGL_draw_buffers");if(ext){ctx["drawBuffers"]=function(n,bufs){ext["drawBuffersWEBGL"](n,bufs)};return 1}}function __webgl_enable_WEBGL_multi_draw(ctx){return!!(ctx.multiDrawWebgl=ctx.getExtension("WEBGL_multi_draw"))}var GL={counter:1,buffers:[],programs:[],framebuffers:[],renderbuffers:[],textures:[],uniforms:[],shaders:[],vaos:[],contexts:[],offscreenCanvases:{},timerQueriesEXT:[],programInfos:{},stringCache:{},unpackAlignment:4,recordError:function recordError(errorCode){if(!GL.lastError){GL.lastError=errorCode}},getNewId:function(table){var ret=GL.counter++;for(var i=table.length;i>2]:-1;source+=UTF8ToString(HEAP32[string+i*4>>2],len<0?undefined:len)}return source},createContext:function(canvas,webGLContextAttributes){var ctx=canvas.getContext("webgl",webGLContextAttributes);if(!ctx)return 0;var handle=GL.registerContext(ctx,webGLContextAttributes);return handle},registerContext:function(ctx,webGLContextAttributes){var handle=GL.getNewId(GL.contexts);var context={handle:handle,attributes:webGLContextAttributes,version:webGLContextAttributes.majorVersion,GLctx:ctx};if(ctx.canvas)ctx.canvas.GLctxObject=context;GL.contexts[handle]=context;if(typeof webGLContextAttributes.enableExtensionsByDefault==="undefined"||webGLContextAttributes.enableExtensionsByDefault){GL.initExtensions(context)}return handle},makeContextCurrent:function(contextHandle){GL.currentContext=GL.contexts[contextHandle];Module.ctx=GLctx=GL.currentContext&&GL.currentContext.GLctx;return!(contextHandle&&!GLctx)},getContext:function(contextHandle){return GL.contexts[contextHandle]},deleteContext:function(contextHandle){if(GL.currentContext===GL.contexts[contextHandle])GL.currentContext=null;if(typeof JSEvents==="object")JSEvents.removeAllHandlersOnTarget(GL.contexts[contextHandle].GLctx.canvas);if(GL.contexts[contextHandle]&&GL.contexts[contextHandle].GLctx.canvas)GL.contexts[contextHandle].GLctx.canvas.GLctxObject=undefined;GL.contexts[contextHandle]=null},initExtensions:function(context){if(!context)context=GL.currentContext;if(context.initExtensionsDone)return;context.initExtensionsDone=true;var GLctx=context.GLctx;__webgl_enable_ANGLE_instanced_arrays(GLctx);__webgl_enable_OES_vertex_array_object(GLctx);__webgl_enable_WEBGL_draw_buffers(GLctx);GLctx.disjointTimerQueryExt=GLctx.getExtension("EXT_disjoint_timer_query");__webgl_enable_WEBGL_multi_draw(GLctx);var automaticallyEnabledExtensions=["OES_texture_float","OES_texture_half_float","OES_standard_derivatives","OES_vertex_array_object","WEBGL_compressed_texture_s3tc","WEBGL_depth_texture","OES_element_index_uint","EXT_texture_filter_anisotropic","EXT_frag_depth","WEBGL_draw_buffers","ANGLE_instanced_arrays","OES_texture_float_linear","OES_texture_half_float_linear","EXT_blend_minmax","EXT_shader_texture_lod","EXT_texture_norm16","WEBGL_compressed_texture_pvrtc","EXT_color_buffer_half_float","WEBGL_color_buffer_float","EXT_sRGB","WEBGL_compressed_texture_etc1","EXT_disjoint_timer_query","WEBGL_compressed_texture_etc","WEBGL_compressed_texture_astc","EXT_color_buffer_float","WEBGL_compressed_texture_s3tc_srgb","EXT_disjoint_timer_query_webgl2","WEBKIT_WEBGL_compressed_texture_pvrtc"];var exts=GLctx.getSupportedExtensions()||[];exts.forEach(function(ext){if(automaticallyEnabledExtensions.indexOf(ext)!=-1){GLctx.getExtension(ext)}})},populateUniformTable:function(program){var p=GL.programs[program];var ptable=GL.programInfos[program]={uniforms:{},maxUniformLength:0,maxAttributeLength:-1,maxUniformBlockNameLength:-1};var utable=ptable.uniforms;var numUniforms=GLctx.getProgramParameter(p,35718);for(var i=0;i>2];if(param==12440){glesContextVersion=HEAP32[contextAttribs+4>>2]}else if(param==12344){break}else{EGL.setErrorCode(12292);return 0}contextAttribs+=8}if(glesContextVersion!=2){EGL.setErrorCode(12293);return 0}EGL.contextAttributes.majorVersion=glesContextVersion-1;EGL.contextAttributes.minorVersion=0;EGL.context=GL.createContext(Module["canvas"],EGL.contextAttributes);if(EGL.context!=0){EGL.setErrorCode(12288);GL.makeContextCurrent(EGL.context);Module.useWebGL=true;Browser.moduleContextCreatedCallbacks.forEach(function(callback){callback()});GL.makeContextCurrent(null);return 62004}else{EGL.setErrorCode(12297);return 0}}function _eglCreateWindowSurface(display,config,win,attrib_list){if(display!=62e3){EGL.setErrorCode(12296);return 0}if(config!=62002){EGL.setErrorCode(12293);return 0}EGL.setErrorCode(12288);return 62006}function _eglDestroyContext(display,context){if(display!=62e3){EGL.setErrorCode(12296);return 0}if(context!=62004){EGL.setErrorCode(12294);return 0}GL.deleteContext(EGL.context);EGL.setErrorCode(12288);if(EGL.currentContext==context){EGL.currentContext=0}return 1}function _eglDestroySurface(display,surface){if(display!=62e3){EGL.setErrorCode(12296);return 0}if(surface!=62006){EGL.setErrorCode(12301);return 1}if(EGL.currentReadSurface==surface){EGL.currentReadSurface=0}if(EGL.currentDrawSurface==surface){EGL.currentDrawSurface=0}EGL.setErrorCode(12288);return 1}function _eglGetConfigAttrib(display,config,attribute,value){if(display!=62e3){EGL.setErrorCode(12296);return 0}if(config!=62002){EGL.setErrorCode(12293);return 0}if(!value){EGL.setErrorCode(12300);return 0}EGL.setErrorCode(12288);switch(attribute){case 12320:HEAP32[value>>2]=EGL.contextAttributes.alpha?32:24;return 1;case 12321:HEAP32[value>>2]=EGL.contextAttributes.alpha?8:0;return 1;case 12322:HEAP32[value>>2]=8;return 1;case 12323:HEAP32[value>>2]=8;return 1;case 12324:HEAP32[value>>2]=8;return 1;case 12325:HEAP32[value>>2]=EGL.contextAttributes.depth?24:0;return 1;case 12326:HEAP32[value>>2]=EGL.contextAttributes.stencil?8:0;return 1;case 12327:HEAP32[value>>2]=12344;return 1;case 12328:HEAP32[value>>2]=62002;return 1;case 12329:HEAP32[value>>2]=0;return 1;case 12330:HEAP32[value>>2]=4096;return 1;case 12331:HEAP32[value>>2]=16777216;return 1;case 12332:HEAP32[value>>2]=4096;return 1;case 12333:HEAP32[value>>2]=0;return 1;case 12334:HEAP32[value>>2]=0;return 1;case 12335:HEAP32[value>>2]=12344;return 1;case 12337:HEAP32[value>>2]=EGL.contextAttributes.antialias?4:0;return 1;case 12338:HEAP32[value>>2]=EGL.contextAttributes.antialias?1:0;return 1;case 12339:HEAP32[value>>2]=4;return 1;case 12340:HEAP32[value>>2]=12344;return 1;case 12341:case 12342:case 12343:HEAP32[value>>2]=-1;return 1;case 12345:case 12346:HEAP32[value>>2]=0;return 1;case 12347:HEAP32[value>>2]=0;return 1;case 12348:HEAP32[value>>2]=1;return 1;case 12349:case 12350:HEAP32[value>>2]=0;return 1;case 12351:HEAP32[value>>2]=12430;return 1;case 12352:HEAP32[value>>2]=4;return 1;case 12354:HEAP32[value>>2]=0;return 1;default:EGL.setErrorCode(12292);return 0}}function _eglGetDisplay(nativeDisplayType){EGL.setErrorCode(12288);return 62e3}function _eglGetError(){return EGL.errorCode}function _eglGetProcAddress(name_){return _emscripten_GetProcAddress(name_)}function _eglInitialize(display,majorVersion,minorVersion){if(display==62e3){if(majorVersion){HEAP32[majorVersion>>2]=1}if(minorVersion){HEAP32[minorVersion>>2]=4}EGL.defaultDisplayInitialized=true;EGL.setErrorCode(12288);return 1}else{EGL.setErrorCode(12296);return 0}}function _eglMakeCurrent(display,draw,read,context){if(display!=62e3){EGL.setErrorCode(12296);return 0}if(context!=0&&context!=62004){EGL.setErrorCode(12294);return 0}if(read!=0&&read!=62006||draw!=0&&draw!=62006){EGL.setErrorCode(12301);return 0}GL.makeContextCurrent(context?EGL.context:null);EGL.currentContext=context;EGL.currentDrawSurface=draw;EGL.currentReadSurface=read;EGL.setErrorCode(12288);return 1}function _eglQueryString(display,name){if(display!=62e3){EGL.setErrorCode(12296);return 0}EGL.setErrorCode(12288);if(EGL.stringCache[name])return EGL.stringCache[name];var ret;switch(name){case 12371:ret=allocateUTF8("Emscripten");break;case 12372:ret=allocateUTF8("1.4 Emscripten EGL");break;case 12373:ret=allocateUTF8("");break;case 12429:ret=allocateUTF8("OpenGL_ES");break;default:EGL.setErrorCode(12300);return 0}EGL.stringCache[name]=ret;return ret}function _eglSwapBuffers(){if(!EGL.defaultDisplayInitialized){EGL.setErrorCode(12289)}else if(!Module.ctx){EGL.setErrorCode(12290)}else if(Module.ctx.isContextLost()){EGL.setErrorCode(12302)}else{EGL.setErrorCode(12288);return 1}return 0}function _eglSwapInterval(display,interval){if(display!=62e3){EGL.setErrorCode(12296);return 0}if(interval==0)_emscripten_set_main_loop_timing(0,0);else _emscripten_set_main_loop_timing(1,interval);EGL.setErrorCode(12288);return 1}function _eglTerminate(display){if(display!=62e3){EGL.setErrorCode(12296);return 0}EGL.currentContext=0;EGL.currentReadSurface=0;EGL.currentDrawSurface=0;EGL.defaultDisplayInitialized=false;EGL.setErrorCode(12288);return 1}function _eglWaitClient(){EGL.setErrorCode(12288);return 1}function _eglWaitGL(){return _eglWaitClient()}function _eglWaitNative(nativeEngineId){EGL.setErrorCode(12288);return 1}function _emscripten_asm_const_int(code,sigPtr,argbuf){var args=readAsmConstArgs(sigPtr,argbuf);return ASM_CONSTS[code].apply(null,args)}var JSEvents={inEventHandler:0,removeAllEventListeners:function(){for(var i=JSEvents.eventHandlers.length-1;i>=0;--i){JSEvents._removeHandler(i)}JSEvents.eventHandlers=[];JSEvents.deferredCalls=[]},registerRemoveEventListeners:function(){if(!JSEvents.removeEventListenersRegistered){__ATEXIT__.push(JSEvents.removeAllEventListeners);JSEvents.removeEventListenersRegistered=true}},deferredCalls:[],deferCall:function(targetFunction,precedence,argsList){function arraysHaveEqualContent(arrA,arrB){if(arrA.length!=arrB.length)return false;for(var i in arrA){if(arrA[i]!=arrB[i])return false}return true}for(var i in JSEvents.deferredCalls){var call=JSEvents.deferredCalls[i];if(call.targetFunction==targetFunction&&arraysHaveEqualContent(call.argsList,argsList)){return}}JSEvents.deferredCalls.push({targetFunction:targetFunction,precedence:precedence,argsList:argsList});JSEvents.deferredCalls.sort(function(x,y){return x.precedence2?UTF8ToString(cString):cString}var specialHTMLTargets=[0,typeof document!=="undefined"?document:0,typeof window!=="undefined"?window:0];function findEventTarget(target){target=maybeCStringToJsString(target);var domElement=specialHTMLTargets[target]||(typeof document!=="undefined"?document.querySelector(target):undefined);return domElement}function findCanvasEventTarget(target){return findEventTarget(target)}function _emscripten_get_canvas_element_size(target,width,height){var canvas=findCanvasEventTarget(target);if(!canvas)return-4;HEAP32[width>>2]=canvas.width;HEAP32[height>>2]=canvas.height}function __get_canvas_element_size(target){var stackTop=stackSave();var w=stackAlloc(8);var h=w+4;var targetInt=stackAlloc(target.id.length+1);stringToUTF8(target.id,targetInt,target.id.length+1);var ret=_emscripten_get_canvas_element_size(targetInt,w,h);var size=[HEAP32[w>>2],HEAP32[h>>2]];stackRestore(stackTop);return size}function _emscripten_set_canvas_element_size(target,width,height){var canvas=findCanvasEventTarget(target);if(!canvas)return-4;canvas.width=width;canvas.height=height;return 0}function __set_canvas_element_size(target,width,height){if(!target.controlTransferredOffscreen){target.width=width;target.height=height}else{var stackTop=stackSave();var targetInt=stackAlloc(target.id.length+1);stringToUTF8(target.id,targetInt,target.id.length+1);_emscripten_set_canvas_element_size(targetInt,width,height);stackRestore(stackTop)}}function __registerRestoreOldStyle(canvas){var canvasSize=__get_canvas_element_size(canvas);var oldWidth=canvasSize[0];var oldHeight=canvasSize[1];var oldCssWidth=canvas.style.width;var oldCssHeight=canvas.style.height;var oldBackgroundColor=canvas.style.backgroundColor;var oldDocumentBackgroundColor=document.body.style.backgroundColor;var oldPaddingLeft=canvas.style.paddingLeft;var oldPaddingRight=canvas.style.paddingRight;var oldPaddingTop=canvas.style.paddingTop;var oldPaddingBottom=canvas.style.paddingBottom;var oldMarginLeft=canvas.style.marginLeft;var oldMarginRight=canvas.style.marginRight;var oldMarginTop=canvas.style.marginTop;var oldMarginBottom=canvas.style.marginBottom;var oldDocumentBodyMargin=document.body.style.margin;var oldDocumentOverflow=document.documentElement.style.overflow;var oldDocumentScroll=document.body.scroll;var oldImageRendering=canvas.style.imageRendering;function restoreOldStyle(){var fullscreenElement=document.fullscreenElement||document.webkitFullscreenElement||document.msFullscreenElement;if(!fullscreenElement){document.removeEventListener("fullscreenchange",restoreOldStyle);document.removeEventListener("webkitfullscreenchange",restoreOldStyle);__set_canvas_element_size(canvas,oldWidth,oldHeight);canvas.style.width=oldCssWidth;canvas.style.height=oldCssHeight;canvas.style.backgroundColor=oldBackgroundColor;if(!oldDocumentBackgroundColor)document.body.style.backgroundColor="white";document.body.style.backgroundColor=oldDocumentBackgroundColor;canvas.style.paddingLeft=oldPaddingLeft;canvas.style.paddingRight=oldPaddingRight;canvas.style.paddingTop=oldPaddingTop;canvas.style.paddingBottom=oldPaddingBottom;canvas.style.marginLeft=oldMarginLeft;canvas.style.marginRight=oldMarginRight;canvas.style.marginTop=oldMarginTop;canvas.style.marginBottom=oldMarginBottom;document.body.style.margin=oldDocumentBodyMargin;document.documentElement.style.overflow=oldDocumentOverflow;document.body.scroll=oldDocumentScroll;canvas.style.imageRendering=oldImageRendering;if(canvas.GLctxObject)canvas.GLctxObject.GLctx.viewport(0,0,oldWidth,oldHeight);if(__currentFullscreenStrategy.canvasResizedCallback){getDynCaller("iiii",__currentFullscreenStrategy.canvasResizedCallback)(37,0,__currentFullscreenStrategy.canvasResizedCallbackUserData)}}}document.addEventListener("fullscreenchange",restoreOldStyle);document.addEventListener("webkitfullscreenchange",restoreOldStyle);return restoreOldStyle}function __setLetterbox(element,topBottom,leftRight){element.style.paddingLeft=element.style.paddingRight=leftRight+"px";element.style.paddingTop=element.style.paddingBottom=topBottom+"px"}function __getBoundingClientRect(e){return specialHTMLTargets.indexOf(e)<0?e.getBoundingClientRect():{"left":0,"top":0}}function _JSEvents_resizeCanvasForFullscreen(target,strategy){var restoreOldStyle=__registerRestoreOldStyle(target);var cssWidth=strategy.softFullscreen?innerWidth:screen.width;var cssHeight=strategy.softFullscreen?innerHeight:screen.height;var rect=__getBoundingClientRect(target);var windowedCssWidth=rect.width;var windowedCssHeight=rect.height;var canvasSize=__get_canvas_element_size(target);var windowedRttWidth=canvasSize[0];var windowedRttHeight=canvasSize[1];if(strategy.scaleMode==3){__setLetterbox(target,(cssHeight-windowedCssHeight)/2,(cssWidth-windowedCssWidth)/2);cssWidth=windowedCssWidth;cssHeight=windowedCssHeight}else if(strategy.scaleMode==2){if(cssWidth*windowedRttHeight>3]=rect.width;HEAPF64[height>>3]=rect.height;return 0}function __fillGamepadEventData(eventStruct,e){HEAPF64[eventStruct>>3]=e.timestamp;for(var i=0;i>3]=e.axes[i]}for(var i=0;i>3]=e.buttons[i].value}else{HEAPF64[eventStruct+i*8+528>>3]=e.buttons[i]}}for(var i=0;i>2]=e.buttons[i].pressed}else{HEAP32[eventStruct+i*4+1040>>2]=e.buttons[i]==1}}HEAP32[eventStruct+1296>>2]=e.connected;HEAP32[eventStruct+1300>>2]=e.index;HEAP32[eventStruct+8>>2]=e.axes.length;HEAP32[eventStruct+12>>2]=e.buttons.length;stringToUTF8(e.id,eventStruct+1304,64);stringToUTF8(e.mapping,eventStruct+1368,64)}function _emscripten_get_gamepad_status(index,gamepadState){if(index<0||index>=JSEvents.lastGamepadState.length)return-5;if(!JSEvents.lastGamepadState[index])return-7;__fillGamepadEventData(gamepadState,JSEvents.lastGamepadState[index]);return 0}function _emscripten_get_num_gamepads(){return JSEvents.lastGamepadState.length}function _emscripten_glActiveTexture(x0){GLctx["activeTexture"](x0)}function _emscripten_glAttachShader(program,shader){GLctx.attachShader(GL.programs[program],GL.shaders[shader])}function _emscripten_glBeginQueryEXT(target,id){GLctx.disjointTimerQueryExt["beginQueryEXT"](target,GL.timerQueriesEXT[id])}function _emscripten_glBindAttribLocation(program,index,name){GLctx.bindAttribLocation(GL.programs[program],index,UTF8ToString(name))}function _emscripten_glBindBuffer(target,buffer){GLctx.bindBuffer(target,GL.buffers[buffer])}function _emscripten_glBindFramebuffer(target,framebuffer){GLctx.bindFramebuffer(target,GL.framebuffers[framebuffer])}function _emscripten_glBindRenderbuffer(target,renderbuffer){GLctx.bindRenderbuffer(target,GL.renderbuffers[renderbuffer])}function _emscripten_glBindTexture(target,texture){GLctx.bindTexture(target,GL.textures[texture])}function _emscripten_glBindVertexArrayOES(vao){GLctx["bindVertexArray"](GL.vaos[vao])}function _emscripten_glBlendColor(x0,x1,x2,x3){GLctx["blendColor"](x0,x1,x2,x3)}function _emscripten_glBlendEquation(x0){GLctx["blendEquation"](x0)}function _emscripten_glBlendEquationSeparate(x0,x1){GLctx["blendEquationSeparate"](x0,x1)}function _emscripten_glBlendFunc(x0,x1){GLctx["blendFunc"](x0,x1)}function _emscripten_glBlendFuncSeparate(x0,x1,x2,x3){GLctx["blendFuncSeparate"](x0,x1,x2,x3)}function _emscripten_glBufferData(target,size,data,usage){GLctx.bufferData(target,data?HEAPU8.subarray(data,data+size):size,usage)}function _emscripten_glBufferSubData(target,offset,size,data){GLctx.bufferSubData(target,offset,HEAPU8.subarray(data,data+size))}function _emscripten_glCheckFramebufferStatus(x0){return GLctx["checkFramebufferStatus"](x0)}function _emscripten_glClear(x0){GLctx["clear"](x0)}function _emscripten_glClearColor(x0,x1,x2,x3){GLctx["clearColor"](x0,x1,x2,x3)}function _emscripten_glClearDepthf(x0){GLctx["clearDepth"](x0)}function _emscripten_glClearStencil(x0){GLctx["clearStencil"](x0)}function _emscripten_glColorMask(red,green,blue,alpha){GLctx.colorMask(!!red,!!green,!!blue,!!alpha)}function _emscripten_glCompileShader(shader){GLctx.compileShader(GL.shaders[shader])}function _emscripten_glCompressedTexImage2D(target,level,internalFormat,width,height,border,imageSize,data){GLctx["compressedTexImage2D"](target,level,internalFormat,width,height,border,data?HEAPU8.subarray(data,data+imageSize):null)}function _emscripten_glCompressedTexSubImage2D(target,level,xoffset,yoffset,width,height,format,imageSize,data){GLctx["compressedTexSubImage2D"](target,level,xoffset,yoffset,width,height,format,data?HEAPU8.subarray(data,data+imageSize):null)}function _emscripten_glCopyTexImage2D(x0,x1,x2,x3,x4,x5,x6,x7){GLctx["copyTexImage2D"](x0,x1,x2,x3,x4,x5,x6,x7)}function _emscripten_glCopyTexSubImage2D(x0,x1,x2,x3,x4,x5,x6,x7){GLctx["copyTexSubImage2D"](x0,x1,x2,x3,x4,x5,x6,x7)}function _emscripten_glCreateProgram(){var id=GL.getNewId(GL.programs);var program=GLctx.createProgram();program.name=id;GL.programs[id]=program;return id}function _emscripten_glCreateShader(shaderType){var id=GL.getNewId(GL.shaders);GL.shaders[id]=GLctx.createShader(shaderType);return id}function _emscripten_glCullFace(x0){GLctx["cullFace"](x0)}function _emscripten_glDeleteBuffers(n,buffers){for(var i=0;i>2];var buffer=GL.buffers[id];if(!buffer)continue;GLctx.deleteBuffer(buffer);buffer.name=0;GL.buffers[id]=null}}function _emscripten_glDeleteFramebuffers(n,framebuffers){for(var i=0;i>2];var framebuffer=GL.framebuffers[id];if(!framebuffer)continue;GLctx.deleteFramebuffer(framebuffer);framebuffer.name=0;GL.framebuffers[id]=null}}function _emscripten_glDeleteProgram(id){if(!id)return;var program=GL.programs[id];if(!program){GL.recordError(1281);return}GLctx.deleteProgram(program);program.name=0;GL.programs[id]=null;GL.programInfos[id]=null}function _emscripten_glDeleteQueriesEXT(n,ids){for(var i=0;i>2];var query=GL.timerQueriesEXT[id];if(!query)continue;GLctx.disjointTimerQueryExt["deleteQueryEXT"](query);GL.timerQueriesEXT[id]=null}}function _emscripten_glDeleteRenderbuffers(n,renderbuffers){for(var i=0;i>2];var renderbuffer=GL.renderbuffers[id];if(!renderbuffer)continue;GLctx.deleteRenderbuffer(renderbuffer);renderbuffer.name=0;GL.renderbuffers[id]=null}}function _emscripten_glDeleteShader(id){if(!id)return;var shader=GL.shaders[id];if(!shader){GL.recordError(1281);return}GLctx.deleteShader(shader);GL.shaders[id]=null}function _emscripten_glDeleteTextures(n,textures){for(var i=0;i>2];var texture=GL.textures[id];if(!texture)continue;GLctx.deleteTexture(texture);texture.name=0;GL.textures[id]=null}}function _emscripten_glDeleteVertexArraysOES(n,vaos){for(var i=0;i>2];GLctx["deleteVertexArray"](GL.vaos[id]);GL.vaos[id]=null}}function _emscripten_glDepthFunc(x0){GLctx["depthFunc"](x0)}function _emscripten_glDepthMask(flag){GLctx.depthMask(!!flag)}function _emscripten_glDepthRangef(x0,x1){GLctx["depthRange"](x0,x1)}function _emscripten_glDetachShader(program,shader){GLctx.detachShader(GL.programs[program],GL.shaders[shader])}function _emscripten_glDisable(x0){GLctx["disable"](x0)}function _emscripten_glDisableVertexAttribArray(index){GLctx.disableVertexAttribArray(index)}function _emscripten_glDrawArrays(mode,first,count){GLctx.drawArrays(mode,first,count)}function _emscripten_glDrawArraysInstancedANGLE(mode,first,count,primcount){GLctx["drawArraysInstanced"](mode,first,count,primcount)}var tempFixedLengthArray=[];function _emscripten_glDrawBuffersWEBGL(n,bufs){var bufArray=tempFixedLengthArray[n];for(var i=0;i>2]}GLctx["drawBuffers"](bufArray)}function _emscripten_glDrawElements(mode,count,type,indices){GLctx.drawElements(mode,count,type,indices)}function _emscripten_glDrawElementsInstancedANGLE(mode,count,type,indices,primcount){GLctx["drawElementsInstanced"](mode,count,type,indices,primcount)}function _emscripten_glEnable(x0){GLctx["enable"](x0)}function _emscripten_glEnableVertexAttribArray(index){GLctx.enableVertexAttribArray(index)}function _emscripten_glEndQueryEXT(target){GLctx.disjointTimerQueryExt["endQueryEXT"](target)}function _emscripten_glFinish(){GLctx["finish"]()}function _emscripten_glFlush(){GLctx["flush"]()}function _emscripten_glFramebufferRenderbuffer(target,attachment,renderbuffertarget,renderbuffer){GLctx.framebufferRenderbuffer(target,attachment,renderbuffertarget,GL.renderbuffers[renderbuffer])}function _emscripten_glFramebufferTexture2D(target,attachment,textarget,texture,level){GLctx.framebufferTexture2D(target,attachment,textarget,GL.textures[texture],level)}function _emscripten_glFrontFace(x0){GLctx["frontFace"](x0)}function __glGenObject(n,buffers,createFunction,objectTable){for(var i=0;i>2]=id}}function _emscripten_glGenBuffers(n,buffers){__glGenObject(n,buffers,"createBuffer",GL.buffers)}function _emscripten_glGenFramebuffers(n,ids){__glGenObject(n,ids,"createFramebuffer",GL.framebuffers)}function _emscripten_glGenQueriesEXT(n,ids){for(var i=0;i>2]=0;return}var id=GL.getNewId(GL.timerQueriesEXT);query.name=id;GL.timerQueriesEXT[id]=query;HEAP32[ids+i*4>>2]=id}}function _emscripten_glGenRenderbuffers(n,renderbuffers){__glGenObject(n,renderbuffers,"createRenderbuffer",GL.renderbuffers)}function _emscripten_glGenTextures(n,textures){__glGenObject(n,textures,"createTexture",GL.textures)}function _emscripten_glGenVertexArraysOES(n,arrays){__glGenObject(n,arrays,"createVertexArray",GL.vaos)}function _emscripten_glGenerateMipmap(x0){GLctx["generateMipmap"](x0)}function __glGetActiveAttribOrUniform(funcName,program,index,bufSize,length,size,type,name){program=GL.programs[program];var info=GLctx[funcName](program,index);if(info){var numBytesWrittenExclNull=name&&stringToUTF8(info.name,name,bufSize);if(length)HEAP32[length>>2]=numBytesWrittenExclNull;if(size)HEAP32[size>>2]=info.size;if(type)HEAP32[type>>2]=info.type}}function _emscripten_glGetActiveAttrib(program,index,bufSize,length,size,type,name){__glGetActiveAttribOrUniform("getActiveAttrib",program,index,bufSize,length,size,type,name)}function _emscripten_glGetActiveUniform(program,index,bufSize,length,size,type,name){__glGetActiveAttribOrUniform("getActiveUniform",program,index,bufSize,length,size,type,name)}function _emscripten_glGetAttachedShaders(program,maxCount,count,shaders){var result=GLctx.getAttachedShaders(GL.programs[program]);var len=result.length;if(len>maxCount){len=maxCount}HEAP32[count>>2]=len;for(var i=0;i>2]=id}}function _emscripten_glGetAttribLocation(program,name){return GLctx.getAttribLocation(GL.programs[program],UTF8ToString(name))}function writeI53ToI64(ptr,num){HEAPU32[ptr>>2]=num;HEAPU32[ptr+4>>2]=(num-HEAPU32[ptr>>2])/4294967296}function emscriptenWebGLGet(name_,p,type){if(!p){GL.recordError(1281);return}var ret=undefined;switch(name_){case 36346:ret=1;break;case 36344:if(type!=0&&type!=1){GL.recordError(1280)}return;case 36345:ret=0;break;case 34466:var formats=GLctx.getParameter(34467);ret=formats?formats.length:0;break}if(ret===undefined){var result=GLctx.getParameter(name_);switch(typeof result){case"number":ret=result;break;case"boolean":ret=result?1:0;break;case"string":GL.recordError(1280);return;case"object":if(result===null){switch(name_){case 34964:case 35725:case 34965:case 36006:case 36007:case 32873:case 34229:case 34068:{ret=0;break}default:{GL.recordError(1280);return}}}else if(result instanceof Float32Array||result instanceof Uint32Array||result instanceof Int32Array||result instanceof Array){for(var i=0;i>2]=result[i];break;case 2:HEAPF32[p+i*4>>2]=result[i];break;case 4:HEAP8[p+i>>0]=result[i]?1:0;break}}return}else{try{ret=result.name|0}catch(e){GL.recordError(1280);err("GL_INVALID_ENUM in glGet"+type+"v: Unknown object returned from WebGL getParameter("+name_+")! (error: "+e+")");return}}break;default:GL.recordError(1280);err("GL_INVALID_ENUM in glGet"+type+"v: Native code calling glGet"+type+"v("+name_+") and it returns "+result+" of type "+typeof result+"!");return}}switch(type){case 1:writeI53ToI64(p,ret);break;case 0:HEAP32[p>>2]=ret;break;case 2:HEAPF32[p>>2]=ret;break;case 4:HEAP8[p>>0]=ret?1:0;break}}function _emscripten_glGetBooleanv(name_,p){emscriptenWebGLGet(name_,p,4)}function _emscripten_glGetBufferParameteriv(target,value,data){if(!data){GL.recordError(1281);return}HEAP32[data>>2]=GLctx.getBufferParameter(target,value)}function _emscripten_glGetError(){var error=GLctx.getError()||GL.lastError;GL.lastError=0;return error}function _emscripten_glGetFloatv(name_,p){emscriptenWebGLGet(name_,p,2)}function _emscripten_glGetFramebufferAttachmentParameteriv(target,attachment,pname,params){var result=GLctx.getFramebufferAttachmentParameter(target,attachment,pname);if(result instanceof WebGLRenderbuffer||result instanceof WebGLTexture){result=result.name|0}HEAP32[params>>2]=result}function _emscripten_glGetIntegerv(name_,p){emscriptenWebGLGet(name_,p,0)}function _emscripten_glGetProgramInfoLog(program,maxLength,length,infoLog){var log=GLctx.getProgramInfoLog(GL.programs[program]);if(log===null)log="(unknown error)";var numBytesWrittenExclNull=maxLength>0&&infoLog?stringToUTF8(log,infoLog,maxLength):0;if(length)HEAP32[length>>2]=numBytesWrittenExclNull}function _emscripten_glGetProgramiv(program,pname,p){if(!p){GL.recordError(1281);return}if(program>=GL.counter){GL.recordError(1281);return}var ptable=GL.programInfos[program];if(!ptable){GL.recordError(1282);return}if(pname==35716){var log=GLctx.getProgramInfoLog(GL.programs[program]);if(log===null)log="(unknown error)";HEAP32[p>>2]=log.length+1}else if(pname==35719){HEAP32[p>>2]=ptable.maxUniformLength}else if(pname==35722){if(ptable.maxAttributeLength==-1){program=GL.programs[program];var numAttribs=GLctx.getProgramParameter(program,35721);ptable.maxAttributeLength=0;for(var i=0;i>2]=ptable.maxAttributeLength}else if(pname==35381){if(ptable.maxUniformBlockNameLength==-1){program=GL.programs[program];var numBlocks=GLctx.getProgramParameter(program,35382);ptable.maxUniformBlockNameLength=0;for(var i=0;i>2]=ptable.maxUniformBlockNameLength}else{HEAP32[p>>2]=GLctx.getProgramParameter(GL.programs[program],pname)}}function _emscripten_glGetQueryObjecti64vEXT(id,pname,params){if(!params){GL.recordError(1281);return}var query=GL.timerQueriesEXT[id];var param=GLctx.disjointTimerQueryExt["getQueryObjectEXT"](query,pname);var ret;if(typeof param=="boolean"){ret=param?1:0}else{ret=param}writeI53ToI64(params,ret)}function _emscripten_glGetQueryObjectivEXT(id,pname,params){if(!params){GL.recordError(1281);return}var query=GL.timerQueriesEXT[id];var param=GLctx.disjointTimerQueryExt["getQueryObjectEXT"](query,pname);var ret;if(typeof param=="boolean"){ret=param?1:0}else{ret=param}HEAP32[params>>2]=ret}function _emscripten_glGetQueryObjectui64vEXT(id,pname,params){if(!params){GL.recordError(1281);return}var query=GL.timerQueriesEXT[id];var param=GLctx.disjointTimerQueryExt["getQueryObjectEXT"](query,pname);var ret;if(typeof param=="boolean"){ret=param?1:0}else{ret=param}writeI53ToI64(params,ret)}function _emscripten_glGetQueryObjectuivEXT(id,pname,params){if(!params){GL.recordError(1281);return}var query=GL.timerQueriesEXT[id];var param=GLctx.disjointTimerQueryExt["getQueryObjectEXT"](query,pname);var ret;if(typeof param=="boolean"){ret=param?1:0}else{ret=param}HEAP32[params>>2]=ret}function _emscripten_glGetQueryivEXT(target,pname,params){if(!params){GL.recordError(1281);return}HEAP32[params>>2]=GLctx.disjointTimerQueryExt["getQueryEXT"](target,pname)}function _emscripten_glGetRenderbufferParameteriv(target,pname,params){if(!params){GL.recordError(1281);return}HEAP32[params>>2]=GLctx.getRenderbufferParameter(target,pname)}function _emscripten_glGetShaderInfoLog(shader,maxLength,length,infoLog){var log=GLctx.getShaderInfoLog(GL.shaders[shader]);if(log===null)log="(unknown error)";var numBytesWrittenExclNull=maxLength>0&&infoLog?stringToUTF8(log,infoLog,maxLength):0;if(length)HEAP32[length>>2]=numBytesWrittenExclNull}function _emscripten_glGetShaderPrecisionFormat(shaderType,precisionType,range,precision){var result=GLctx.getShaderPrecisionFormat(shaderType,precisionType);HEAP32[range>>2]=result.rangeMin;HEAP32[range+4>>2]=result.rangeMax;HEAP32[precision>>2]=result.precision}function _emscripten_glGetShaderSource(shader,bufSize,length,source){var result=GLctx.getShaderSource(GL.shaders[shader]);if(!result)return;var numBytesWrittenExclNull=bufSize>0&&source?stringToUTF8(result,source,bufSize):0;if(length)HEAP32[length>>2]=numBytesWrittenExclNull}function _emscripten_glGetShaderiv(shader,pname,p){if(!p){GL.recordError(1281);return}if(pname==35716){var log=GLctx.getShaderInfoLog(GL.shaders[shader]);if(log===null)log="(unknown error)";var logLength=log?log.length+1:0;HEAP32[p>>2]=logLength}else if(pname==35720){var source=GLctx.getShaderSource(GL.shaders[shader]);var sourceLength=source?source.length+1:0;HEAP32[p>>2]=sourceLength}else{HEAP32[p>>2]=GLctx.getShaderParameter(GL.shaders[shader],pname)}}function stringToNewUTF8(jsString){var length=lengthBytesUTF8(jsString)+1;var cString=_malloc(length);stringToUTF8(jsString,cString,length);return cString}function _emscripten_glGetString(name_){if(GL.stringCache[name_])return GL.stringCache[name_];var ret;switch(name_){case 7939:var exts=GLctx.getSupportedExtensions()||[];exts=exts.concat(exts.map(function(e){return"GL_"+e}));ret=stringToNewUTF8(exts.join(" "));break;case 7936:case 7937:case 37445:case 37446:var s=GLctx.getParameter(name_);if(!s){GL.recordError(1280)}ret=stringToNewUTF8(s);break;case 7938:var glVersion=GLctx.getParameter(7938);{glVersion="OpenGL ES 2.0 ("+glVersion+")"}ret=stringToNewUTF8(glVersion);break;case 35724:var glslVersion=GLctx.getParameter(35724);var ver_re=/^WebGL GLSL ES ([0-9]\.[0-9][0-9]?)(?:$| .*)/;var ver_num=glslVersion.match(ver_re);if(ver_num!==null){if(ver_num[1].length==3)ver_num[1]=ver_num[1]+"0";glslVersion="OpenGL ES GLSL ES "+ver_num[1]+" ("+glslVersion+")"}ret=stringToNewUTF8(glslVersion);break;default:GL.recordError(1280);return 0}GL.stringCache[name_]=ret;return ret}function _emscripten_glGetTexParameterfv(target,pname,params){if(!params){GL.recordError(1281);return}HEAPF32[params>>2]=GLctx.getTexParameter(target,pname)}function _emscripten_glGetTexParameteriv(target,pname,params){if(!params){GL.recordError(1281);return}HEAP32[params>>2]=GLctx.getTexParameter(target,pname)}function jstoi_q(str){return parseInt(str)}function _emscripten_glGetUniformLocation(program,name){name=UTF8ToString(name);var arrayIndex=0;if(name[name.length-1]=="]"){var leftBrace=name.lastIndexOf("[");arrayIndex=name[leftBrace+1]!="]"?jstoi_q(name.slice(leftBrace+1)):0;name=name.slice(0,leftBrace)}var uniformInfo=GL.programInfos[program]&&GL.programInfos[program].uniforms[name];if(uniformInfo&&arrayIndex>=0&&arrayIndex>2]=data;break;case 2:HEAPF32[params>>2]=data;break}}else{for(var i=0;i>2]=data[i];break;case 2:HEAPF32[params+i*4>>2]=data[i];break}}}}function _emscripten_glGetUniformfv(program,location,params){emscriptenWebGLGetUniform(program,location,params,2)}function _emscripten_glGetUniformiv(program,location,params){emscriptenWebGLGetUniform(program,location,params,0)}function _emscripten_glGetVertexAttribPointerv(index,pname,pointer){if(!pointer){GL.recordError(1281);return}HEAP32[pointer>>2]=GLctx.getVertexAttribOffset(index,pname)}function emscriptenWebGLGetVertexAttrib(index,pname,params,type){if(!params){GL.recordError(1281);return}var data=GLctx.getVertexAttrib(index,pname);if(pname==34975){HEAP32[params>>2]=data&&data["name"]}else if(typeof data=="number"||typeof data=="boolean"){switch(type){case 0:HEAP32[params>>2]=data;break;case 2:HEAPF32[params>>2]=data;break;case 5:HEAP32[params>>2]=Math.fround(data);break}}else{for(var i=0;i>2]=data[i];break;case 2:HEAPF32[params+i*4>>2]=data[i];break;case 5:HEAP32[params+i*4>>2]=Math.fround(data[i]);break}}}}function _emscripten_glGetVertexAttribfv(index,pname,params){emscriptenWebGLGetVertexAttrib(index,pname,params,2)}function _emscripten_glGetVertexAttribiv(index,pname,params){emscriptenWebGLGetVertexAttrib(index,pname,params,5)}function _emscripten_glHint(x0,x1){GLctx["hint"](x0,x1)}function _emscripten_glIsBuffer(buffer){var b=GL.buffers[buffer];if(!b)return 0;return GLctx.isBuffer(b)}function _emscripten_glIsEnabled(x0){return GLctx["isEnabled"](x0)}function _emscripten_glIsFramebuffer(framebuffer){var fb=GL.framebuffers[framebuffer];if(!fb)return 0;return GLctx.isFramebuffer(fb)}function _emscripten_glIsProgram(program){program=GL.programs[program];if(!program)return 0;return GLctx.isProgram(program)}function _emscripten_glIsQueryEXT(id){var query=GL.timerQueriesEXT[id];if(!query)return 0;return GLctx.disjointTimerQueryExt["isQueryEXT"](query)}function _emscripten_glIsRenderbuffer(renderbuffer){var rb=GL.renderbuffers[renderbuffer];if(!rb)return 0;return GLctx.isRenderbuffer(rb)}function _emscripten_glIsShader(shader){var s=GL.shaders[shader];if(!s)return 0;return GLctx.isShader(s)}function _emscripten_glIsTexture(id){var texture=GL.textures[id];if(!texture)return 0;return GLctx.isTexture(texture)}function _emscripten_glIsVertexArrayOES(array){var vao=GL.vaos[array];if(!vao)return 0;return GLctx["isVertexArray"](vao)}function _emscripten_glLineWidth(x0){GLctx["lineWidth"](x0)}function _emscripten_glLinkProgram(program){GLctx.linkProgram(GL.programs[program]);GL.populateUniformTable(program)}function _emscripten_glPixelStorei(pname,param){if(pname==3317){GL.unpackAlignment=param}GLctx.pixelStorei(pname,param)}function _emscripten_glPolygonOffset(x0,x1){GLctx["polygonOffset"](x0,x1)}function _emscripten_glQueryCounterEXT(id,target){GLctx.disjointTimerQueryExt["queryCounterEXT"](GL.timerQueriesEXT[id],target)}function computeUnpackAlignedImageSize(width,height,sizePerPixel,alignment){function roundedToNextMultipleOf(x,y){return x+y-1&-y}var plainRowSize=width*sizePerPixel;var alignedRowSize=roundedToNextMultipleOf(plainRowSize,alignment);return height*alignedRowSize}function __colorChannelsInGlTextureFormat(format){var colorChannels={5:3,6:4,8:2,29502:3,29504:4};return colorChannels[format-6402]||1}function heapObjectForWebGLType(type){type-=5120;if(type==1)return HEAPU8;if(type==4)return HEAP32;if(type==6)return HEAPF32;if(type==5||type==28922)return HEAPU32;return HEAPU16}function heapAccessShiftForWebGLHeap(heap){return 31-Math.clz32(heap.BYTES_PER_ELEMENT)}function emscriptenWebGLGetTexPixelData(type,format,width,height,pixels,internalFormat){var heap=heapObjectForWebGLType(type);var shift=heapAccessShiftForWebGLHeap(heap);var byteSize=1<>shift,pixels+bytes>>shift)}function _emscripten_glReadPixels(x,y,width,height,format,type,pixels){var pixelData=emscriptenWebGLGetTexPixelData(type,format,width,height,pixels,format);if(!pixelData){GL.recordError(1280);return}GLctx.readPixels(x,y,width,height,format,type,pixelData)}function _emscripten_glReleaseShaderCompiler(){}function _emscripten_glRenderbufferStorage(x0,x1,x2,x3){GLctx["renderbufferStorage"](x0,x1,x2,x3)}function _emscripten_glSampleCoverage(value,invert){GLctx.sampleCoverage(value,!!invert)}function _emscripten_glScissor(x0,x1,x2,x3){GLctx["scissor"](x0,x1,x2,x3)}function _emscripten_glShaderBinary(){GL.recordError(1280)}function _emscripten_glShaderSource(shader,count,string,length){var source=GL.getSource(shader,count,string,length);GLctx.shaderSource(GL.shaders[shader],source)}function _emscripten_glStencilFunc(x0,x1,x2){GLctx["stencilFunc"](x0,x1,x2)}function _emscripten_glStencilFuncSeparate(x0,x1,x2,x3){GLctx["stencilFuncSeparate"](x0,x1,x2,x3)}function _emscripten_glStencilMask(x0){GLctx["stencilMask"](x0)}function _emscripten_glStencilMaskSeparate(x0,x1){GLctx["stencilMaskSeparate"](x0,x1)}function _emscripten_glStencilOp(x0,x1,x2){GLctx["stencilOp"](x0,x1,x2)}function _emscripten_glStencilOpSeparate(x0,x1,x2,x3){GLctx["stencilOpSeparate"](x0,x1,x2,x3)}function _emscripten_glTexImage2D(target,level,internalFormat,width,height,border,format,type,pixels){GLctx.texImage2D(target,level,internalFormat,width,height,border,format,type,pixels?emscriptenWebGLGetTexPixelData(type,format,width,height,pixels,internalFormat):null)}function _emscripten_glTexParameterf(x0,x1,x2){GLctx["texParameterf"](x0,x1,x2)}function _emscripten_glTexParameterfv(target,pname,params){var param=HEAPF32[params>>2];GLctx.texParameterf(target,pname,param)}function _emscripten_glTexParameteri(x0,x1,x2){GLctx["texParameteri"](x0,x1,x2)}function _emscripten_glTexParameteriv(target,pname,params){var param=HEAP32[params>>2];GLctx.texParameteri(target,pname,param)}function _emscripten_glTexSubImage2D(target,level,xoffset,yoffset,width,height,format,type,pixels){var pixelData=null;if(pixels)pixelData=emscriptenWebGLGetTexPixelData(type,format,width,height,pixels,0);GLctx.texSubImage2D(target,level,xoffset,yoffset,width,height,format,type,pixelData)}function _emscripten_glUniform1f(location,v0){GLctx.uniform1f(GL.uniforms[location],v0)}var miniTempWebGLFloatBuffers=[];function _emscripten_glUniform1fv(location,count,value){if(count<=288){var view=miniTempWebGLFloatBuffers[count-1];for(var i=0;i>2]}}else{var view=HEAPF32.subarray(value>>2,value+count*4>>2)}GLctx.uniform1fv(GL.uniforms[location],view)}function _emscripten_glUniform1i(location,v0){GLctx.uniform1i(GL.uniforms[location],v0)}var __miniTempWebGLIntBuffers=[];function _emscripten_glUniform1iv(location,count,value){if(count<=288){var view=__miniTempWebGLIntBuffers[count-1];for(var i=0;i>2]}}else{var view=HEAP32.subarray(value>>2,value+count*4>>2)}GLctx.uniform1iv(GL.uniforms[location],view)}function _emscripten_glUniform2f(location,v0,v1){GLctx.uniform2f(GL.uniforms[location],v0,v1)}function _emscripten_glUniform2fv(location,count,value){if(count<=144){var view=miniTempWebGLFloatBuffers[2*count-1];for(var i=0;i<2*count;i+=2){view[i]=HEAPF32[value+4*i>>2];view[i+1]=HEAPF32[value+(4*i+4)>>2]}}else{var view=HEAPF32.subarray(value>>2,value+count*8>>2)}GLctx.uniform2fv(GL.uniforms[location],view)}function _emscripten_glUniform2i(location,v0,v1){GLctx.uniform2i(GL.uniforms[location],v0,v1)}function _emscripten_glUniform2iv(location,count,value){if(count<=144){var view=__miniTempWebGLIntBuffers[2*count-1];for(var i=0;i<2*count;i+=2){view[i]=HEAP32[value+4*i>>2];view[i+1]=HEAP32[value+(4*i+4)>>2]}}else{var view=HEAP32.subarray(value>>2,value+count*8>>2)}GLctx.uniform2iv(GL.uniforms[location],view)}function _emscripten_glUniform3f(location,v0,v1,v2){GLctx.uniform3f(GL.uniforms[location],v0,v1,v2)}function _emscripten_glUniform3fv(location,count,value){if(count<=96){var view=miniTempWebGLFloatBuffers[3*count-1];for(var i=0;i<3*count;i+=3){view[i]=HEAPF32[value+4*i>>2];view[i+1]=HEAPF32[value+(4*i+4)>>2];view[i+2]=HEAPF32[value+(4*i+8)>>2]}}else{var view=HEAPF32.subarray(value>>2,value+count*12>>2)}GLctx.uniform3fv(GL.uniforms[location],view)}function _emscripten_glUniform3i(location,v0,v1,v2){GLctx.uniform3i(GL.uniforms[location],v0,v1,v2)}function _emscripten_glUniform3iv(location,count,value){if(count<=96){var view=__miniTempWebGLIntBuffers[3*count-1];for(var i=0;i<3*count;i+=3){view[i]=HEAP32[value+4*i>>2];view[i+1]=HEAP32[value+(4*i+4)>>2];view[i+2]=HEAP32[value+(4*i+8)>>2]}}else{var view=HEAP32.subarray(value>>2,value+count*12>>2)}GLctx.uniform3iv(GL.uniforms[location],view)}function _emscripten_glUniform4f(location,v0,v1,v2,v3){GLctx.uniform4f(GL.uniforms[location],v0,v1,v2,v3)}function _emscripten_glUniform4fv(location,count,value){if(count<=72){var view=miniTempWebGLFloatBuffers[4*count-1];var heap=HEAPF32;value>>=2;for(var i=0;i<4*count;i+=4){var dst=value+i;view[i]=heap[dst];view[i+1]=heap[dst+1];view[i+2]=heap[dst+2];view[i+3]=heap[dst+3]}}else{var view=HEAPF32.subarray(value>>2,value+count*16>>2)}GLctx.uniform4fv(GL.uniforms[location],view)}function _emscripten_glUniform4i(location,v0,v1,v2,v3){GLctx.uniform4i(GL.uniforms[location],v0,v1,v2,v3)}function _emscripten_glUniform4iv(location,count,value){if(count<=72){var view=__miniTempWebGLIntBuffers[4*count-1];for(var i=0;i<4*count;i+=4){view[i]=HEAP32[value+4*i>>2];view[i+1]=HEAP32[value+(4*i+4)>>2];view[i+2]=HEAP32[value+(4*i+8)>>2];view[i+3]=HEAP32[value+(4*i+12)>>2]}}else{var view=HEAP32.subarray(value>>2,value+count*16>>2)}GLctx.uniform4iv(GL.uniforms[location],view)}function _emscripten_glUniformMatrix2fv(location,count,transpose,value){if(count<=72){var view=miniTempWebGLFloatBuffers[4*count-1];for(var i=0;i<4*count;i+=4){view[i]=HEAPF32[value+4*i>>2];view[i+1]=HEAPF32[value+(4*i+4)>>2];view[i+2]=HEAPF32[value+(4*i+8)>>2];view[i+3]=HEAPF32[value+(4*i+12)>>2]}}else{var view=HEAPF32.subarray(value>>2,value+count*16>>2)}GLctx.uniformMatrix2fv(GL.uniforms[location],!!transpose,view)}function _emscripten_glUniformMatrix3fv(location,count,transpose,value){if(count<=32){var view=miniTempWebGLFloatBuffers[9*count-1];for(var i=0;i<9*count;i+=9){view[i]=HEAPF32[value+4*i>>2];view[i+1]=HEAPF32[value+(4*i+4)>>2];view[i+2]=HEAPF32[value+(4*i+8)>>2];view[i+3]=HEAPF32[value+(4*i+12)>>2];view[i+4]=HEAPF32[value+(4*i+16)>>2];view[i+5]=HEAPF32[value+(4*i+20)>>2];view[i+6]=HEAPF32[value+(4*i+24)>>2];view[i+7]=HEAPF32[value+(4*i+28)>>2];view[i+8]=HEAPF32[value+(4*i+32)>>2]}}else{var view=HEAPF32.subarray(value>>2,value+count*36>>2)}GLctx.uniformMatrix3fv(GL.uniforms[location],!!transpose,view)}function _emscripten_glUniformMatrix4fv(location,count,transpose,value){if(count<=18){var view=miniTempWebGLFloatBuffers[16*count-1];var heap=HEAPF32;value>>=2;for(var i=0;i<16*count;i+=16){var dst=value+i;view[i]=heap[dst];view[i+1]=heap[dst+1];view[i+2]=heap[dst+2];view[i+3]=heap[dst+3];view[i+4]=heap[dst+4];view[i+5]=heap[dst+5];view[i+6]=heap[dst+6];view[i+7]=heap[dst+7];view[i+8]=heap[dst+8];view[i+9]=heap[dst+9];view[i+10]=heap[dst+10];view[i+11]=heap[dst+11];view[i+12]=heap[dst+12];view[i+13]=heap[dst+13];view[i+14]=heap[dst+14];view[i+15]=heap[dst+15]}}else{var view=HEAPF32.subarray(value>>2,value+count*64>>2)}GLctx.uniformMatrix4fv(GL.uniforms[location],!!transpose,view)}function _emscripten_glUseProgram(program){GLctx.useProgram(GL.programs[program])}function _emscripten_glValidateProgram(program){GLctx.validateProgram(GL.programs[program])}function _emscripten_glVertexAttrib1f(x0,x1){GLctx["vertexAttrib1f"](x0,x1)}function _emscripten_glVertexAttrib1fv(index,v){GLctx.vertexAttrib1f(index,HEAPF32[v>>2])}function _emscripten_glVertexAttrib2f(x0,x1,x2){GLctx["vertexAttrib2f"](x0,x1,x2)}function _emscripten_glVertexAttrib2fv(index,v){GLctx.vertexAttrib2f(index,HEAPF32[v>>2],HEAPF32[v+4>>2])}function _emscripten_glVertexAttrib3f(x0,x1,x2,x3){GLctx["vertexAttrib3f"](x0,x1,x2,x3)}function _emscripten_glVertexAttrib3fv(index,v){GLctx.vertexAttrib3f(index,HEAPF32[v>>2],HEAPF32[v+4>>2],HEAPF32[v+8>>2])}function _emscripten_glVertexAttrib4f(x0,x1,x2,x3,x4){GLctx["vertexAttrib4f"](x0,x1,x2,x3,x4)}function _emscripten_glVertexAttrib4fv(index,v){GLctx.vertexAttrib4f(index,HEAPF32[v>>2],HEAPF32[v+4>>2],HEAPF32[v+8>>2],HEAPF32[v+12>>2])}function _emscripten_glVertexAttribDivisorANGLE(index,divisor){GLctx["vertexAttribDivisor"](index,divisor)}function _emscripten_glVertexAttribPointer(index,size,type,normalized,stride,ptr){GLctx.vertexAttribPointer(index,size,type,!!normalized,stride,ptr)}function _emscripten_glViewport(x0,x1,x2,x3){GLctx["viewport"](x0,x1,x2,x3)}function _emscripten_has_asyncify(){return 1}function _emscripten_is_main_browser_thread(){return!ENVIRONMENT_IS_WORKER}function _emscripten_memcpy_big(dest,src,num){HEAPU8.copyWithin(dest,src,src+num)}function __emscripten_do_request_fullscreen(target,strategy){if(!JSEvents.fullscreenEnabled())return-1;target=findEventTarget(target);if(!target)return-4;if(!target.requestFullscreen&&!target.webkitRequestFullscreen){return-3}var canPerformRequests=JSEvents.canPerformEventHandlerRequests();if(!canPerformRequests){if(strategy.deferUntilInEventHandler){JSEvents.deferCall(_JSEvents_requestFullscreen,1,[target,strategy]);return 1}else{return-2}}return _JSEvents_requestFullscreen(target,strategy)}function _emscripten_request_fullscreen_strategy(target,deferUntilInEventHandler,fullscreenStrategy){var strategy={scaleMode:HEAP32[fullscreenStrategy>>2],canvasResolutionScaleMode:HEAP32[fullscreenStrategy+4>>2],filteringMode:HEAP32[fullscreenStrategy+8>>2],deferUntilInEventHandler:deferUntilInEventHandler,canvasResizedCallback:HEAP32[fullscreenStrategy+12>>2],canvasResizedCallbackUserData:HEAP32[fullscreenStrategy+16>>2]};return __emscripten_do_request_fullscreen(target,strategy)}function _emscripten_request_pointerlock(target,deferUntilInEventHandler){target=findEventTarget(target);if(!target)return-4;if(!target.requestPointerLock&&!target.msRequestPointerLock){return-1}var canPerformRequests=JSEvents.canPerformEventHandlerRequests();if(!canPerformRequests){if(deferUntilInEventHandler){JSEvents.deferCall(__requestPointerLock,2,[target]);return 1}else{return-2}}return __requestPointerLock(target)}function abortOnCannotGrowMemory(requestedSize){abort("OOM")}function _emscripten_resize_heap(requestedSize){requestedSize=requestedSize>>>0;abortOnCannotGrowMemory(requestedSize)}function _emscripten_generate_pc(frame){var match;if(match=/\bwasm-function\[\d+\]:(0x[0-9a-f]+)/.exec(frame)){return+match[1]}else if(match=/\bwasm-function\[(\d+)\]:(\d+)/.exec(frame)){return wasmOffsetConverter.convert(+match[1],+match[2])}else if(match=/:(\d+):\d+(?:\)|$)/.exec(frame)){return 2147483648|+match[1]}else{return 0}}function _emscripten_return_address(level){var callstack=(new Error).stack.split("\n");if(callstack[0]=="Error"){callstack.shift()}return _emscripten_generate_pc(callstack[level+2])}function _emscripten_sample_gamepad_data(){return(JSEvents.lastGamepadState=navigator.getGamepads?navigator.getGamepads():navigator.webkitGetGamepads?navigator.webkitGetGamepads():null)?0:-1}function __registerBeforeUnloadEventCallback(target,userData,useCapture,callbackfunc,eventTypeId,eventTypeString){var beforeUnloadEventHandlerFunc=function(ev){var e=ev||event;var confirmationMessage=getDynCaller("iiii",callbackfunc)(eventTypeId,0,userData);if(confirmationMessage){confirmationMessage=UTF8ToString(confirmationMessage)}if(confirmationMessage){e.preventDefault();e.returnValue=confirmationMessage;return confirmationMessage}};var eventHandler={target:findEventTarget(target),eventTypeString:eventTypeString,callbackfunc:callbackfunc,handlerFunc:beforeUnloadEventHandlerFunc,useCapture:useCapture};JSEvents.registerOrRemoveHandler(eventHandler)}function _emscripten_set_beforeunload_callback_on_thread(userData,callbackfunc,targetThread){if(typeof onbeforeunload==="undefined")return-1;if(targetThread!==1)return-5;__registerBeforeUnloadEventCallback(2,userData,true,callbackfunc,28,"beforeunload");return 0}function __registerFocusEventCallback(target,userData,useCapture,callbackfunc,eventTypeId,eventTypeString,targetThread){if(!JSEvents.focusEvent)JSEvents.focusEvent=_malloc(256);var focusEventHandlerFunc=function(ev){var e=ev||event;var nodeName=JSEvents.getNodeNameForTarget(e.target);var id=e.target.id?e.target.id:"";var focusEvent=JSEvents.focusEvent;stringToUTF8(nodeName,focusEvent+0,128);stringToUTF8(id,focusEvent+128,128);if(getDynCaller("iiii",callbackfunc)(eventTypeId,focusEvent,userData))e.preventDefault()};var eventHandler={target:findEventTarget(target),eventTypeString:eventTypeString,callbackfunc:callbackfunc,handlerFunc:focusEventHandlerFunc,useCapture:useCapture};JSEvents.registerOrRemoveHandler(eventHandler)}function _emscripten_set_blur_callback_on_thread(target,userData,useCapture,callbackfunc,targetThread){__registerFocusEventCallback(target,userData,useCapture,callbackfunc,12,"blur",targetThread);return 0}function _emscripten_set_element_css_size(target,width,height){target=findEventTarget(target);if(!target)return-4;target.style.width=width+"px";target.style.height=height+"px";return 0}function _emscripten_set_focus_callback_on_thread(target,userData,useCapture,callbackfunc,targetThread){__registerFocusEventCallback(target,userData,useCapture,callbackfunc,13,"focus",targetThread);return 0}function __fillFullscreenChangeEventData(eventStruct){var fullscreenElement=document.fullscreenElement||document.mozFullScreenElement||document.webkitFullscreenElement||document.msFullscreenElement;var isFullscreen=!!fullscreenElement;HEAP32[eventStruct>>2]=isFullscreen;HEAP32[eventStruct+4>>2]=JSEvents.fullscreenEnabled();var reportedElement=isFullscreen?fullscreenElement:JSEvents.previousFullscreenElement;var nodeName=JSEvents.getNodeNameForTarget(reportedElement);var id=reportedElement&&reportedElement.id?reportedElement.id:"";stringToUTF8(nodeName,eventStruct+8,128);stringToUTF8(id,eventStruct+136,128);HEAP32[eventStruct+264>>2]=reportedElement?reportedElement.clientWidth:0;HEAP32[eventStruct+268>>2]=reportedElement?reportedElement.clientHeight:0;HEAP32[eventStruct+272>>2]=screen.width;HEAP32[eventStruct+276>>2]=screen.height;if(isFullscreen){JSEvents.previousFullscreenElement=fullscreenElement}}function __registerFullscreenChangeEventCallback(target,userData,useCapture,callbackfunc,eventTypeId,eventTypeString,targetThread){if(!JSEvents.fullscreenChangeEvent)JSEvents.fullscreenChangeEvent=_malloc(280);var fullscreenChangeEventhandlerFunc=function(ev){var e=ev||event;var fullscreenChangeEvent=JSEvents.fullscreenChangeEvent;__fillFullscreenChangeEventData(fullscreenChangeEvent);if(getDynCaller("iiii",callbackfunc)(eventTypeId,fullscreenChangeEvent,userData))e.preventDefault()};var eventHandler={target:target,eventTypeString:eventTypeString,callbackfunc:callbackfunc,handlerFunc:fullscreenChangeEventhandlerFunc,useCapture:useCapture};JSEvents.registerOrRemoveHandler(eventHandler)}function _emscripten_set_fullscreenchange_callback_on_thread(target,userData,useCapture,callbackfunc,targetThread){if(!JSEvents.fullscreenEnabled())return-1;target=findEventTarget(target);if(!target)return-4;__registerFullscreenChangeEventCallback(target,userData,useCapture,callbackfunc,19,"fullscreenchange",targetThread);__registerFullscreenChangeEventCallback(target,userData,useCapture,callbackfunc,19,"webkitfullscreenchange",targetThread);return 0}function __registerGamepadEventCallback(target,userData,useCapture,callbackfunc,eventTypeId,eventTypeString,targetThread){if(!JSEvents.gamepadEvent)JSEvents.gamepadEvent=_malloc(1432);var gamepadEventHandlerFunc=function(ev){var e=ev||event;var gamepadEvent=JSEvents.gamepadEvent;__fillGamepadEventData(gamepadEvent,e["gamepad"]);if(getDynCaller("iiii",callbackfunc)(eventTypeId,gamepadEvent,userData))e.preventDefault()};var eventHandler={target:findEventTarget(target),allowsDeferredCalls:true,eventTypeString:eventTypeString,callbackfunc:callbackfunc,handlerFunc:gamepadEventHandlerFunc,useCapture:useCapture};JSEvents.registerOrRemoveHandler(eventHandler)}function _emscripten_set_gamepadconnected_callback_on_thread(userData,useCapture,callbackfunc,targetThread){if(!navigator.getGamepads&&!navigator.webkitGetGamepads)return-1;__registerGamepadEventCallback(2,userData,useCapture,callbackfunc,26,"gamepadconnected",targetThread);return 0}function _emscripten_set_gamepaddisconnected_callback_on_thread(userData,useCapture,callbackfunc,targetThread){if(!navigator.getGamepads&&!navigator.webkitGetGamepads)return-1;__registerGamepadEventCallback(2,userData,useCapture,callbackfunc,27,"gamepaddisconnected",targetThread);return 0}function __registerKeyEventCallback(target,userData,useCapture,callbackfunc,eventTypeId,eventTypeString,targetThread){if(!JSEvents.keyEvent)JSEvents.keyEvent=_malloc(164);var keyEventHandlerFunc=function(e){var keyEventData=JSEvents.keyEvent;var idx=keyEventData>>2;HEAP32[idx+0]=e.location;HEAP32[idx+1]=e.ctrlKey;HEAP32[idx+2]=e.shiftKey;HEAP32[idx+3]=e.altKey;HEAP32[idx+4]=e.metaKey;HEAP32[idx+5]=e.repeat;HEAP32[idx+6]=e.charCode;HEAP32[idx+7]=e.keyCode;HEAP32[idx+8]=e.which;stringToUTF8(e.key||"",keyEventData+36,32);stringToUTF8(e.code||"",keyEventData+68,32);stringToUTF8(e.char||"",keyEventData+100,32);stringToUTF8(e.locale||"",keyEventData+132,32);if(getDynCaller("iiii",callbackfunc)(eventTypeId,keyEventData,userData))e.preventDefault()};var eventHandler={target:findEventTarget(target),allowsDeferredCalls:true,eventTypeString:eventTypeString,callbackfunc:callbackfunc,handlerFunc:keyEventHandlerFunc,useCapture:useCapture};JSEvents.registerOrRemoveHandler(eventHandler)}function _emscripten_set_keydown_callback_on_thread(target,userData,useCapture,callbackfunc,targetThread){__registerKeyEventCallback(target,userData,useCapture,callbackfunc,2,"keydown",targetThread);return 0}function _emscripten_set_keypress_callback_on_thread(target,userData,useCapture,callbackfunc,targetThread){__registerKeyEventCallback(target,userData,useCapture,callbackfunc,1,"keypress",targetThread);return 0}function _emscripten_set_keyup_callback_on_thread(target,userData,useCapture,callbackfunc,targetThread){__registerKeyEventCallback(target,userData,useCapture,callbackfunc,3,"keyup",targetThread);return 0}function _emscripten_set_main_loop_arg(func,arg,fps,simulateInfiniteLoop){var browserIterationFunc=function(){getDynCaller("vi",func)(arg)};setMainLoop(browserIterationFunc,fps,simulateInfiniteLoop,arg)}function __fillMouseEventData(eventStruct,e,target){var idx=eventStruct>>2;HEAP32[idx+0]=e.screenX;HEAP32[idx+1]=e.screenY;HEAP32[idx+2]=e.clientX;HEAP32[idx+3]=e.clientY;HEAP32[idx+4]=e.ctrlKey;HEAP32[idx+5]=e.shiftKey;HEAP32[idx+6]=e.altKey;HEAP32[idx+7]=e.metaKey;HEAP16[idx*2+16]=e.button;HEAP16[idx*2+17]=e.buttons;HEAP32[idx+9]=e["movementX"];HEAP32[idx+10]=e["movementY"];var rect=__getBoundingClientRect(target);HEAP32[idx+11]=e.clientX-rect.left;HEAP32[idx+12]=e.clientY-rect.top}function __registerMouseEventCallback(target,userData,useCapture,callbackfunc,eventTypeId,eventTypeString,targetThread){if(!JSEvents.mouseEvent)JSEvents.mouseEvent=_malloc(64);target=findEventTarget(target);var mouseEventHandlerFunc=function(ev){var e=ev||event;__fillMouseEventData(JSEvents.mouseEvent,e,target);if(getDynCaller("iiii",callbackfunc)(eventTypeId,JSEvents.mouseEvent,userData))e.preventDefault()};var eventHandler={target:target,allowsDeferredCalls:eventTypeString!="mousemove"&&eventTypeString!="mouseenter"&&eventTypeString!="mouseleave",eventTypeString:eventTypeString,callbackfunc:callbackfunc,handlerFunc:mouseEventHandlerFunc,useCapture:useCapture};JSEvents.registerOrRemoveHandler(eventHandler)}function _emscripten_set_mousedown_callback_on_thread(target,userData,useCapture,callbackfunc,targetThread){__registerMouseEventCallback(target,userData,useCapture,callbackfunc,5,"mousedown",targetThread);return 0}function _emscripten_set_mouseenter_callback_on_thread(target,userData,useCapture,callbackfunc,targetThread){__registerMouseEventCallback(target,userData,useCapture,callbackfunc,33,"mouseenter",targetThread);return 0}function _emscripten_set_mouseleave_callback_on_thread(target,userData,useCapture,callbackfunc,targetThread){__registerMouseEventCallback(target,userData,useCapture,callbackfunc,34,"mouseleave",targetThread);return 0}function _emscripten_set_mousemove_callback_on_thread(target,userData,useCapture,callbackfunc,targetThread){__registerMouseEventCallback(target,userData,useCapture,callbackfunc,8,"mousemove",targetThread);return 0}function _emscripten_set_mouseup_callback_on_thread(target,userData,useCapture,callbackfunc,targetThread){__registerMouseEventCallback(target,userData,useCapture,callbackfunc,6,"mouseup",targetThread);return 0}function __fillPointerlockChangeEventData(eventStruct){var pointerLockElement=document.pointerLockElement||document.mozPointerLockElement||document.webkitPointerLockElement||document.msPointerLockElement;var isPointerlocked=!!pointerLockElement;HEAP32[eventStruct>>2]=isPointerlocked;var nodeName=JSEvents.getNodeNameForTarget(pointerLockElement);var id=pointerLockElement&&pointerLockElement.id?pointerLockElement.id:"";stringToUTF8(nodeName,eventStruct+4,128);stringToUTF8(id,eventStruct+132,128)}function __registerPointerlockChangeEventCallback(target,userData,useCapture,callbackfunc,eventTypeId,eventTypeString,targetThread){if(!JSEvents.pointerlockChangeEvent)JSEvents.pointerlockChangeEvent=_malloc(260);var pointerlockChangeEventHandlerFunc=function(ev){var e=ev||event;var pointerlockChangeEvent=JSEvents.pointerlockChangeEvent;__fillPointerlockChangeEventData(pointerlockChangeEvent);if(getDynCaller("iiii",callbackfunc)(eventTypeId,pointerlockChangeEvent,userData))e.preventDefault()};var eventHandler={target:target,eventTypeString:eventTypeString,callbackfunc:callbackfunc,handlerFunc:pointerlockChangeEventHandlerFunc,useCapture:useCapture};JSEvents.registerOrRemoveHandler(eventHandler)}function _emscripten_set_pointerlockchange_callback_on_thread(target,userData,useCapture,callbackfunc,targetThread){if(!document||!document.body||!document.body.requestPointerLock&&!document.body.mozRequestPointerLock&&!document.body.webkitRequestPointerLock&&!document.body.msRequestPointerLock){return-1}target=findEventTarget(target);if(!target)return-4;__registerPointerlockChangeEventCallback(target,userData,useCapture,callbackfunc,20,"pointerlockchange",targetThread);__registerPointerlockChangeEventCallback(target,userData,useCapture,callbackfunc,20,"mozpointerlockchange",targetThread);__registerPointerlockChangeEventCallback(target,userData,useCapture,callbackfunc,20,"webkitpointerlockchange",targetThread);__registerPointerlockChangeEventCallback(target,userData,useCapture,callbackfunc,20,"mspointerlockchange",targetThread);return 0}function __registerUiEventCallback(target,userData,useCapture,callbackfunc,eventTypeId,eventTypeString,targetThread){if(!JSEvents.uiEvent)JSEvents.uiEvent=_malloc(36);target=findEventTarget(target);var uiEventHandlerFunc=function(ev){var e=ev||event;if(e.target!=target){return}var b=document.body;if(!b){return}var uiEvent=JSEvents.uiEvent;HEAP32[uiEvent>>2]=e.detail;HEAP32[uiEvent+4>>2]=b.clientWidth;HEAP32[uiEvent+8>>2]=b.clientHeight;HEAP32[uiEvent+12>>2]=innerWidth;HEAP32[uiEvent+16>>2]=innerHeight;HEAP32[uiEvent+20>>2]=outerWidth;HEAP32[uiEvent+24>>2]=outerHeight;HEAP32[uiEvent+28>>2]=pageXOffset;HEAP32[uiEvent+32>>2]=pageYOffset;if(getDynCaller("iiii",callbackfunc)(eventTypeId,uiEvent,userData))e.preventDefault()};var eventHandler={target:target,eventTypeString:eventTypeString,callbackfunc:callbackfunc,handlerFunc:uiEventHandlerFunc,useCapture:useCapture};JSEvents.registerOrRemoveHandler(eventHandler)}function _emscripten_set_resize_callback_on_thread(target,userData,useCapture,callbackfunc,targetThread){__registerUiEventCallback(target,userData,useCapture,callbackfunc,10,"resize",targetThread);return 0}function __registerTouchEventCallback(target,userData,useCapture,callbackfunc,eventTypeId,eventTypeString,targetThread){if(!JSEvents.touchEvent)JSEvents.touchEvent=_malloc(1684);target=findEventTarget(target);var touchEventHandlerFunc=function(e){var touches={};var et=e.touches;for(var i=0;i>2;HEAP32[idx+1]=e.ctrlKey;HEAP32[idx+2]=e.shiftKey;HEAP32[idx+3]=e.altKey;HEAP32[idx+4]=e.metaKey;idx+=5;var targetRect=__getBoundingClientRect(target);var numTouches=0;for(var i in touches){var t=touches[i];HEAP32[idx+0]=t.identifier;HEAP32[idx+1]=t.screenX;HEAP32[idx+2]=t.screenY;HEAP32[idx+3]=t.clientX;HEAP32[idx+4]=t.clientY;HEAP32[idx+5]=t.pageX;HEAP32[idx+6]=t.pageY;HEAP32[idx+7]=t.isChanged;HEAP32[idx+8]=t.onTarget;HEAP32[idx+9]=t.clientX-targetRect.left;HEAP32[idx+10]=t.clientY-targetRect.top;idx+=13;if(++numTouches>31){break}}HEAP32[touchEvent>>2]=numTouches;if(getDynCaller("iiii",callbackfunc)(eventTypeId,touchEvent,userData))e.preventDefault()};var eventHandler={target:target,allowsDeferredCalls:eventTypeString=="touchstart"||eventTypeString=="touchend",eventTypeString:eventTypeString,callbackfunc:callbackfunc,handlerFunc:touchEventHandlerFunc,useCapture:useCapture};JSEvents.registerOrRemoveHandler(eventHandler)}function _emscripten_set_touchcancel_callback_on_thread(target,userData,useCapture,callbackfunc,targetThread){__registerTouchEventCallback(target,userData,useCapture,callbackfunc,25,"touchcancel",targetThread);return 0}function _emscripten_set_touchend_callback_on_thread(target,userData,useCapture,callbackfunc,targetThread){__registerTouchEventCallback(target,userData,useCapture,callbackfunc,23,"touchend",targetThread);return 0}function _emscripten_set_touchmove_callback_on_thread(target,userData,useCapture,callbackfunc,targetThread){__registerTouchEventCallback(target,userData,useCapture,callbackfunc,24,"touchmove",targetThread);return 0}function _emscripten_set_touchstart_callback_on_thread(target,userData,useCapture,callbackfunc,targetThread){__registerTouchEventCallback(target,userData,useCapture,callbackfunc,22,"touchstart",targetThread);return 0}function __fillVisibilityChangeEventData(eventStruct){var visibilityStates=["hidden","visible","prerender","unloaded"];var visibilityState=visibilityStates.indexOf(document.visibilityState);HEAP32[eventStruct>>2]=document.hidden;HEAP32[eventStruct+4>>2]=visibilityState}function __registerVisibilityChangeEventCallback(target,userData,useCapture,callbackfunc,eventTypeId,eventTypeString,targetThread){if(!JSEvents.visibilityChangeEvent)JSEvents.visibilityChangeEvent=_malloc(8);var visibilityChangeEventHandlerFunc=function(ev){var e=ev||event;var visibilityChangeEvent=JSEvents.visibilityChangeEvent;__fillVisibilityChangeEventData(visibilityChangeEvent);if(getDynCaller("iiii",callbackfunc)(eventTypeId,visibilityChangeEvent,userData))e.preventDefault()};var eventHandler={target:target,eventTypeString:eventTypeString,callbackfunc:callbackfunc,handlerFunc:visibilityChangeEventHandlerFunc,useCapture:useCapture};JSEvents.registerOrRemoveHandler(eventHandler)}function _emscripten_set_visibilitychange_callback_on_thread(userData,useCapture,callbackfunc,targetThread){if(!specialHTMLTargets[1]){return-4}__registerVisibilityChangeEventCallback(specialHTMLTargets[1],userData,useCapture,callbackfunc,21,"visibilitychange",targetThread);return 0}function __registerWheelEventCallback(target,userData,useCapture,callbackfunc,eventTypeId,eventTypeString,targetThread){if(!JSEvents.wheelEvent)JSEvents.wheelEvent=_malloc(96);var wheelHandlerFunc=function(ev){var e=ev||event;var wheelEvent=JSEvents.wheelEvent;__fillMouseEventData(wheelEvent,e,target);HEAPF64[wheelEvent+64>>3]=e["deltaX"];HEAPF64[wheelEvent+72>>3]=e["deltaY"];HEAPF64[wheelEvent+80>>3]=e["deltaZ"];HEAP32[wheelEvent+88>>2]=e["deltaMode"];if(getDynCaller("iiii",callbackfunc)(eventTypeId,wheelEvent,userData))e.preventDefault()};var eventHandler={target:target,allowsDeferredCalls:true,eventTypeString:eventTypeString,callbackfunc:callbackfunc,handlerFunc:wheelHandlerFunc,useCapture:useCapture};JSEvents.registerOrRemoveHandler(eventHandler)}function _emscripten_set_wheel_callback_on_thread(target,userData,useCapture,callbackfunc,targetThread){target=findEventTarget(target);if(typeof target.onwheel!=="undefined"){__registerWheelEventCallback(target,userData,useCapture,callbackfunc,9,"wheel",targetThread);return 0}else{return-1}}function _emscripten_sleep(ms){Asyncify.handleSleep(function(wakeUp){Browser.safeSetTimeout(wakeUp,ms)})}var Fetch={xhrs:[],setu64:function(addr,val){HEAPU32[addr>>2]=val;HEAPU32[addr+4>>2]=val/4294967296|0},openDatabase:function(dbname,dbversion,onsuccess,onerror){try{var openRequest=indexedDB.open(dbname,dbversion)}catch(e){return onerror(e)}openRequest.onupgradeneeded=function(event){var db=event.target.result;if(db.objectStoreNames.contains("FILES")){db.deleteObjectStore("FILES")}db.createObjectStore("FILES")};openRequest.onsuccess=function(event){onsuccess(event.target.result)};openRequest.onerror=function(error){onerror(error)}},staticInit:function(){var isMainThread=true;var onsuccess=function(db){Fetch.dbInstance=db;if(isMainThread){removeRunDependency("library_fetch_init")}};var onerror=function(){Fetch.dbInstance=false;if(isMainThread){removeRunDependency("library_fetch_init")}};Fetch.openDatabase("emscripten_filesystem",1,onsuccess,onerror);if(typeof ENVIRONMENT_IS_FETCH_WORKER==="undefined"||!ENVIRONMENT_IS_FETCH_WORKER)addRunDependency("library_fetch_init")}};function __emscripten_fetch_xhr(fetch,onsuccess,onerror,onprogress,onreadystatechange){var url=HEAPU32[fetch+8>>2];if(!url){onerror(fetch,0,"no url specified!");return}var url_=UTF8ToString(url);var fetch_attr=fetch+112;var requestMethod=UTF8ToString(fetch_attr);if(!requestMethod)requestMethod="GET";var userData=HEAPU32[fetch+4>>2];var fetchAttributes=HEAPU32[fetch_attr+52>>2];var timeoutMsecs=HEAPU32[fetch_attr+56>>2];var withCredentials=!!HEAPU32[fetch_attr+60>>2];var destinationPath=HEAPU32[fetch_attr+64>>2];var userName=HEAPU32[fetch_attr+68>>2];var password=HEAPU32[fetch_attr+72>>2];var requestHeaders=HEAPU32[fetch_attr+76>>2];var overriddenMimeType=HEAPU32[fetch_attr+80>>2];var dataPtr=HEAPU32[fetch_attr+84>>2];var dataLength=HEAPU32[fetch_attr+88>>2];var fetchAttrLoadToMemory=!!(fetchAttributes&1);var fetchAttrStreamData=!!(fetchAttributes&2);var fetchAttrSynchronous=!!(fetchAttributes&64);var userNameStr=userName?UTF8ToString(userName):undefined;var passwordStr=password?UTF8ToString(password):undefined;var overriddenMimeTypeStr=overriddenMimeType?UTF8ToString(overriddenMimeType):undefined;var xhr=new XMLHttpRequest;xhr.withCredentials=withCredentials;xhr.open(requestMethod,url_,!fetchAttrSynchronous,userNameStr,passwordStr);if(!fetchAttrSynchronous)xhr.timeout=timeoutMsecs;xhr.url_=url_;xhr.responseType="arraybuffer";if(overriddenMimeType){xhr.overrideMimeType(overriddenMimeTypeStr)}if(requestHeaders){for(;;){var key=HEAPU32[requestHeaders>>2];if(!key)break;var value=HEAPU32[requestHeaders+4>>2];if(!value)break;requestHeaders+=8;var keyStr=UTF8ToString(key);var valueStr=UTF8ToString(value);xhr.setRequestHeader(keyStr,valueStr)}}Fetch.xhrs.push(xhr);var id=Fetch.xhrs.length;HEAPU32[fetch+0>>2]=id;var data=dataPtr&&dataLength?HEAPU8.slice(dataPtr,dataPtr+dataLength):null;function saveResponse(condition){var ptr=0;var ptrLen=0;if(condition){ptrLen=xhr.response?xhr.response.byteLength:0;ptr=_malloc(ptrLen);HEAPU8.set(new Uint8Array(xhr.response),ptr)}HEAPU32[fetch+12>>2]=ptr;Fetch.setu64(fetch+16,ptrLen)}xhr.onload=function(e){saveResponse(fetchAttrLoadToMemory&&!fetchAttrStreamData);var len=xhr.response?xhr.response.byteLength:0;Fetch.setu64(fetch+24,0);if(len){Fetch.setu64(fetch+32,len)}HEAPU16[fetch+40>>1]=xhr.readyState;HEAPU16[fetch+42>>1]=xhr.status;if(xhr.statusText)stringToUTF8(xhr.statusText,fetch+44,64);if(xhr.status>=200&&xhr.status<300){if(onsuccess)onsuccess(fetch,xhr,e)}else{if(onerror)onerror(fetch,xhr,e)}};xhr.onerror=function(e){saveResponse(fetchAttrLoadToMemory);var status=xhr.status;Fetch.setu64(fetch+24,0);Fetch.setu64(fetch+32,xhr.response?xhr.response.byteLength:0);HEAPU16[fetch+40>>1]=xhr.readyState;HEAPU16[fetch+42>>1]=status;if(onerror)onerror(fetch,xhr,e)};xhr.ontimeout=function(e){if(onerror)onerror(fetch,xhr,e)};xhr.onprogress=function(e){var ptrLen=fetchAttrLoadToMemory&&fetchAttrStreamData&&xhr.response?xhr.response.byteLength:0;var ptr=0;if(fetchAttrLoadToMemory&&fetchAttrStreamData){ptr=_malloc(ptrLen);HEAPU8.set(new Uint8Array(xhr.response),ptr)}HEAPU32[fetch+12>>2]=ptr;Fetch.setu64(fetch+16,ptrLen);Fetch.setu64(fetch+24,e.loaded-ptrLen);Fetch.setu64(fetch+32,e.total);HEAPU16[fetch+40>>1]=xhr.readyState;if(xhr.readyState>=3&&xhr.status===0&&e.loaded>0)xhr.status=200;HEAPU16[fetch+42>>1]=xhr.status;if(xhr.statusText)stringToUTF8(xhr.statusText,fetch+44,64);if(onprogress)onprogress(fetch,xhr,e);if(ptr){_free(ptr)}};xhr.onreadystatechange=function(e){HEAPU16[fetch+40>>1]=xhr.readyState;if(xhr.readyState>=2){HEAPU16[fetch+42>>1]=xhr.status}if(onreadystatechange)onreadystatechange(fetch,xhr,e)};try{xhr.send(data)}catch(e){if(onerror)onerror(fetch,xhr,e)}}function __emscripten_fetch_cache_data(db,fetch,data,onsuccess,onerror){if(!db){onerror(fetch,0,"IndexedDB not available!");return}var fetch_attr=fetch+112;var destinationPath=HEAPU32[fetch_attr+64>>2];if(!destinationPath)destinationPath=HEAPU32[fetch+8>>2];var destinationPathStr=UTF8ToString(destinationPath);try{var transaction=db.transaction(["FILES"],"readwrite");var packages=transaction.objectStore("FILES");var putRequest=packages.put(data,destinationPathStr);putRequest.onsuccess=function(event){HEAPU16[fetch+40>>1]=4;HEAPU16[fetch+42>>1]=200;stringToUTF8("OK",fetch+44,64);onsuccess(fetch,0,destinationPathStr)};putRequest.onerror=function(error){HEAPU16[fetch+40>>1]=4;HEAPU16[fetch+42>>1]=413;stringToUTF8("Payload Too Large",fetch+44,64);onerror(fetch,0,error)}}catch(e){onerror(fetch,0,e)}}function __emscripten_fetch_load_cached_data(db,fetch,onsuccess,onerror){if(!db){onerror(fetch,0,"IndexedDB not available!");return}var fetch_attr=fetch+112;var path=HEAPU32[fetch_attr+64>>2];if(!path)path=HEAPU32[fetch+8>>2];var pathStr=UTF8ToString(path);try{var transaction=db.transaction(["FILES"],"readonly");var packages=transaction.objectStore("FILES");var getRequest=packages.get(pathStr);getRequest.onsuccess=function(event){if(event.target.result){var value=event.target.result;var len=value.byteLength||value.length;var ptr=_malloc(len);HEAPU8.set(new Uint8Array(value),ptr);HEAPU32[fetch+12>>2]=ptr;Fetch.setu64(fetch+16,len);Fetch.setu64(fetch+24,0);Fetch.setu64(fetch+32,len);HEAPU16[fetch+40>>1]=4;HEAPU16[fetch+42>>1]=200;stringToUTF8("OK",fetch+44,64);onsuccess(fetch,0,value)}else{HEAPU16[fetch+40>>1]=4;HEAPU16[fetch+42>>1]=404;stringToUTF8("Not Found",fetch+44,64);onerror(fetch,0,"no data")}};getRequest.onerror=function(error){HEAPU16[fetch+40>>1]=4;HEAPU16[fetch+42>>1]=404;stringToUTF8("Not Found",fetch+44,64);onerror(fetch,0,error)}}catch(e){onerror(fetch,0,e)}}function __emscripten_fetch_delete_cached_data(db,fetch,onsuccess,onerror){if(!db){onerror(fetch,0,"IndexedDB not available!");return}var fetch_attr=fetch+112;var path=HEAPU32[fetch_attr+64>>2];if(!path)path=HEAPU32[fetch+8>>2];var pathStr=UTF8ToString(path);try{var transaction=db.transaction(["FILES"],"readwrite");var packages=transaction.objectStore("FILES");var request=packages.delete(pathStr);request.onsuccess=function(event){var value=event.target.result;HEAPU32[fetch+12>>2]=0;Fetch.setu64(fetch+16,0);Fetch.setu64(fetch+24,0);Fetch.setu64(fetch+32,0);HEAPU16[fetch+40>>1]=4;HEAPU16[fetch+42>>1]=200;stringToUTF8("OK",fetch+44,64);onsuccess(fetch,0,value)};request.onerror=function(error){HEAPU16[fetch+40>>1]=4;HEAPU16[fetch+42>>1]=404;stringToUTF8("Not Found",fetch+44,64);onerror(fetch,0,error)}}catch(e){onerror(fetch,0,e)}}function _emscripten_start_fetch(fetch,successcb,errorcb,progresscb,readystatechangecb){if(typeof noExitRuntime!=="undefined")noExitRuntime=true;var fetch_attr=fetch+112;var requestMethod=UTF8ToString(fetch_attr);var onsuccess=HEAPU32[fetch_attr+36>>2];var onerror=HEAPU32[fetch_attr+40>>2];var onprogress=HEAPU32[fetch_attr+44>>2];var onreadystatechange=HEAPU32[fetch_attr+48>>2];var fetchAttributes=HEAPU32[fetch_attr+52>>2];var fetchAttrPersistFile=!!(fetchAttributes&4);var fetchAttrNoDownload=!!(fetchAttributes&32);var fetchAttrReplace=!!(fetchAttributes&16);var reportSuccess=function(fetch,xhr,e){if(onsuccess)getDynCaller("vi",onsuccess)(fetch);else if(successcb)successcb(fetch)};var reportProgress=function(fetch,xhr,e){if(onprogress)getDynCaller("vi",onprogress)(fetch);else if(progresscb)progresscb(fetch)};var reportError=function(fetch,xhr,e){if(onerror)getDynCaller("vi",onerror)(fetch);else if(errorcb)errorcb(fetch)};var reportReadyStateChange=function(fetch,xhr,e){if(onreadystatechange)getDynCaller("vi",onreadystatechange)(fetch);else if(readystatechangecb)readystatechangecb(fetch)};var performUncachedXhr=function(fetch,xhr,e){__emscripten_fetch_xhr(fetch,reportSuccess,reportError,reportProgress,reportReadyStateChange)};var cacheResultAndReportSuccess=function(fetch,xhr,e){var storeSuccess=function(fetch,xhr,e){if(onsuccess)getDynCaller("vi",onsuccess)(fetch);else if(successcb)successcb(fetch)};var storeError=function(fetch,xhr,e){if(onsuccess)getDynCaller("vi",onsuccess)(fetch);else if(successcb)successcb(fetch)};__emscripten_fetch_cache_data(Fetch.dbInstance,fetch,xhr.response,storeSuccess,storeError)};var performCachedXhr=function(fetch,xhr,e){__emscripten_fetch_xhr(fetch,cacheResultAndReportSuccess,reportError,reportProgress,reportReadyStateChange)};if(requestMethod==="EM_IDB_STORE"){var ptr=HEAPU32[fetch_attr+84>>2];__emscripten_fetch_cache_data(Fetch.dbInstance,fetch,HEAPU8.slice(ptr,ptr+HEAPU32[fetch_attr+88>>2]),reportSuccess,reportError)}else if(requestMethod==="EM_IDB_DELETE"){__emscripten_fetch_delete_cached_data(Fetch.dbInstance,fetch,reportSuccess,reportError)}else if(!fetchAttrReplace){__emscripten_fetch_load_cached_data(Fetch.dbInstance,fetch,reportSuccess,fetchAttrNoDownload?reportError:fetchAttrPersistFile?performCachedXhr:performUncachedXhr)}else if(!fetchAttrNoDownload){__emscripten_fetch_xhr(fetch,fetchAttrPersistFile?cacheResultAndReportSuccess:reportSuccess,reportError,reportProgress,reportReadyStateChange)}else{return 0}return fetch}var ENV={};function getExecutableName(){return thisProgram||"./this.program"}function getEnvStrings(){if(!getEnvStrings.strings){var lang=(typeof navigator==="object"&&navigator.languages&&navigator.languages[0]||"C").replace("-","_")+".UTF-8";var env={"USER":"web_user","LOGNAME":"web_user","PATH":"/","PWD":"/","HOME":"/home/web_user","LANG":lang,"_":getExecutableName()};for(var x in ENV){env[x]=ENV[x]}var strings=[];for(var x in env){strings.push(x+"="+env[x])}getEnvStrings.strings=strings}return getEnvStrings.strings}function _environ_get(__environ,environ_buf){var bufSize=0;getEnvStrings().forEach(function(string,i){var ptr=environ_buf+bufSize;HEAP32[__environ+i*4>>2]=ptr;writeAsciiToMemory(string,ptr);bufSize+=string.length+1});return 0}function _environ_sizes_get(penviron_count,penviron_buf_size){var strings=getEnvStrings();HEAP32[penviron_count>>2]=strings.length;var bufSize=0;strings.forEach(function(string){bufSize+=string.length+1});HEAP32[penviron_buf_size>>2]=bufSize;return 0}function _exit(status){exit(status)}function _fd_close(fd){try{var stream=SYSCALLS.getStreamFromFD(fd);FS.close(stream);return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return e.errno}}function _fd_fdstat_get(fd,pbuf){try{var stream=SYSCALLS.getStreamFromFD(fd);var type=stream.tty?2:FS.isDir(stream.mode)?3:FS.isLink(stream.mode)?7:4;HEAP8[pbuf>>0]=type;return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return e.errno}}function _fd_read(fd,iov,iovcnt,pnum){try{var stream=SYSCALLS.getStreamFromFD(fd);var num=SYSCALLS.doReadv(stream,iov,iovcnt);HEAP32[pnum>>2]=num;return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return e.errno}}function _fd_seek(fd,offset_low,offset_high,whence,newOffset){try{var stream=SYSCALLS.getStreamFromFD(fd);var HIGH_OFFSET=4294967296;var offset=offset_high*HIGH_OFFSET+(offset_low>>>0);var DOUBLE_LIMIT=9007199254740992;if(offset<=-DOUBLE_LIMIT||offset>=DOUBLE_LIMIT){return-61}FS.llseek(stream,offset,whence);tempI64=[stream.position>>>0,(tempDouble=stream.position,+Math.abs(tempDouble)>=1?tempDouble>0?(Math.min(+Math.floor(tempDouble/4294967296),4294967295)|0)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[newOffset>>2]=tempI64[0],HEAP32[newOffset+4>>2]=tempI64[1];if(stream.getdents&&offset===0&&whence===0)stream.getdents=null;return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return e.errno}}function _fd_write(fd,iov,iovcnt,pnum){try{var stream=SYSCALLS.getStreamFromFD(fd);var num=SYSCALLS.doWritev(stream,iov,iovcnt);HEAP32[pnum>>2]=num;return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return e.errno}}function _gettimeofday(ptr){var now=Date.now();HEAP32[ptr>>2]=now/1e3|0;HEAP32[ptr+4>>2]=now%1e3*1e3|0;return 0}function _usleep(useconds){var start=_emscripten_get_now();while(_emscripten_get_now()-start>2];var nanoseconds=HEAP32[rqtp+4>>2];if(nanoseconds<0||nanoseconds>999999999||seconds<0){setErrNo(28);return-1}if(rmtp!==0){HEAP32[rmtp>>2]=0;HEAP32[rmtp+4>>2]=0}return _usleep(seconds*1e6+nanoseconds/1e3)}function _setTempRet0($i){setTempRet0($i|0)}function _sigaction(signum,act,oldact){return 0}var __sigalrm_handler=0;function _signal(sig,func){if(sig==14){__sigalrm_handler=func}else{}return 0}function _system(command){if(ENVIRONMENT_IS_NODE){if(!command)return 1;var cmdstr=UTF8ToString(command);if(!cmdstr.length)return 0;var cp=require("child_process");var ret=cp.spawnSync(cmdstr,[],{shell:true,stdio:"inherit"});var _W_EXITCODE=function(ret,sig){return ret<<8|sig};if(ret.status===null){var signalToNumber=function(sig){switch(sig){case"SIGHUP":return 1;case"SIGINT":return 2;case"SIGQUIT":return 3;case"SIGFPE":return 8;case"SIGKILL":return 9;case"SIGALRM":return 14;case"SIGTERM":return 15}return 2};return _W_EXITCODE(0,signalToNumber(ret.signal))}return _W_EXITCODE(ret.status,0)}if(!command)return 0;setErrNo(6);return-1}var readAsmConstArgsArray=[];function readAsmConstArgs(sigPtr,buf){readAsmConstArgsArray.length=0;var ch;buf>>=2;while(ch=HEAPU8[sigPtr++]){var double=ch<105;if(double&&buf&1)buf++;readAsmConstArgsArray.push(double?HEAPF64[buf++>>1]:HEAP32[buf]);++buf}return readAsmConstArgsArray}function runAndAbortIfError(func){try{return func()}catch(e){abort(e)}}var Asyncify={State:{Normal:0,Unwinding:1,Rewinding:2},state:0,StackSize:4096,currData:null,handleSleepReturnValue:0,exportCallStack:[],callStackNameToId:{},callStackIdToName:{},callStackId:0,afterUnwind:null,asyncFinalizers:[],sleepCallbacks:[],getCallStackId:function(funcName){var id=Asyncify.callStackNameToId[funcName];if(id===undefined){id=Asyncify.callStackId++;Asyncify.callStackNameToId[funcName]=id;Asyncify.callStackIdToName[id]=funcName}return id},instrumentWasmExports:function(exports){var ret={};for(var x in exports){(function(x){var original=exports[x];if(typeof original==="function"){ret[x]=function(){Asyncify.exportCallStack.push(x);try{return original.apply(null,arguments)}finally{if(ABORT)return;var y=Asyncify.exportCallStack.pop();assert(y===x);Asyncify.maybeStopUnwind()}}}else{ret[x]=original}})(x)}return ret},maybeStopUnwind:function(){if(Asyncify.currData&&Asyncify.state===Asyncify.State.Unwinding&&Asyncify.exportCallStack.length===0){Asyncify.state=Asyncify.State.Normal;runAndAbortIfError(Module["_asyncify_stop_unwind"]);if(typeof Fibers!=="undefined"){Fibers.trampoline()}if(Asyncify.afterUnwind){Asyncify.afterUnwind();Asyncify.afterUnwind=null}}},allocateData:function(){var ptr=_malloc(12+Asyncify.StackSize);Asyncify.setDataHeader(ptr,ptr+12,Asyncify.StackSize);Asyncify.setDataRewindFunc(ptr);return ptr},setDataHeader:function(ptr,stack,stackSize){HEAP32[ptr>>2]=stack;HEAP32[ptr+4>>2]=stack+stackSize},setDataRewindFunc:function(ptr){var bottomOfCallStack=Asyncify.exportCallStack[0];var rewindId=Asyncify.getCallStackId(bottomOfCallStack);HEAP32[ptr+8>>2]=rewindId},getDataRewindFunc:function(ptr){var id=HEAP32[ptr+8>>2];var name=Asyncify.callStackIdToName[id];var func=Module["asm"][name];return func},handleSleep:function(startAsync){if(ABORT)return;noExitRuntime=true;if(Asyncify.state===Asyncify.State.Normal){var reachedCallback=false;var reachedAfterCallback=false;startAsync(function(handleSleepReturnValue){if(ABORT)return;Asyncify.handleSleepReturnValue=handleSleepReturnValue||0;reachedCallback=true;if(!reachedAfterCallback){return}Asyncify.state=Asyncify.State.Rewinding;runAndAbortIfError(function(){Module["_asyncify_start_rewind"](Asyncify.currData)});if(typeof Browser!=="undefined"&&Browser.mainLoop.func){Browser.mainLoop.resume()}var start=Asyncify.getDataRewindFunc(Asyncify.currData);var asyncWasmReturnValue=start();if(!Asyncify.currData){var asyncFinalizers=Asyncify.asyncFinalizers;Asyncify.asyncFinalizers=[];asyncFinalizers.forEach(function(func){func(asyncWasmReturnValue)})}});reachedAfterCallback=true;if(!reachedCallback){Asyncify.state=Asyncify.State.Unwinding;Asyncify.currData=Asyncify.allocateData();runAndAbortIfError(function(){Module["_asyncify_start_unwind"](Asyncify.currData)});if(typeof Browser!=="undefined"&&Browser.mainLoop.func){Browser.mainLoop.pause()}}}else if(Asyncify.state===Asyncify.State.Rewinding){Asyncify.state=Asyncify.State.Normal;runAndAbortIfError(Module["_asyncify_stop_rewind"]);_free(Asyncify.currData);Asyncify.currData=null;Asyncify.sleepCallbacks.forEach(function(func){func()})}else{abort("invalid state: "+Asyncify.state)}return Asyncify.handleSleepReturnValue},handleAsync:function(startAsync){return Asyncify.handleSleep(function(wakeUp){startAsync().then(wakeUp)})}};var FSNode=function(parent,name,mode,rdev){if(!parent){parent=this}this.parent=parent;this.mount=parent.mount;this.mounted=null;this.id=FS.nextInode++;this.name=name;this.mode=mode;this.node_ops={};this.stream_ops={};this.rdev=rdev};var readMode=292|73;var writeMode=146;Object.defineProperties(FSNode.prototype,{read:{get:function(){return(this.mode&readMode)===readMode},set:function(val){val?this.mode|=readMode:this.mode&=~readMode}},write:{get:function(){return(this.mode&writeMode)===writeMode},set:function(val){val?this.mode|=writeMode:this.mode&=~writeMode}},isFolder:{get:function(){return FS.isDir(this.mode)}},isDevice:{get:function(){return FS.isChrdev(this.mode)}}});FS.FSNode=FSNode;FS.staticInit();Module["FS_createPath"]=FS.createPath;Module["FS_createDataFile"]=FS.createDataFile;Module["FS_createPreloadedFile"]=FS.createPreloadedFile;Module["FS_createLazyFile"]=FS.createLazyFile;Module["FS_createDevice"]=FS.createDevice;Module["FS_unlink"]=FS.unlink;Module["requestFullscreen"]=function Module_requestFullscreen(lockPointer,resizeCanvas){Browser.requestFullscreen(lockPointer,resizeCanvas)};Module["requestAnimationFrame"]=function Module_requestAnimationFrame(func){Browser.requestAnimationFrame(func)};Module["setCanvasSize"]=function Module_setCanvasSize(width,height,noUpdates){Browser.setCanvasSize(width,height,noUpdates)};Module["pauseMainLoop"]=function Module_pauseMainLoop(){Browser.mainLoop.pause()};Module["resumeMainLoop"]=function Module_resumeMainLoop(){Browser.mainLoop.resume()};Module["getUserMedia"]=function Module_getUserMedia(){Browser.getUserMedia()};Module["createContext"]=function Module_createContext(canvas,useWebGL,setInModule,webGLContextAttributes){return Browser.createContext(canvas,useWebGL,setInModule,webGLContextAttributes)};var GLctx;for(var i=0;i<32;++i)tempFixedLengthArray.push(new Array(i));var miniTempWebGLFloatBuffersStorage=new Float32Array(288);for(var i=0;i<288;++i){miniTempWebGLFloatBuffers[i]=miniTempWebGLFloatBuffersStorage.subarray(0,i+1)}var __miniTempWebGLIntBuffersStorage=new Int32Array(288);for(var i=0;i<288;++i){__miniTempWebGLIntBuffers[i]=__miniTempWebGLIntBuffersStorage.subarray(0,i+1)}Fetch.staticInit();function intArrayFromString(stringy,dontAddNull,length){var len=length>0?length:lengthBytesUTF8(stringy)+1;var u8array=new Array(len);var numBytesWritten=stringToUTF8Array(stringy,u8array,0,u8array.length);if(dontAddNull)u8array.length=numBytesWritten;return u8array}__ATINIT__.push({func:function(){___wasm_call_ctors()}});var asmLibraryArg={"sa":___sys_chdir,"r":___sys_fcntl64,"na":___sys_fstat64,"ua":___sys_getcwd,"va":___sys_getdents64,"qa":___sys_ioctl,"ka":___sys_mkdir,"l":___sys_open,"ra":___sys_readlink,"s":___sys_rmdir,"q":___sys_stat64,"la":___sys_statfs64,"oa":___sys_unlink,"wa":__emscripten_fetch_free,"n":_clock_gettime,"Ca":_dlclose,"cd":_eglBindAPI,"ma":_eglChooseConfig,"lb":_eglCreateContext,"Hb":_eglCreateWindowSurface,"wb":_eglDestroyContext,"Sb":_eglDestroySurface,"ta":_eglGetConfigAttrib,"T":_eglGetDisplay,"ab":_eglGetError,"nd":_eglGetProcAddress,"Id":_eglInitialize,"bc":_eglMakeCurrent,"Ra":_eglQueryString,"mc":_eglSwapBuffers,"xc":_eglSwapInterval,"ca":_eglTerminate,"Tc":_eglWaitGL,"Ic":_eglWaitNative,"b":_emscripten_asm_const_int,"Da":_emscripten_exit_fullscreen,"Ga":_emscripten_exit_pointerlock,"i":_emscripten_get_device_pixel_ratio,"e":_emscripten_get_element_css_size,"v":_emscripten_get_gamepad_status,"Ba":_emscripten_get_num_gamepads,"Ad":_emscripten_glActiveTexture,"zd":_emscripten_glAttachShader,"aa":_emscripten_glBeginQueryEXT,"yd":_emscripten_glBindAttribLocation,"xd":_emscripten_glBindBuffer,"wd":_emscripten_glBindFramebuffer,"vd":_emscripten_glBindRenderbuffer,"ud":_emscripten_glBindTexture,"U":_emscripten_glBindVertexArrayOES,"td":_emscripten_glBlendColor,"sd":_emscripten_glBlendEquation,"rd":_emscripten_glBlendEquationSeparate,"qd":_emscripten_glBlendFunc,"pd":_emscripten_glBlendFuncSeparate,"od":_emscripten_glBufferData,"md":_emscripten_glBufferSubData,"ld":_emscripten_glCheckFramebufferStatus,"kd":_emscripten_glClear,"jd":_emscripten_glClearColor,"id":_emscripten_glClearDepthf,"hd":_emscripten_glClearStencil,"gd":_emscripten_glColorMask,"fd":_emscripten_glCompileShader,"ed":_emscripten_glCompressedTexImage2D,"dd":_emscripten_glCompressedTexSubImage2D,"bd":_emscripten_glCopyTexImage2D,"ad":_emscripten_glCopyTexSubImage2D,"$c":_emscripten_glCreateProgram,"_c":_emscripten_glCreateShader,"Zc":_emscripten_glCullFace,"Yc":_emscripten_glDeleteBuffers,"Xc":_emscripten_glDeleteFramebuffers,"Wc":_emscripten_glDeleteProgram,"da":_emscripten_glDeleteQueriesEXT,"Vc":_emscripten_glDeleteRenderbuffers,"Uc":_emscripten_glDeleteShader,"Sc":_emscripten_glDeleteTextures,"Hd":_emscripten_glDeleteVertexArraysOES,"Rc":_emscripten_glDepthFunc,"Qc":_emscripten_glDepthMask,"Pc":_emscripten_glDepthRangef,"Oc":_emscripten_glDetachShader,"Nc":_emscripten_glDisable,"Mc":_emscripten_glDisableVertexAttribArray,"Lc":_emscripten_glDrawArrays,"Dd":_emscripten_glDrawArraysInstancedANGLE,"Ed":_emscripten_glDrawBuffersWEBGL,"Kc":_emscripten_glDrawElements,"Cd":_emscripten_glDrawElementsInstancedANGLE,"Jc":_emscripten_glEnable,"Hc":_emscripten_glEnableVertexAttribArray,"$":_emscripten_glEndQueryEXT,"Gc":_emscripten_glFinish,"Fc":_emscripten_glFlush,"Ec":_emscripten_glFramebufferRenderbuffer,"Dc":_emscripten_glFramebufferTexture2D,"Cc":_emscripten_glFrontFace,"Bc":_emscripten_glGenBuffers,"zc":_emscripten_glGenFramebuffers,"ea":_emscripten_glGenQueriesEXT,"yc":_emscripten_glGenRenderbuffers,"wc":_emscripten_glGenTextures,"Gd":_emscripten_glGenVertexArraysOES,"Ac":_emscripten_glGenerateMipmap,"vc":_emscripten_glGetActiveAttrib,"uc":_emscripten_glGetActiveUniform,"tc":_emscripten_glGetAttachedShaders,"sc":_emscripten_glGetAttribLocation,"rc":_emscripten_glGetBooleanv,"qc":_emscripten_glGetBufferParameteriv,"pc":_emscripten_glGetError,"oc":_emscripten_glGetFloatv,"nc":_emscripten_glGetFramebufferAttachmentParameteriv,"lc":_emscripten_glGetIntegerv,"jc":_emscripten_glGetProgramInfoLog,"kc":_emscripten_glGetProgramiv,"W":_emscripten_glGetQueryObjecti64vEXT,"Y":_emscripten_glGetQueryObjectivEXT,"V":_emscripten_glGetQueryObjectui64vEXT,"X":_emscripten_glGetQueryObjectuivEXT,"Z":_emscripten_glGetQueryivEXT,"ic":_emscripten_glGetRenderbufferParameteriv,"gc":_emscripten_glGetShaderInfoLog,"fc":_emscripten_glGetShaderPrecisionFormat,"ec":_emscripten_glGetShaderSource,"hc":_emscripten_glGetShaderiv,"dc":_emscripten_glGetString,"cc":_emscripten_glGetTexParameterfv,"ac":_emscripten_glGetTexParameteriv,"Zb":_emscripten_glGetUniformLocation,"$b":_emscripten_glGetUniformfv,"_b":_emscripten_glGetUniformiv,"Wb":_emscripten_glGetVertexAttribPointerv,"Yb":_emscripten_glGetVertexAttribfv,"Xb":_emscripten_glGetVertexAttribiv,"Vb":_emscripten_glHint,"Ub":_emscripten_glIsBuffer,"Tb":_emscripten_glIsEnabled,"Rb":_emscripten_glIsFramebuffer,"Qb":_emscripten_glIsProgram,"ba":_emscripten_glIsQueryEXT,"Pb":_emscripten_glIsRenderbuffer,"Ob":_emscripten_glIsShader,"Nb":_emscripten_glIsTexture,"Fd":_emscripten_glIsVertexArrayOES,"Mb":_emscripten_glLineWidth,"Lb":_emscripten_glLinkProgram,"Kb":_emscripten_glPixelStorei,"Jb":_emscripten_glPolygonOffset,"_":_emscripten_glQueryCounterEXT,"Ib":_emscripten_glReadPixels,"Gb":_emscripten_glReleaseShaderCompiler,"Fb":_emscripten_glRenderbufferStorage,"Eb":_emscripten_glSampleCoverage,"Db":_emscripten_glScissor,"Cb":_emscripten_glShaderBinary,"Bb":_emscripten_glShaderSource,"Ab":_emscripten_glStencilFunc,"zb":_emscripten_glStencilFuncSeparate,"yb":_emscripten_glStencilMask,"xb":_emscripten_glStencilMaskSeparate,"vb":_emscripten_glStencilOp,"ub":_emscripten_glStencilOpSeparate,"tb":_emscripten_glTexImage2D,"sb":_emscripten_glTexParameterf,"rb":_emscripten_glTexParameterfv,"qb":_emscripten_glTexParameteri,"pb":_emscripten_glTexParameteriv,"ob":_emscripten_glTexSubImage2D,"nb":_emscripten_glUniform1f,"mb":_emscripten_glUniform1fv,"kb":_emscripten_glUniform1i,"jb":_emscripten_glUniform1iv,"ib":_emscripten_glUniform2f,"hb":_emscripten_glUniform2fv,"gb":_emscripten_glUniform2i,"fb":_emscripten_glUniform2iv,"eb":_emscripten_glUniform3f,"db":_emscripten_glUniform3fv,"cb":_emscripten_glUniform3i,"bb":_emscripten_glUniform3iv,"$a":_emscripten_glUniform4f,"_a":_emscripten_glUniform4fv,"Za":_emscripten_glUniform4i,"Ya":_emscripten_glUniform4iv,"Xa":_emscripten_glUniformMatrix2fv,"Wa":_emscripten_glUniformMatrix3fv,"Va":_emscripten_glUniformMatrix4fv,"Ua":_emscripten_glUseProgram,"Ta":_emscripten_glValidateProgram,"Sa":_emscripten_glVertexAttrib1f,"Qa":_emscripten_glVertexAttrib1fv,"Pa":_emscripten_glVertexAttrib2f,"Oa":_emscripten_glVertexAttrib2fv,"Na":_emscripten_glVertexAttrib3f,"Ma":_emscripten_glVertexAttrib3fv,"La":_emscripten_glVertexAttrib4f,"Ka":_emscripten_glVertexAttrib4fv,"Bd":_emscripten_glVertexAttribDivisorANGLE,"Ja":_emscripten_glVertexAttribPointer,"Ia":_emscripten_glViewport,"p":_emscripten_has_asyncify,"ya":_emscripten_is_main_browser_thread,"fa":_emscripten_memcpy_big,"Ea":_emscripten_request_fullscreen_strategy,"R":_emscripten_request_pointerlock,"ga":_emscripten_resize_heap,"c":_emscripten_return_address,"w":_emscripten_sample_gamepad_data,"x":_emscripten_set_beforeunload_callback_on_thread,"J":_emscripten_set_blur_callback_on_thread,"h":_emscripten_set_canvas_element_size,"o":_emscripten_set_element_css_size,"K":_emscripten_set_focus_callback_on_thread,"A":_emscripten_set_fullscreenchange_callback_on_thread,"u":_emscripten_set_gamepadconnected_callback_on_thread,"t":_emscripten_set_gamepaddisconnected_callback_on_thread,"D":_emscripten_set_keydown_callback_on_thread,"B":_emscripten_set_keypress_callback_on_thread,"C":_emscripten_set_keyup_callback_on_thread,"Fa":_emscripten_set_main_loop_arg,"P":_emscripten_set_mousedown_callback_on_thread,"N":_emscripten_set_mouseenter_callback_on_thread,"M":_emscripten_set_mouseleave_callback_on_thread,"Q":_emscripten_set_mousemove_callback_on_thread,"O":_emscripten_set_mouseup_callback_on_thread,"E":_emscripten_set_pointerlockchange_callback_on_thread,"z":_emscripten_set_resize_callback_on_thread,"F":_emscripten_set_touchcancel_callback_on_thread,"H":_emscripten_set_touchend_callback_on_thread,"G":_emscripten_set_touchmove_callback_on_thread,"I":_emscripten_set_touchstart_callback_on_thread,"y":_emscripten_set_visibilitychange_callback_on_thread,"L":_emscripten_set_wheel_callback_on_thread,"g":_emscripten_sleep,"xa":_emscripten_start_fetch,"ia":_environ_get,"ja":_environ_sizes_get,"j":_exit,"f":_fd_close,"ha":_fd_fdstat_get,"pa":_fd_read,"Ha":_fd_seek,"k":_fd_write,"m":_gettimeofday,"a":wasmMemory,"za":_nanosleep,"S":_setTempRet0,"d":_sigaction,"Aa":_signal,"Jd":_system};var asm=createWasm();var ___wasm_call_ctors=Module["___wasm_call_ctors"]=function(){return(___wasm_call_ctors=Module["___wasm_call_ctors"]=Module["asm"]["Ld"]).apply(null,arguments)};var _malloc=Module["_malloc"]=function(){return(_malloc=Module["_malloc"]=Module["asm"]["Md"]).apply(null,arguments)};var _free=Module["_free"]=function(){return(_free=Module["_free"]=Module["asm"]["Nd"]).apply(null,arguments)};var _www_async_dload=Module["_www_async_dload"]=function(){return(_www_async_dload=Module["_www_async_dload"]=Module["asm"]["Od"]).apply(null,arguments)};var _main=Module["_main"]=function(){return(_main=Module["_main"]=Module["asm"]["Pd"]).apply(null,arguments)};var ___errno_location=Module["___errno_location"]=function(){return(___errno_location=Module["___errno_location"]=Module["asm"]["Qd"]).apply(null,arguments)};var _emscripten_GetProcAddress=Module["_emscripten_GetProcAddress"]=function(){return(_emscripten_GetProcAddress=Module["_emscripten_GetProcAddress"]=Module["asm"]["Rd"]).apply(null,arguments)};var stackSave=Module["stackSave"]=function(){return(stackSave=Module["stackSave"]=Module["asm"]["Sd"]).apply(null,arguments)};var stackRestore=Module["stackRestore"]=function(){return(stackRestore=Module["stackRestore"]=Module["asm"]["Td"]).apply(null,arguments)};var stackAlloc=Module["stackAlloc"]=function(){return(stackAlloc=Module["stackAlloc"]=Module["asm"]["Ud"]).apply(null,arguments)};var dynCall_vi=Module["dynCall_vi"]=function(){return(dynCall_vi=Module["dynCall_vi"]=Module["asm"]["Vd"]).apply(null,arguments)};var dynCall_ii=Module["dynCall_ii"]=function(){return(dynCall_ii=Module["dynCall_ii"]=Module["asm"]["Wd"]).apply(null,arguments)};var dynCall_iii=Module["dynCall_iii"]=function(){return(dynCall_iii=Module["dynCall_iii"]=Module["asm"]["Xd"]).apply(null,arguments)};var dynCall_viii=Module["dynCall_viii"]=function(){return(dynCall_viii=Module["dynCall_viii"]=Module["asm"]["Yd"]).apply(null,arguments)};var dynCall_vii=Module["dynCall_vii"]=function(){return(dynCall_vii=Module["dynCall_vii"]=Module["asm"]["Zd"]).apply(null,arguments)};var dynCall_viiii=Module["dynCall_viiii"]=function(){return(dynCall_viiii=Module["dynCall_viiii"]=Module["asm"]["_d"]).apply(null,arguments)};var dynCall_viiiiiii=Module["dynCall_viiiiiii"]=function(){return(dynCall_viiiiiii=Module["dynCall_viiiiiii"]=Module["asm"]["$d"]).apply(null,arguments)};var dynCall_viiiii=Module["dynCall_viiiii"]=function(){return(dynCall_viiiii=Module["dynCall_viiiii"]=Module["asm"]["ae"]).apply(null,arguments)};var dynCall_v=Module["dynCall_v"]=function(){return(dynCall_v=Module["dynCall_v"]=Module["asm"]["be"]).apply(null,arguments)};var dynCall_iiiii=Module["dynCall_iiiii"]=function(){return(dynCall_iiiii=Module["dynCall_iiiii"]=Module["asm"]["ce"]).apply(null,arguments)};var dynCall_iiii=Module["dynCall_iiii"]=function(){return(dynCall_iiii=Module["dynCall_iiii"]=Module["asm"]["de"]).apply(null,arguments)};var dynCall_iiiiii=Module["dynCall_iiiiii"]=function(){return(dynCall_iiiiii=Module["dynCall_iiiiii"]=Module["asm"]["ee"]).apply(null,arguments)};var dynCall_jiji=Module["dynCall_jiji"]=function(){return(dynCall_jiji=Module["dynCall_jiji"]=Module["asm"]["fe"]).apply(null,arguments)};var dynCall_ji=Module["dynCall_ji"]=function(){return(dynCall_ji=Module["dynCall_ji"]=Module["asm"]["ge"]).apply(null,arguments)};var dynCall_iiiiiiiiii=Module["dynCall_iiiiiiiiii"]=function(){return(dynCall_iiiiiiiiii=Module["dynCall_iiiiiiiiii"]=Module["asm"]["he"]).apply(null,arguments)};var dynCall_iiiiiidii=Module["dynCall_iiiiiidii"]=function(){return(dynCall_iiiiiidii=Module["dynCall_iiiiiidii"]=Module["asm"]["ie"]).apply(null,arguments)};var dynCall_iiiiiiiii=Module["dynCall_iiiiiiiii"]=function(){return(dynCall_iiiiiiiii=Module["dynCall_iiiiiiiii"]=Module["asm"]["je"]).apply(null,arguments)};var dynCall_viiiiiiiiiii=Module["dynCall_viiiiiiiiiii"]=function(){return(dynCall_viiiiiiiiiii=Module["dynCall_viiiiiiiiiii"]=Module["asm"]["ke"]).apply(null,arguments)};var dynCall_iiiiiiii=Module["dynCall_iiiiiiii"]=function(){return(dynCall_iiiiiiii=Module["dynCall_iiiiiiii"]=Module["asm"]["le"]).apply(null,arguments)};var dynCall_i=Module["dynCall_i"]=function(){return(dynCall_i=Module["dynCall_i"]=Module["asm"]["me"]).apply(null,arguments)};var dynCall_iidiiii=Module["dynCall_iidiiii"]=function(){return(dynCall_iidiiii=Module["dynCall_iidiiii"]=Module["asm"]["ne"]).apply(null,arguments)};var dynCall_vffff=Module["dynCall_vffff"]=function(){return(dynCall_vffff=Module["dynCall_vffff"]=Module["asm"]["oe"]).apply(null,arguments)};var dynCall_vf=Module["dynCall_vf"]=function(){return(dynCall_vf=Module["dynCall_vf"]=Module["asm"]["pe"]).apply(null,arguments)};var dynCall_viiiiiiii=Module["dynCall_viiiiiiii"]=function(){return(dynCall_viiiiiiii=Module["dynCall_viiiiiiii"]=Module["asm"]["qe"]).apply(null,arguments)};var dynCall_viiiiiiiii=Module["dynCall_viiiiiiiii"]=function(){return(dynCall_viiiiiiiii=Module["dynCall_viiiiiiiii"]=Module["asm"]["re"]).apply(null,arguments)};var dynCall_vff=Module["dynCall_vff"]=function(){return(dynCall_vff=Module["dynCall_vff"]=Module["asm"]["se"]).apply(null,arguments)};var dynCall_vfi=Module["dynCall_vfi"]=function(){return(dynCall_vfi=Module["dynCall_vfi"]=Module["asm"]["te"]).apply(null,arguments)};var dynCall_viif=Module["dynCall_viif"]=function(){return(dynCall_viif=Module["dynCall_viif"]=Module["asm"]["ue"]).apply(null,arguments)};var dynCall_vif=Module["dynCall_vif"]=function(){return(dynCall_vif=Module["dynCall_vif"]=Module["asm"]["ve"]).apply(null,arguments)};var dynCall_viff=Module["dynCall_viff"]=function(){return(dynCall_viff=Module["dynCall_viff"]=Module["asm"]["we"]).apply(null,arguments)};var dynCall_vifff=Module["dynCall_vifff"]=function(){return(dynCall_vifff=Module["dynCall_vifff"]=Module["asm"]["xe"]).apply(null,arguments)};var dynCall_viffff=Module["dynCall_viffff"]=function(){return(dynCall_viffff=Module["dynCall_viffff"]=Module["asm"]["ye"]).apply(null,arguments)};var dynCall_viiiiii=Module["dynCall_viiiiii"]=function(){return(dynCall_viiiiii=Module["dynCall_viiiiii"]=Module["asm"]["ze"]).apply(null,arguments)};var _asyncify_start_unwind=Module["_asyncify_start_unwind"]=function(){return(_asyncify_start_unwind=Module["_asyncify_start_unwind"]=Module["asm"]["Ae"]).apply(null,arguments)};var _asyncify_stop_unwind=Module["_asyncify_stop_unwind"]=function(){return(_asyncify_stop_unwind=Module["_asyncify_stop_unwind"]=Module["asm"]["Be"]).apply(null,arguments)};var _asyncify_start_rewind=Module["_asyncify_start_rewind"]=function(){return(_asyncify_start_rewind=Module["_asyncify_start_rewind"]=Module["asm"]["Ce"]).apply(null,arguments)};var _asyncify_stop_rewind=Module["_asyncify_stop_rewind"]=function(){return(_asyncify_stop_rewind=Module["_asyncify_stop_rewind"]=Module["asm"]["De"]).apply(null,arguments)};var ___heap_base=Module["___heap_base"]=6853456;var ___global_base=Module["___global_base"]=1024;Module["addRunDependency"]=addRunDependency;Module["removeRunDependency"]=removeRunDependency;Module["FS_createPath"]=FS.createPath;Module["FS_createDataFile"]=FS.createDataFile;Module["FS_createPreloadedFile"]=FS.createPreloadedFile;Module["FS_createLazyFile"]=FS.createLazyFile;Module["FS_createDevice"]=FS.createDevice;Module["FS_unlink"]=FS.unlink;var calledRun;function ExitStatus(status){this.name="ExitStatus";this.message="Program terminated with exit("+status+")";this.status=status}var calledMain=false;dependenciesFulfilled=function runCaller(){if(!calledRun)run();if(!calledRun)dependenciesFulfilled=runCaller};function callMain(args){var entryFunction=Module["_main"];args=args||[];var argc=args.length+1;var argv=stackAlloc((argc+1)*4);HEAP32[argv>>2]=allocateUTF8OnStack(thisProgram);for(var i=1;i>2)+i]=allocateUTF8OnStack(args[i-1])}HEAP32[(argv>>2)+argc]=0;try{var ret=entryFunction(argc,argv);if(!noExitRuntime){exit(ret,true)}}catch(e){if(e instanceof ExitStatus){return}else if(e=="unwind"){noExitRuntime=true;return}else{var toLog=e;if(e&&typeof e==="object"&&e.stack){toLog=[e,e.stack]}err("exception thrown: "+toLog);quit_(1,e)}}finally{calledMain=true}}function run(args){args=args||arguments_;if(runDependencies>0){return}preRun();if(runDependencies>0)return;function doRun(){if(calledRun)return;calledRun=true;Module["calledRun"]=true;if(ABORT)return;initRuntime();preMain();if(Module["onRuntimeInitialized"])Module["onRuntimeInitialized"]();if(shouldRunNow)callMain(args);postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout(function(){setTimeout(function(){Module["setStatus"]("")},1);doRun()},1)}else{doRun()}}Module["run"]=run;function exit(status,implicit){if(implicit&&noExitRuntime&&status===0){return}if(noExitRuntime){}else{EXITSTATUS=status;exitRuntime();if(Module["onExit"])Module["onExit"](status);ABORT=true}quit_(status,new ExitStatus(status))}if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].pop()()}}var shouldRunNow=true;if(Module["noInitialRun"])shouldRunNow=false;noExitRuntime=true;run(); diff --git a/www/Oricutron.wasm b/www/Oricutron.wasm new file mode 100755 index 00000000..f9506ff2 Binary files /dev/null and b/www/Oricutron.wasm differ diff --git a/www/Readme.txt b/www/Readme.txt new file mode 100644 index 00000000..4c8ce16b --- /dev/null +++ b/www/Readme.txt @@ -0,0 +1,116 @@ +// Web version of Oricutron + +If you only want to host the provided version of Oricutron and some disks and tapes files : + +Requirement: have PHP running on your website. + +Note : If you don't have PHP you can use the index_nophp.html file and edit it by hand +adding your .dsk and .tap names in the JavaScript lists. + +Copy the following files to your web directory +dir.php +index.html +Oricutron.data +oricutron.html +Oricutron.js +Oricutron.wasm + +Add all your .tap and .dsk files in the same directory. + +That's all folks! + + + +If you want to compile your own version of Oricutron : + +Requirements: + +Install Emscripten SDK from https://emscripten.org/ + +https://emscripten.org/docs/getting_started/downloads.html + +Note : you can use a docker image if you don't want to install everything +(look at the end of the above linked page). + +Cmake building : + +; Create a build directory in the www directory : +cd www +mkdir build +; Change to this new directory +cd build +; Use emcmake and cmake to generate Makefile +emcmake cmake .. + +Prepare your assets : + +; create an assets directory +mkdir assets +; copy the images directory +; WARNING you'd better remove the gfx_atmoskbd.psd file as it is quite big and not used by Oricutron +cp -r ../../images assets/ +; copy the roms directory (after adding the actual roms - not included in the git repository) +cp -r ../../roms assets/ + +Either : + +; if you want to include a tap +; copy the tap +mkdir assets/tapes +cp ../../tapes/Cyclotron.tap assets/tapes + +Or : + +; if you want to include a dsk +; copy the dsk +mkdir assets/disks +cp ../../disks/aigledor.dsk assets/disks + +Edit the configuration file (so that it autoloads the tape or the disk) : +You want to search for tapeimage and have it look like this : +tapeimage = 'assets/tapes/Cyclotron.tap' +Or you want to search for diskimage and have it look like this : +diskimage = 'assets/disks/aigledor.dsk' + +You may also want to show the keyboard automatically and enable sticky mod keys +(for the shift and ctrl keys) : +show_keyboard = yes +sticky_mod_keys = yes + +Copy the configuration file : + +cp ../../oricutron.cfg assets/ + +Building : + +make + +Note : if you want to change the configuration/tapes/disks you will need to do : + +rm Oricutron.html +make + + +Testing the build : + +emrun Oricutron.html + +If everything is okay : + +You now need to move the following files to your website : +Oricutron.html ->> the web page +Oricutron.js ->> the javascript launcher file +Oricutron.wasm ->> the web assembly (the machine code) +Oricutron.data ->> all the assets + +If your data is very big you might want to look at the end of the following page + to send it compressed to navigators : +https://emscripten.org/docs/compiling/WebAssembly.html + + +Reference documentation : + +https://emscripten.org/index.html + +https://lyceum-allotments.github.io/2016/06/emscripten-and-sdl-2-tutorial-part-1/ + diff --git a/www/dir.php b/www/dir.php new file mode 100644 index 00000000..d9af6758 --- /dev/null +++ b/www/dir.php @@ -0,0 +1,16 @@ +// this php file lists dsk, tap, and oricutron config files +var dskFiles = ; +var tapFiles = ; +var cfgFiles = ; \ No newline at end of file diff --git a/www/download.html b/www/download.html new file mode 100644 index 00000000..69bd5be3 --- /dev/null +++ b/www/download.html @@ -0,0 +1,28 @@ + + + + + Oricutron.js Downloader + + +

Oricutron.js Downloader

+ + + + + + + + diff --git a/www/index.html b/www/index.html new file mode 100644 index 00000000..1b601adc --- /dev/null +++ b/www/index.html @@ -0,0 +1,46 @@ + + + + + Oricutron.js Launcher + + +

Oricutron.js Launcher

+

Please click on one of those links:

+

Disks :

+
+ +
+

Tapes :

+
+ +
+ + + + \ No newline at end of file diff --git a/www/index_nophp.html b/www/index_nophp.html new file mode 100644 index 00000000..baa4e722 --- /dev/null +++ b/www/index_nophp.html @@ -0,0 +1,49 @@ + + + + Oricutron.js Launcher + + +

Oricutron.js Launcher

+

Please click on one of those links:

+

Disks :

+ +

Tapes :

+ + + + + \ No newline at end of file diff --git a/www/oricutron.html b/www/oricutron.html new file mode 100644 index 00000000..5468b15b --- /dev/null +++ b/www/oricutron.html @@ -0,0 +1,257 @@ + + + + + + Emscripten-Generated Code + + + +
The Disks and Tapes files are in the /readwritefs/ directory! + You may need to go up twice in the directory structure to find this directory.
+ Remember to save snapshots, tapes and dsk in this directory as it is the only one + that is saved in your browser's storage space. +
+ In order to download one tape or dsk file so that you can use it in an emulator + on your computer first click on this button and then on the name of the file +
+ +
+
+ +
+
+
+
Downloading...
+
+ +
+
+ +
+ + + + + + + + + + + + \ No newline at end of file