From 34bd53d9be53b6c1fee4b062b059c98325f57d82 Mon Sep 17 00:00:00 2001 From: tudnai Date: Thu, 25 Jun 2020 16:23:20 -0700 Subject: [PATCH] Disk Save --- A2Mac.xcodeproj/project.pbxproj | 4 +- A2Mac/A2Mac.entitlements | 8 +-- A2Mac/AppDelegate.swift | 10 +++ A2Mac/Base.lproj/Main.storyboard | 5 ++ A2Mac/Info.plist | 4 +- src/dev/disk/woz.c | 119 +++++++++++++++++++------------ src/dev/disk/woz.h | 2 +- 7 files changed, 96 insertions(+), 56 deletions(-) diff --git a/A2Mac.xcodeproj/project.pbxproj b/A2Mac.xcodeproj/project.pbxproj index 17e05c9..3fb4531 100644 --- a/A2Mac.xcodeproj/project.pbxproj +++ b/A2Mac.xcodeproj/project.pbxproj @@ -1481,7 +1481,7 @@ "-D_NO_CLK_ABSOLUTE_PRECISE", ); OTHER_SWIFT_FLAGS = "-DHIRES -D_NO_METAL -D_NO_HIRESDRAW -DHIRESLOW -DHIRESLOWCOLOR"; - PRODUCT_BUNDLE_IDENTIFIER = com.gamealloy.A2Mac; + PRODUCT_BUNDLE_IDENTIFIER = com.trudnai.steveii; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_OBJC_BRIDGING_HEADER = "A2Mac/A2Mac-Bridging-Header.h"; @@ -1518,7 +1518,7 @@ "-D_NO_CLK_ABSOLUTE_PRECISE", ); OTHER_SWIFT_FLAGS = "-DHIRES -D_NO_METAL -D_NO_HIRESDRAW -DHIRESLOW -DHIRESLOWCOLOR"; - PRODUCT_BUNDLE_IDENTIFIER = com.gamealloy.A2Mac; + PRODUCT_BUNDLE_IDENTIFIER = com.trudnai.steveii; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "A2Mac/A2Mac-Bridging-Header.h"; SWIFT_VERSION = 5.0; diff --git a/A2Mac/A2Mac.entitlements b/A2Mac/A2Mac.entitlements index f2ef3ae..19afff1 100644 --- a/A2Mac/A2Mac.entitlements +++ b/A2Mac/A2Mac.entitlements @@ -2,9 +2,9 @@ - com.apple.security.app-sandbox - - com.apple.security.files.user-selected.read-only - + com.apple.security.app-sandbox + + com.apple.security.files.user-selected.read-write + diff --git a/A2Mac/AppDelegate.swift b/A2Mac/AppDelegate.swift index 50c1b7a..e85ceaf 100644 --- a/A2Mac/AppDelegate.swift +++ b/A2Mac/AppDelegate.swift @@ -48,6 +48,16 @@ class AppDelegate: NSObject, NSApplicationDelegate { return woz_err == 0; } + @IBAction func saveFile(_ sender: NSMenuItem) { + + let savePanel = NSSavePanel() + savePanel.begin { (result) in + if result.rawValue == NSApplication.ModalResponse.OK.rawValue { + woz_saveFile( savePanel.url?.absoluteString ); + } + } + + } @IBAction func showPreferences(_ sender: NSMenuItem) { diff --git a/A2Mac/Base.lproj/Main.storyboard b/A2Mac/Base.lproj/Main.storyboard index 440fdf2..0d9e238 100644 --- a/A2Mac/Base.lproj/Main.storyboard +++ b/A2Mac/Base.lproj/Main.storyboard @@ -87,6 +87,11 @@ + + + + + diff --git a/A2Mac/Info.plist b/A2Mac/Info.plist index e1b2fc4..78fd22f 100644 --- a/A2Mac/Info.plist +++ b/A2Mac/Info.plist @@ -2,6 +2,8 @@ + ATSApplicationFontsPath + fnt CFBundleDevelopmentRegion $(DEVELOPMENT_LANGUAGE) CFBundleExecutable @@ -30,7 +32,5 @@ Main NSPrincipalClass NSApplication - ATSApplicationFontsPath - fnt diff --git a/src/dev/disk/woz.c b/src/dev/disk/woz.c index 20a4c52..524b932 100644 --- a/src/dev/disk/woz.c +++ b/src/dev/disk/woz.c @@ -25,10 +25,12 @@ int bitOffset = 0; uint64_t clkelpased; -woz_header_t woz_header; -woz_chunk_header_t woz_chunk_header; -woz_tmap_t woz_tmap; -woz_trks_t woz_trks; +size_t woz_file_size = 0; +uint8_t * woz_file_buffer = NULL; +woz_header_t * woz_header; +woz_chunk_header_t * woz_chunk_header; +woz_tmap_t * woz_tmap; +woz_trks_t * woz_trks; int track_loaded = -1; @@ -59,8 +61,8 @@ uint8_t readLatch; void woz_loadTrack_old( int track ) { trackEntry_t reg = {0}; - reg.shift = woz_trks[track].data[0]; - reg.data = woz_trks[track].data[1]; + reg.shift = (*woz_trks)[track].data[0]; + reg.data = (*woz_trks)[track].data[1]; prepared_track[0] = reg; for ( int offs = 1; offs < WOZ_TRACK_BYTE_COUNT; offs++ ) { @@ -73,7 +75,7 @@ void woz_loadTrack_old( int track ) { reg.shift16 <<= 1; } - reg.data = woz_trks[track].data[ (offs + 1) % WOZ_TRACK_BYTE_COUNT ]; + reg.data = (*woz_trks)[track].data[ (offs + 1) % WOZ_TRACK_BYTE_COUNT ]; prepared_track[offs] = reg; } } @@ -197,7 +199,7 @@ void woz_loadTrack( int track ) { for ( int byteOffs = 0; byteOffs < WOZ_TRACK_BYTE_COUNT; byteOffs++ ) { - reg.data = woz_trks[track].data[ byteOffs ]; + reg.data = (*woz_trks)[track].data[ byteOffs ]; for ( int i = 0; i < 8; i++ ) { reg.shift16 <<= 1; @@ -215,7 +217,7 @@ void woz_loadTrack( int track ) { uint8_t woz_read() { - int track = woz_tmap.phase[disk.phase.count]; + int track = woz_tmap->phase[disk.phase.count]; if (outdev) fprintf(outdev, "track: %d (%d) ", track, disk.phase.count); if ( track >= 40 ) { dbgPrintf("TRCK TOO HIGH!\n"); @@ -232,7 +234,7 @@ uint8_t woz_read() { const int clkBeforeAdjusting = 512; const int magicShiftOffset = 45; - uint16_t usedBytes = woz_trks[track].bytes_used < WOZ_TRACK_BYTE_COUNT ? woz_trks[track].bytes_used : WOZ_TRACK_BYTE_COUNT; + uint16_t usedBytes = (*woz_trks)[track].bytes_used < WOZ_TRACK_BYTE_COUNT ? (*woz_trks)[track].bytes_used : WOZ_TRACK_BYTE_COUNT; if ( usedBytes ) { int shiftOffset = magicShiftOffset; @@ -254,7 +256,7 @@ uint8_t woz_read() { // preroll data stream WOZread.shift = 0; - WOZread.data = woz_trks[track].data[trackOffset++]; + WOZread.data = (*woz_trks)[track].data[trackOffset++]; trackOffset %= usedBytes; trackWRoffset = trackOffset; @@ -271,7 +273,7 @@ uint8_t woz_read() { } } trackWRoffset = trackOffset; - WOZwrite.data = WOZread.data = woz_trks[track].data[trackOffset++]; + WOZwrite.data = WOZread.data = (*woz_trks)[track].data[trackOffset++]; trackOffset %= usedBytes; bitOffset = 0; } @@ -287,7 +289,7 @@ uint8_t woz_read() { trackOffset++; trackOffset %= usedBytes; - WOZwrite.data = WOZread.data = woz_trks[track].data[trackOffset]; + WOZwrite.data = WOZread.data = (*woz_trks)[track].data[trackOffset]; } WOZread.shift <<= 1; @@ -320,7 +322,7 @@ uint8_t woz_read() { trackOffset++; trackOffset %= usedBytes; - WOZwrite.data = WOZread.data = woz_trks[track].data[trackOffset]; + WOZwrite.data = WOZread.data = (*woz_trks)[track].data[trackOffset]; } WOZread.shift <<= 1; @@ -359,7 +361,7 @@ void printWozBuffer (const char * s, int n, WOZread_t WOZbuf ) { void woz_write( uint8_t data ) { - int track = woz_tmap.phase[disk.phase.count]; + int track = woz_tmap->phase[disk.phase.count]; if (outdev) fprintf(outdev, "track: %d (%d) ", track, disk.phase.count); if ( track >= 40 ) { dbgPrintf("TRACK TOO HIGH!\n"); @@ -369,7 +371,7 @@ void woz_write( uint8_t data ) { clkelpased = m6502.clktime + clkfrm - m6502.clklast; m6502.clklast = m6502.clktime + clkfrm; - uint16_t usedBytes = woz_trks[track].bytes_used < WOZ_TRACK_BYTE_COUNT ? woz_trks[track].bytes_used : WOZ_TRACK_BYTE_COUNT; + uint16_t usedBytes = (*woz_trks)[track].bytes_used < WOZ_TRACK_BYTE_COUNT ? (*woz_trks)[track].bytes_used : WOZ_TRACK_BYTE_COUNT; if ( usedBytes ) { @@ -392,7 +394,7 @@ void woz_write( uint8_t data ) { trackOffset %= usedBytes; // WOZwrite.data = - WOZread.data = woz_trks[track].data[trackOffset]; + WOZread.data = (*woz_trks)[track].data[trackOffset]; } WOZread.shift <<= 1; @@ -415,7 +417,7 @@ void woz_write( uint8_t data ) { while ( i-- ) { if ( ++bitOffset >= 8 ) { // write out first part - woz_trks[track].data[trackWRoffset] = WOZwrite.latch; + (*woz_trks)[track].data[trackWRoffset] = WOZwrite.latch; bitOffset = 0; trackWRoffset = trackOffset; @@ -423,7 +425,7 @@ void woz_write( uint8_t data ) { trackOffset %= usedBytes; // simulate shift in data (path of write latch is already loaded, we should not overwrite it!) - uint8_t new = woz_trks[track].data[trackOffset]; + uint8_t new = (*woz_trks)[track].data[trackOffset]; new >>= i + 1; WOZread.data |= new; // WOZwrite.data |= new; @@ -448,7 +450,7 @@ void woz_write( uint8_t data ) { while ( i-- ) { if ( ++bitOffset >= 8 ) { // write out first part - woz_trks[track].data[trackWRoffset] = WOZwrite.latch; + (*woz_trks)[track].data[trackWRoffset] = WOZwrite.latch; break; } @@ -476,36 +478,53 @@ int woz_loadFile( const char * filename ) { return WOZ_ERR_FILE_NOT_FOUND; } - fread( &woz_header, 1, sizeof(woz_header_t), f); - if ( woz_header.magic != WOZ1_MAGIC ) { + // get file size + fseek(f, 0, SEEK_END); + woz_file_size = ftell(f); + fseek(f, 0, SEEK_SET); + + if ( woz_file_buffer ) { + free(woz_file_buffer); + woz_file_buffer = NULL; + } + + woz_file_buffer = malloc(woz_file_size); + if (woz_file_buffer == NULL) { + perror("Not Enough Memory: "); + return WOZ_ERR_BAD_DATA; + } + woz_header = (woz_header_t*)woz_file_buffer; + + // to simulate file read + long bufOffs = 0; + + fread( woz_file_buffer, woz_file_size, 1, f); + fclose(f); + if ( woz_header->magic != WOZ1_MAGIC ) { + free(woz_file_buffer); + woz_file_buffer = NULL; return WOZ_ERR_NOT_WOZ_FILE; } - - while ( ! feof(f) ) { + + bufOffs += sizeof(woz_header_t); + + while ( bufOffs < woz_file_size ) { // beginning of the chunk, so we can skip it later - long r = fread( &woz_chunk_header, 1, sizeof(woz_chunk_header_t), f); - if ( r != sizeof(woz_chunk_header_t) ) { - if ( r ) { - return WOZ_ERR_BAD_CHUNK_HDR; - } - // ok we just reached the end of the file, we should exit properly, close file handle etc - break; - } - long foffs = ftell(f); + woz_chunk_header = (woz_chunk_header_t*)(woz_file_buffer + bufOffs); - void * buf = NULL; - - switch ( woz_chunk_header.magic ) { + bufOffs += sizeof(woz_chunk_header_t); + + switch ( woz_chunk_header->magic ) { case WOZ_INFO_CHUNK_ID: break; case WOZ_TMAP_CHUNK_ID: - buf = &woz_tmap; + woz_tmap = (woz_tmap_t*)(woz_file_buffer + bufOffs); break; case WOZ_TRKS_CHUNK_ID: - buf = woz_trks; + woz_trks = (woz_trks_t*)(woz_file_buffer + bufOffs); break; case WOZ_META_CHUNK_ID: @@ -515,18 +534,10 @@ int woz_loadFile( const char * filename ) { break; } - if (buf) { - r = fread( buf, 1, woz_chunk_header.size, f); - if ( r != woz_chunk_header.size ) { - return WOZ_ERR_BAD_DATA; - } - } - // make sure we are skipping unhandled chunks correctly - fseek(f, foffs + woz_chunk_header.size, SEEK_SET); + bufOffs += woz_chunk_header->size; } - fclose(f); // DO NOT COMMIT THIS! ONLY FOR DEBUG!!! @@ -535,4 +546,18 @@ int woz_loadFile( const char * filename ) { return WOZ_ERR_OK; } +int woz_saveFile( const char * filename ) { + + FILE * f = fopen( filename, "wb" ); + if (f == NULL) { + perror("Failed to crete WOZ: "); + return WOZ_ERR_FILE_NOT_FOUND; + } + + fwrite( &woz_file_buffer, woz_file_size, 1, f ); + fclose(f); + + return WOZ_ERR_OK; +} + diff --git a/src/dev/disk/woz.h b/src/dev/disk/woz.h index 0b9c366..32ca66d 100644 --- a/src/dev/disk/woz.h +++ b/src/dev/disk/woz.h @@ -131,6 +131,6 @@ extern uint8_t WOZlatch; extern uint8_t woz_read(void); extern void woz_write( uint8_t data ); extern int woz_loadFile( const char * filename ); - +extern int woz_saveFile( const char * filename ); #endif /* woz_h */