diff --git a/A2Mac.xcodeproj/project.pbxproj b/A2Mac.xcodeproj/project.pbxproj index ad9d83b..b3044a4 100644 --- a/A2Mac.xcodeproj/project.pbxproj +++ b/A2Mac.xcodeproj/project.pbxproj @@ -639,6 +639,7 @@ 32440BA22480D5C0000F9DA1 /* LoRes.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoRes.swift; sourceTree = ""; }; 324D15D224ADAC71008AAFB0 /* floppy.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = floppy.png; sourceTree = ""; }; 32544194264A6C1600B7E3ED /* DisplayView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DisplayView.swift; sourceTree = ""; }; + 32583B682B5CAD8700A45F0A /* woz_debug.rtf */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; path = woz_debug.rtf; sourceTree = ""; }; 325B75DF2909F95000B29605 /* 6502_dbg.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = 6502_dbg.c; sourceTree = ""; }; 325B7652290A32CC00B29605 /* 6502_dbg.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = 6502_dbg.h; sourceTree = ""; }; 325DC40D24AC5ABC00EB8858 /* doc.on.doc.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = doc.on.doc.png; sourceTree = ""; }; @@ -1148,6 +1149,7 @@ 32BFFB4E22EACC630003B53F = { isa = PBXGroup; children = ( + 32583B682B5CAD8700A45F0A /* woz_debug.rtf */, 32D08991291AF23500F2B486 /* Debug.storyboard */, 326426112328ADF4008B615F /* Apple_II_ROM.s */, 325EB63123F8861A00C6B4A4 /* src */, diff --git a/A2Mac.xcodeproj/project.xcworkspace/xcuserdata/trudnai.xcuserdatad/xcdebugger/Expressions.xcexplist b/A2Mac.xcodeproj/project.xcworkspace/xcuserdata/trudnai.xcuserdatad/xcdebugger/Expressions.xcexplist index 674450b..79c7ab7 100644 --- a/A2Mac.xcodeproj/project.xcworkspace/xcuserdata/trudnai.xcuserdatad/xcdebugger/Expressions.xcexplist +++ b/A2Mac.xcodeproj/project.xcworkspace/xcuserdata/trudnai.xcuserdatad/xcdebugger/Expressions.xcexplist @@ -3,22 +3,10 @@ version = "1.0"> + contextName = "ViewController.newUpdateTimer(timeInterval:):ViewController.swift"> - - - - - - - - + value = "upd"> @@ -26,30 +14,59 @@ contextName = "HiRes.compute():HiRes.swift"> + value = "computePipelineState.maxTotalThreadsPerThreadgroup"> + value = "UnsafeRawBufferPointer(result)"> - - + contextName = "_memwrite8_low:mmio.c"> + value = "MEMcfg"> + value = "currentLowWRMEM == Apple2_64K_MEM"> + value = "WRLOMEM == currentLowWRMEM"> + + + + + + + + + + + + + + + + + + + + + + @@ -74,16 +91,13 @@ + contextName = "memwrite8_bank2:mmio.h"> + value = "WRD0MEM"> - - + value = "WRHIMEM"> @@ -102,30 +116,36 @@ value = "disassLineRange[forLine]"> + value = "disassLineRange"> + value = "disassLineRange.count"> + contextName = "woz_write:woz.c"> + value = "WOZwrite.data"> + value = "new"> + value = "WOZwrite.shift16"> + value = "WOZwrite.shift"> + value = "bitOffset"> + + + + @@ -165,10 +185,10 @@ contextName = "HiRes.draw(_:):HiRes.swift"> + value = "linAddr"> + value = "ctx?.bitsPerComponent"> @@ -185,6 +205,9 @@ + + @@ -195,10 +218,7 @@ value = "ctx?.height"> - - + value = "ctx?.data"> @@ -226,7 +246,7 @@ contextName = "DebuggerViewController.DisplayDisassembly():DebuggerViewController.swift"> + value = "line_number"> @@ -235,7 +255,7 @@ value = "m6502.PC"> + value = "disass_addr_min"> @@ -472,10 +492,10 @@ value = "WRLOMEM == Apple2_64K_RAM"> + value = "newReadMEM == Apple2_64K_RAM + 0x200"> + value = "currentLowWRMEM == newWriteMEM"> @@ -534,7 +554,7 @@ value = "m6502_saved.PC"> + value = "scroll_line_number"> @@ -543,7 +563,7 @@ value = "m6502.PC"> + value = "isCurrentLine"> @@ -557,7 +577,7 @@ value = "textDisplay_height_diff"> + value = "textDisplay.frame"> @@ -566,10 +586,10 @@ value = "frame.size"> + value = "textDisplay_width_diff"> + value = "textDisplay.bounds"> @@ -635,10 +655,10 @@ contextName = "set_flags_NZC:common.h"> + value = "(unsigned)test "> + value = "(unsigned)0xFF"> @@ -748,10 +768,10 @@ value = "MEMcfg.int_Cx_ROM"> + value = "(int)IOframe"> + value = "m6502.clkfrm"> @@ -762,10 +782,10 @@ value = "Apple2_64K_AUX + 0xC600"> + value = "(void*)rom"> + value = "Apple2_64K_RAM + 0xC600"> @@ -897,16 +917,16 @@ contextName = "DisplayScrollView.scrollWheel(with:):DisplayScrollView.swift"> + value = "subviews[1].subviews"> + value = "documentView"> + value = "textView.defaultParagraphStyle?.lineSpacing"> @@ -1006,10 +1026,10 @@ contextName = "_fetch_dbg:mmio.c"> + value = "memread8_low(m6502.PC)"> + value = "disassembly.pOpcode"> @@ -1017,13 +1037,13 @@ contextName = "m6502_dbg_bp_add:6502_bp.c"> + value = "bp_array"> + value = "bp"> @@ -1098,7 +1118,7 @@ contextName = "DebuggerViewController.DisplayDisassembly(scrollY:):DebuggerViewController.swift"> + value = "isCurrentLine"> @@ -1107,7 +1127,7 @@ value = "m6502.PC"> + value = "scroll_line_number"> @@ -1136,20 +1156,20 @@ - - - - + + + + @@ -1200,6 +1220,9 @@ + + @@ -1212,6 +1235,12 @@ + + + + + value = "blockChanged[ screenIdx ]"> @@ -1243,7 +1272,7 @@ value = "UInt8(block & 4)"> + value = "UInt8( (block >> 4) & 0x0F )"> @@ -1300,22 +1329,22 @@ value = "m6502"> + value = "(void*)Apple2_64K_RAM"> + value = "Apple2_64K_RAM + 0x3600"> + + - - + value = "m6502.clkfrm"> @@ -1329,7 +1358,7 @@ value = "pdl_value[pdl]"> + value = "normalized_time >= pdl_value[pdl] ? 255 : 0"> @@ -1341,7 +1370,7 @@ value = "1 * 512 * (1 - ( 3300 / 3300.0 ))"> + value = "normalized_time"> @@ -1360,10 +1389,10 @@ contextName = "ToolBarController.GamePort(_:):ToolBarController.swift"> + value = "ViewController.current?.mouseCursorJoystickEmulation"> + value = "ViewController.current?.mouseCursorHidden"> @@ -1447,6 +1476,14 @@ + + + + + + @@ -1586,7 +1623,7 @@ value = "m6502.PC"> + value = "m6502.clkfrm"> @@ -1595,7 +1632,7 @@ value = "frameCounter"> + value = "m6502.debugger.on"> @@ -1640,6 +1677,26 @@ + + + + + + + + + + + + + + @@ -1647,7 +1704,7 @@ value = "default_MHz_6502 * 1000 * 1000 / spkr_sample_rate"> + value = "( (spkr_clk + m6502.clkfrm) / ( 1024000 / spkr_sample_rate ) ) * 2"> @@ -1665,98 +1722,58 @@ value = "(spkr_clk + m6502.clkfrm)"> + value = "( (spkr_clk + m6502.clkfrm) / ( default_MHz_6502 * 1000 * 1000 / spkr_sample_rate)) * 2"> + contextName = "AND:6502_instr_logic.h"> + + + value = "line_number"> + + + + + contextName = "ViewController.mouseMoved(with:):ViewController.swift"> + value = "oldLocation"> + value = "mouseLocation"> - - - - - - - - - - - - + value = "view.bounds"> + contextName = "closure #1 in ViewController.Update():ViewController.swift"> + value = "txtArr"> + value = "self.shadowTxt"> - - - - - - + value = "txt"> - - - - - - + value = "MEMcfg.is_80STORE"> - - - - - - - - - - + value = "MEMcfg.txt_page_2"> diff --git a/A2Mac/HiRes.swift b/A2Mac/HiRes.swift index 65032b6..729bfdc 100644 --- a/A2Mac/HiRes.swift +++ b/A2Mac/HiRes.swift @@ -341,9 +341,11 @@ class HiRes: NSView { switch ( pixel ) { case 1: // purple (bits are in reverse!) + pixelsSRGB[colorAddr - 1] = color_purple + pixelsSRGB[colorAddr - 2] = color_purple pixelsSRGB[colorAddr] = color_purple pixelsSRGB[colorAddr + 1] = color_purple - pixelsSRGB[colorAddr + 2] = color_purple +// pixelsSRGB[colorAddr + 2] = color_purple if (colorAddr >= 2) && (prev != 0x03) && (prev != 0x07) && (prev != 0x00) && (prev != 0x04) { pixelsSRGB[colorAddr - 1] = color_purple pixelsSRGB[colorAddr - 2] = color_purple @@ -351,10 +353,10 @@ class HiRes: NSView { case 2: // green // reducing color bleeding - if (colorAddr > 1) && (pixelsSRGB[colorAddr - 2] != color_black) { + if (colorAddr > 1) && ((pixelsSRGB[colorAddr - 2] == color_green) || (pixelsSRGB[colorAddr - 2] == color_white)) { pixelsSRGB[colorAddr + 0] = color_green } - pixelsSRGB[colorAddr] = color_green +// pixelsSRGB[colorAddr] = color_green pixelsSRGB[colorAddr + 1] = color_green pixelsSRGB[colorAddr + 2] = color_green pixelsSRGB[colorAddr + 3] = color_green @@ -371,7 +373,7 @@ class HiRes: NSView { pixelsSRGB[colorAddr + 1] = color_white pixelsSRGB[colorAddr + 2] = color_white pixelsSRGB[colorAddr + 3] = color_white - pixelsSRGB[colorAddr + 4] = color_white +// pixelsSRGB[colorAddr + 4] = color_white case 5: // blue pixelsSRGB[colorAddr + 1] = color_blue @@ -386,8 +388,8 @@ class HiRes: NSView { // reducing color bleeding if (colorAddr > 0) && (pixelsSRGB[colorAddr - 2] != color_black) { pixelsSRGB[colorAddr + 0] = color_orange // important for color bleeding and color contiunity - pixelsSRGB[colorAddr + 1] = color_orange } + pixelsSRGB[colorAddr + 1] = color_orange pixelsSRGB[colorAddr + 2] = color_orange pixelsSRGB[colorAddr + 3] = color_orange pixelsSRGB[colorAddr + 4] = color_orange @@ -397,11 +399,12 @@ class HiRes: NSView { // pixelsSRGB[colorAddr - 2] = color_white // HiRes.pixelsSRGB[colorAddr - 2] pixelsSRGB[colorAddr - 1] = color_white } + pixelsSRGB[colorAddr - 1] = color_white pixelsSRGB[colorAddr + 0] = color_white // Donkey Kong would be perfect but problem in Sneakers pixelsSRGB[colorAddr + 1] = color_white pixelsSRGB[colorAddr + 2] = color_white pixelsSRGB[colorAddr + 3] = color_white - pixelsSRGB[colorAddr + 4] = color_white +// pixelsSRGB[colorAddr + 4] = color_white case 0: // 0x00 (black 1), 0x04 (black 2) // pixelsSRGB[colorAddr + 0] = color_black diff --git a/A2Mac/Info.plist b/A2Mac/Info.plist index 4de6ec2..4f40f82 100644 --- a/A2Mac/Info.plist +++ b/A2Mac/Info.plist @@ -23,7 +23,7 @@ CFBundleVersion 1 LSApplicationCategoryType - public.app-category.education + public.app-category.arcade-games LSMinimumSystemVersion $(MACOSX_DEPLOYMENT_TARGET) NSHumanReadableCopyright diff --git a/Hard Hat Mack - Disk 1, Side A.dsk b/Hard Hat Mack - Disk 1, Side A.dsk new file mode 100644 index 0000000..49d7587 Binary files /dev/null and b/Hard Hat Mack - Disk 1, Side A.dsk differ diff --git a/Hard Hat Mack - Disk 1, Side A.woz b/Hard Hat Mack - Disk 1, Side A.woz new file mode 100644 index 0000000..4ed7d20 Binary files /dev/null and b/Hard Hat Mack - Disk 1, Side A.woz differ diff --git a/src/dev/audio/speaker.c b/src/dev/audio/speaker.c index 22e35bc..42d564f 100644 --- a/src/dev/audio/speaker.c +++ b/src/dev/audio/speaker.c @@ -106,8 +106,9 @@ int spkr_last_level = SPKR_LEVEL_ZERO; //static const int ema_len_soft = 64; //static const int ema_len_supersoft = 80; -int spkr_ema_len = 640; // with EMA -int spkr_ema3_len = 50; // with EMA3 +int spkr_ema_len = 70; // with EMA +int spkr_ema3_len = 30; // with EMA3 +int spkr_ehler_len = 100; // 50; // with Ehler's Super Smoother Filter #define BUFFER_COUNT 32 @@ -290,6 +291,8 @@ static void spkr_debug(FILE * file) { #endif +void ehler_init(const int val, const int cutoffLength); + // initialize OpenAL void spkr_init(void) { const char *defname = alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER); @@ -387,6 +390,8 @@ void spkr_init(void) { // make sure we have free buffers initialized here freeBuffers = BUFFER_COUNT; + + ehler_init(0, spkr_ehler_len); } @@ -785,6 +790,54 @@ INLINE static const double t3_new( } +// Ehler's constants -- must be initialized +static double a1 = 0; +static double coeff2 = 0; +static double coeff3 = 0; +static double coeff1 = 0; + +// Ehler's variables +static int val1 = 0; +static int filt = 0; +static int filt1 = 0; +static int filt2 = 0; + +/// Initializer for the Ehlers' Super Smoother Filter +/// @param val Current value the filter is applied +/// @param cutoffLength Maximum period for a wave cycle to be considered noise +void ehler_init(const int val, const int cutoffLength) { + a1 = exp((-M_PI) * M_SQRT2 / cutoffLength); + coeff2 = 2 * a1 * cos(M_SQRT2 * M_PI / cutoffLength); + coeff3 = -(a1 * a1); + coeff1 = 1 - coeff2 - coeff3; + + val1 = val; + filt = val; + filt1 = val; + filt2 = val; +} + +/// The Ehlers' Super Smoother Filter is a smoothing technique developed by John F. Ehlers, based on aerospace analog filters. This filter aims at reducing noise in price data, which appears to be stronger as the high-to-low price swings increase especially when chart is plotted for greater time intervals. In theory, this filter eliminates the noise completely, as opposed to moving averages, e.g., exponential (EMA) which only offers a modest attenuation effect. +/// +/// Regardless of the time frame used, all waves having cycles of less than 10 bars are considered noise. Thus, the filter only passes those spectral components whose periods are greater than 10 bars. Note that the period of 10 bars is a default value which can be customized using the cutoff length input parameter. +/// @param val Current value the filter is applied +/// @param cutoffLength Maximum period for a wave cycle to be considered noise - This is moved to the ehler_init() +INLINE static const int ehler(const int val) { +// // cutoff must be positive +// if (cutoffLength < 0) { +// return val; +// } + + val1 = val; + filt2 = filt1; + filt1 = filt; + + filt = coeff1 * (val + val1) / 2 + coeff2 * filt1 + coeff3 * filt2; + + return filt; +} + + INLINE static void spkr_filter_ema(spkr_sample_t * buf, const int buf_size) { for ( int i = 0; i < buf_size; ) { spkr_level_ema = ema(buf[i], spkr_level_ema, spkr_ema_len); @@ -874,6 +927,20 @@ INLINE static void spkr_filter_t3(spkr_sample_t * buf, const int buf_size) { } +INLINE static void spkr_filter_ehler(spkr_sample_t * buf, const int buf_size) { + for ( int i = 0; i < buf_size; ) { + const int level = ehler(buf[i]); + + // smoothing with Ehler's Super Smoother Filter + buf[i++] = level; + buf[i++] = level; + } + + // Debug SPKR Buffer After EMA + spkr_debug(spkr_debug_ema_file); +} + + #ifdef SPKR_FILTER_SMA INLINE static void spkr_filter_sma(int buf_len) { static const unsigned sma_len = 35; @@ -899,9 +966,44 @@ INLINE static void spkr_filter_sma(int buf_len) { #ifdef SPKR_OVERSAMPLING +#define DOWNSAMPLE_EMA INLINE static spkr_sample_t spkr_avg(const spkr_sample_t * buf, const int len) { - long sum = 0; +#ifdef DOWNSAMPLE_TEMA + static int level = buf[0]; + static int ema1 = SPKR_LEVEL_ZERO; + static int ema2 = SPKR_LEVEL_ZERO; + static int ema3 = SPKR_LEVEL_ZERO; + + // get the sum for that section + for (int i = 0; i < len; i++) { + ema1 = ema(buf[i * SPKR_CHANNELS], ema1, spkr_ema_len); + ema2 = ema(ema1, ema2, spkr_ema_len); + ema3 = ema(ema2, ema3, spkr_ema_len); + + // smoothing with TEMA + double level = tema(ema1, ema2, ema3); + } + + return level; +#endif + + +#ifdef DOWNSAMPLE_EMA + static int level = SPKR_LEVEL_ZERO; // buf[0]; + + // get the sum for that section + for (int i = 0; i < len; i++) { + level = ema(buf[ i * SPKR_CHANNELS ], level, len); + } + + return level; +#endif + + +#ifdef DOWNSAMPLE_SMA + long sum = 0; + // get the sum for that section for (int i = 0; i < len; i++) { sum += buf[ i * SPKR_CHANNELS ]; @@ -909,9 +1011,11 @@ INLINE static spkr_sample_t spkr_avg(const spkr_sample_t * buf, const int len) { // get the average for that section return sum / len; +#endif } +#ifdef SPKR_AVG_NEW INLINE static spkr_sample_t spkr_avg_new(const spkr_sample_t * buf, int len) { long sum = 0; @@ -939,6 +1043,7 @@ INLINE static spkr_sample_t spkr_avg_new(const spkr_sample_t * buf, int len) { return 0; } +#endif INLINE static void spkr_downsample(void) { @@ -962,12 +1067,16 @@ INLINE static void spkr_filter(void) { #ifdef SPKR_OVERSAMPLING -// spkr_filter_ema( spkr_samples, SPKR_BUF_SIZE ); - spkr_filter_ema3( spkr_samples, SPKR_BUF_SIZE ); + spkr_filter_ema( spkr_samples, SPKR_BUF_SIZE ); // spkr_filter_dema( spkr_samples, SPKR_BUF_SIZE ); // spkr_filter_tema( spkr_samples, SPKR_BUF_SIZE ); // spkr_filter_t3( spkr_samples, SPKR_BUF_SIZE ); + + // The two filters together with the down sampling give you a smooth but crystal sound +// spkr_filter_ema3( spkr_samples, SPKR_BUF_SIZE ); // this will do a prelimenary filtering + spkr_filter_ehler( spkr_samples, SPKR_BUF_SIZE ); // it smooths out very high frequencies. spkr_downsample(); + // spkr_filter_ema( spkr_stream, SPKR_STRM_SLOT_SIZE(1) ); #else spkr_filter_ema( spkr_samples, SPKR_BUF_SIZE ); diff --git a/src/dev/disk/woz.c b/src/dev/disk/woz.c index cdb5650..c25b777 100644 --- a/src/dev/disk/woz.c +++ b/src/dev/disk/woz.c @@ -28,6 +28,7 @@ #include "disk.h" #include "6502.h" #include "common.h" +#include "dsk2woz.h" WOZread_t WOZread = {0}; @@ -37,6 +38,7 @@ WOZread_t WOZwrite = {0}; unsigned trackNextOffset = 0; unsigned trackOffset = 0; unsigned bitOffset = 0; +unsigned bitShift = 0; uint64_t clkelpased; int extraForward = 6; // we search for 7 bit high a bit further to speed up disk read... @@ -48,7 +50,8 @@ uint8_t * woz_file_buffer = NULL; woz_header_t * woz_header; woz_chunk_header_t * woz_chunk_header; woz_tmap_t * woz_tmap; -woz1_trks_t * woz_trks; +woz1_trks_t * woz1_trks; +woz2_trks_t * woz2_trks; int track_loaded = -1; @@ -146,11 +149,59 @@ static uint32_t crc32(const uint8_t *buf, size_t size) { } +static uint32_t getTrackBitsUsed(int track) { + switch ( woz_header->magic ) { + case WOZ1_MAGIC: + return (*woz1_trks)[track].bytes_used * 8 + 1; + + case WOZ2_MAGIC: + return (*woz2_trks)[track].bit_count; + + default: + dbgPrintf("Track Bits ERROR: Invalid WOZ Magic!\n"); + return 0; + } +} + + +static uint16_t getTrackBytesUsed(int track) { + uint32_t bits = getTrackBitsUsed(track); + uint16_t bytes = bits / 8; + + if (bits % 8) { + bytes++; + } + + return bytes; +} + + +static uint8_t * getTrackDataPtr(int track) { + switch ( woz_header->magic ) { + case WOZ1_MAGIC: + return (*woz1_trks)[track].data; + + case WOZ2_MAGIC: { + uint16_t startingBlock = (*woz2_trks)[track].starting_block; +// uint16_t blockCount = (*woz2_trks)[track].block_count; + int dataOffs = startingBlock * 512; + return woz_file_buffer + dataOffs; + } + + default: + dbgPrintf("Track Data ERROR: Invalid WOZ Magic!\n"); + return NULL; + } +} + + void woz_loadTrack_old( int track ) { trackEntry_t reg = {0}; + + uint8_t * trkdata = getTrackDataPtr(track); - reg.shift = (*woz_trks)[track].data[0]; - reg.data = (*woz_trks)[track].data[1]; + reg.shift = trkdata[0]; + reg.data = trkdata[1]; prepared_track[0] = reg; for ( int offs = 1; offs < WOZ1_TRACK_BYTE_COUNT; offs++ ) { @@ -163,7 +214,7 @@ void woz_loadTrack_old( int track ) { reg.shift16 <<= 1; } - reg.data = (*woz_trks)[track].data[ (offs + 1) % WOZ1_TRACK_BYTE_COUNT ]; + reg.data = trkdata[ (offs + 1) % WOZ1_TRACK_BYTE_COUNT ]; prepared_track[offs] = reg; } } @@ -173,13 +224,19 @@ typedef enum wozTrackState_e { wozTrackState_Start = 0, wozTrackState_D5, wozTrackState_D5_AA, - wozTrackState_D5_AA_96, + wozTrackState_D5_AA_B5, // sector header for DOS 3.1 / 3.2 (13 sector format) + wozTrackState_D5_AA_96, // sector header + wozTrackState_D5_AA_AD, // data block + wozTrackState_DE, // epilogue? + wozTrackState_DE_AA, + wozTrackState_DE_AA_EB, // epilogue - end of sector wozTrackState_vol1, wozTrackState_vol2, wozTrackState_trk1, wozTrackState_trk2, wozTrackState_sec1, wozTrackState_sec2, + wozTrackState_ChkSum, wozTrackState_END, } wozTrackState_t; @@ -189,23 +246,87 @@ int vol = 0; int trk = 0; int sec = 0; +extern m6502_t m6502; + +// Sector contents. +static uint8_t contents[343]; + +// Remove bit 7 to address this table -- we save memory... +static const uint8_t six_and_two_reverse_mapping[] = { +// x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 8x + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0x03, 0x00, 0x04, 0x05, 0x06, // 9x + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x08, 0x00, 0x00, 0x00, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, // Ax + 0x00, 0x00, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x00, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, // Bx + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x1C, 0x1D, 0x1E, // Cx + 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x20, 0x21, 0x00, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, // Dx + 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x2A, 0x2B, 0x00, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, // Ex + 0x00, 0x00, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x00, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, // Fx +}; + + wozTrackState_t woz_decodeTrkSec( uint8_t data, uint64_t clkelapsed, int bitOffs ) { static wozTrackState_t wozTrackState = wozTrackState_Start; + static int databytes = 0; + static uint8_t datachksum = 0; + +// printf("*** woz_decodeTrkSec: %02X\n", data); if ( clkelpased > 40 ) { // spent too much time on reading, we cannot reliably decode sector header wozTrackState = wozTrackState_Start; } + if ( data < 0x80 ) { + return wozTrackState; + } + + + switch (data) { + case 0xD5: + dbgPrintf("*** D5 Sector Marker 1st byte\n"); + wozTrackState = wozTrackState_D5; + bitOffs_D5_SecHdr = bitOffs; + break; + + default: + break; + } + + switch (wozTrackState) { case wozTrackState_D5: switch (data) { case 0xAA: -// printf("D5 AA at bitOffset:%d\n", bitOffs); + dbgPrintf("*** D5 AA Sector Marker 2nd byte\n"); wozTrackState = wozTrackState_D5_AA; break; + case 0xD5: + // eliminate stateless 1st byte detection treated as a broken marker + break; + default: + dbgPrintf("*** Broken Sector Marker: D5 %02X\n", data); + wozTrackState = wozTrackState_Start; + break; + } + + break; + + case wozTrackState_DE: + switch (data) { + case 0xAA: + dbgPrintf("*** DE AA Epilogue Marker 2nd byte\n"); + wozTrackState = wozTrackState_DE_AA; + break; + + case 0xDE: + // eliminate stateless 1st byte detection treated as a broken marker + break; + + default: + dbgPrintf("*** Broken Epilogue Marker: DE %02X\n", data); wozTrackState = wozTrackState_Start; break; } @@ -216,11 +337,41 @@ wozTrackState_t woz_decodeTrkSec( uint8_t data, uint64_t clkelapsed, int bitOffs switch (data) { case 0x96: wozTrackState = wozTrackState_vol1; -// printf("D5 AA 96 at bitOffset:%d\n", bitOffs); -// printf("Sector Header at bitOffset:%d\n", bitOffs_D5_SecHdr); + dbgPrintf("*** D5 AA 96 Sector Marker 3rd byte\n"); + dbgPrintf("*** Sector Header ***\n"); break; + case 0xB5: + wozTrackState = wozTrackState_vol1; + dbgPrintf("*** D5 AA B5\n"); + dbgPrintf("*** Sector Data (13 sector disk) ***\n"); + break; + + case 0xAD: + wozTrackState = wozTrackState_D5_AA_AD; + databytes = 0; + datachksum = 0; + dbgPrintf("*** D5 AA AD\n"); + dbgPrintf("*** Sector Data\n"); + break; + default: + dbgPrintf("*** Broken Sector Marker: D5 AA %02X\n", data); + wozTrackState = wozTrackState_Start; + break; + } + + break; + + case wozTrackState_DE_AA: + switch (data) { + case 0xEB: + wozTrackState = wozTrackState_DE_AA_EB; + dbgPrintf("*** DE AA EB Sector Epilogue\n"); + break; + + default: + dbgPrintf("*** Broken Epilogue Marker: DE AA %02X\n", data); wozTrackState = wozTrackState_Start; break; } @@ -256,19 +407,72 @@ wozTrackState_t woz_decodeTrkSec( uint8_t data, uint64_t clkelapsed, int bitOffs sec &= data; wozTrackState = wozTrackState_END; -// printf("Vol:%d Track:%d Sector:%d at bitOffset:%d\n", vol, trk, sec, bitOffs_D5_SecHdr); + dbgPrintf("*** Vol:%d Track:%d Sector:%d at bitShift:%d\n", vol, trk, sec, bitOffs_D5_SecHdr); + + if ((trk == 0) && (sec == 0)) { + m6502.interrupt = BREAK; + } break; - default: - if ( data == 0xD5 ) { -// printf("D5 at bitOffset:%d\n", bitOffs); - wozTrackState = wozTrackState_D5; - bitOffs_D5_SecHdr = bitOffs; + case wozTrackState_D5_AA_AD: { + uint8_t decoded = six_and_two_reverse_mapping[ data &0x7F ]; + +#ifdef DEBUG + if (decoded & 0xC0) { + printf("!!! Vol:%d Track:%d Sector:%d at bitShift:%d\n", vol, trk, sec, bitOffs_D5_SecHdr); + printf("!!! WRONG Decoding: %02X -> %02X\n", data, decoded); + } + + if ((decoded == 0x00) && (data != 0x96)) { + printf("!!! Vol:%d Track:%d Sector:%d at bitShift:%d trackOffset:%d\n", vol, trk, sec, bitOffs_D5_SecHdr, trackOffset); + printf("!!! WRONG Decoding: %02X -> %02X\n", data, decoded); + } + + if (databytes % 16 == 0) { + printf("\n%04X: ", databytes); + } + + // TODO: DEBUG ONLY!!! + if ( (trk==0) && (sec==0) && (databytes == 0xF4) ){ + printf("."); + } + + printf("%02X ", data); +#endif + + datachksum ^= decoded; + contents[databytes++] = decoded; + + if (databytes >= 342) { + wozTrackState = wozTrackState_ChkSum; + dbgPrintf("\n\n*** Vol:%d Track:%d Sector:%d at bitShift:%d\n", vol, trk, sec, bitOffs_D5_SecHdr); + dbgPrintf("Data Bytes: %u\n", databytes); + } + + break; + } + + case wozTrackState_ChkSum: { + wozTrackState = wozTrackState_Start; + uint8_t decoded = six_and_two_reverse_mapping[ data &0x7F ]; + if (datachksum != decoded) { + dbgPrintf("!!! Vol:%d Track:%d Sector:%d at bitShift:%d\n", vol, trk, sec, bitOffs_D5_SecHdr); + dbgPrintf("!!! Data Checksum: WRONG! %02X vs %02X\n", datachksum, decoded); } else { - wozTrackState = wozTrackState_Start; +// printf("Data Checksum: %s %02X vs %02X\n", datachksum == decoded ? "OK" : "WRONG!!!", datachksum, decoded); } + break; + } + default: + switch (data) { + case 0xDE: + dbgPrintf("*** DE Epoligue Marker 1st byte\n"); + wozTrackState = wozTrackState_DE; + break; + } + break; } @@ -284,10 +488,14 @@ void woz_loadTrack( int track ) { prepared_track[0] = reg; int bitOffs = 0; - + uint8_t * trkdata = getTrackDataPtr(track); + + // to trigger a status reset + woz_decodeTrkSec( 0, 999, bitOffs ); + for ( int byteOffs = 0; byteOffs < WOZ1_TRACK_BYTE_COUNT; byteOffs++ ) { - reg.data = (*woz_trks)[track].data[ byteOffs ]; + reg.data = trkdata[ byteOffs ]; for ( int i = 0; i < 8; i++ ) { reg.shift16 <<= 1; @@ -305,20 +513,27 @@ void woz_loadTrack( int track ) { // number needs to be unsigned to work with these macros INLINE unsigned woz_incTrackOffset( unsigned ofs, unsigned limit) { +// if (++ofs >= limit) { +// ofs = 0; +// } +// return ofs; return (ofs + 1) % limit; } INLINE uint8_t woz_readByte(unsigned trk, unsigned ofs) { - return (*woz_trks)[trk].data[ofs]; + uint8_t * trkdata = getTrackDataPtr(trk); + + return trkdata[ofs]; } + uint8_t woz_read(void) { - if ( woz_tmap && woz_trks ) { + if ( woz_tmap && woz1_trks ) { int track = woz_tmap->phase[disk.phase.count]; - dbgPrintf2("track: %d (%d)\n", track, disk.phase.count); + dbgPrintf2("*** track: %d (%d)\n", track, disk.phase.count); if ( track >= 40 ) { - dbgPrintf("TRCK TOO HIGH!\n"); + dbgPrintf("*** TRCK TOO HIGH!\n"); return rand(); } @@ -328,7 +543,7 @@ uint8_t woz_read(void) { clkelpased = clktime - m6502.clklast; m6502.clklast = clktime; - uint16_t usedBytes = (*woz_trks)[track].bytes_used < WOZ1_TRACK_BYTE_COUNT ? (*woz_trks)[track].bytes_used : WOZ1_TRACK_BYTE_COUNT; + uint16_t usedBytes = getTrackBytesUsed(track); if ( usedBytes ) { // static const int extraForward = 4; // we search for 7 bit high a bit further to speed up disk read... @@ -339,13 +554,23 @@ uint8_t woz_read(void) { // Simulate idle spinning until a close point to the actual turn position while ( bitForward-- ) { - if ( ++bitOffset > 7 ) { - bitOffset = 0; + bitOffset++; + bitShift++; + + if (( bitShift > 7 ) || (bitOffset > getTrackBitsUsed(track))) { +// if ( bitShift > 7 ) { + if (bitOffset > getTrackBitsUsed(track)) { + bitOffset = 0; + } + + bitShift = 0; + trackOffset = woz_incTrackOffset(trackOffset, usedBytes); WOZwrite.data = WOZread.data = woz_readByte(track, trackOffset); -//if (outdev) fprintf(outdev, "(%02X.%u:%u): d:%02X\n", track, trackOffset, bitOffset, WOZread.data); +//if (outdev) fprintf(outdev, "(%02X.%u:%u): d:%02X\n", track, trackOffset, bitShift, WOZread.data); +// printf("[%02X] ", WOZread.data); } WOZread.shift <<= 1; @@ -353,19 +578,23 @@ uint8_t woz_read(void) { if ( WOZread.valid ) { latch = WOZread.latch; -//if (outdev) fprintf(outdev, "(%02X.%u:%u): r:%02X\n", track, trackOffset, bitOffset, WOZread.latch); +//if (outdev) fprintf(outdev, "(%02X.%u:%u): r:%02X\n", track, trackOffset, bitShift, WOZread.latch); // latch is cleared when bit 7 is high // WOZwrite.latch = WOZread.latch = 0; // but we do not want to miss that latch valid nibble... // in other words synchronization is needed because of imperfect cycle calculation - if ( bitForward < 18 ) { // for 30 Hz FPS 18 is better ) { + if ( bitForward < 100 ) { // for 30 Hz FPS 18 is better ) { +// printf("*** latch: %02X\n", latch); + woz_decodeTrkSec( latch, 0, bitShift ); return latch; } } } // return nibble +// printf("*** WOZread.latch: %02X\n", WOZread.latch); +// woz_decodeTrkSec( WOZread.latch, 0, bitShift ); return WOZread.latch; } } @@ -400,8 +629,10 @@ void printWozBuffer (const char * s, int n, WOZread_t WOZbuf ) { void woz_write( uint8_t data ) { - if ( woz_tmap && woz_trks ) { + if ( woz_tmap && woz1_trks ) { int track = woz_tmap->phase[disk.phase.count]; + uint8_t * trkdata = getTrackDataPtr(track); + //if (outdev) fprintf(outdev, "track: %d (%d)\n", track, disk.phase.count); if ( track >= 40 ) { dbgPrintf("TRACK TOO HIGH!\n"); @@ -414,12 +645,13 @@ void woz_write( uint8_t data ) { clkelpased = clktime - m6502.clklast; m6502.clklast = clktime; - uint16_t usedBytes = (*woz_trks)[track].bytes_used < WOZ1_TRACK_BYTE_COUNT ? (*woz_trks)[track].bytes_used : WOZ1_TRACK_BYTE_COUNT; + uint32_t usedBits = getTrackBitsUsed(track); + uint16_t usedBytes = getTrackBytesUsed(track); if ( usedBytes ) { uint64_t bitForward = (clkelpased >> 2) + 1; -// uint64_t bitOffsShouldBe = (bitOffset + bitForward) % 8; +// uint64_t bitOffsShouldBe = (bitShift + bitForward) % 8; // uint64_t trkOffsShouldBe = (trackOffset + bitForward / 8) % usedBytes; //if (outdev) fprintf(outdev, "[%02X.%llu:%llu]: *:%02X\n", track, trkOffsShouldBe, bitOffsShouldBe, data); @@ -430,20 +662,20 @@ void woz_write( uint8_t data ) { //printf("("); // Simulate idle spinning until s close point to the actual turn position - while ( bitForward-- ) { - if ( ++bitOffset > 7 ) { - bitOffset = 0; + while ( bitForward-- ) { + if ( ++bitShift > 7 ) { + bitShift = 0; trackOffset = woz_incTrackOffset(trackOffset, usedBytes); WOZwrite.data = WOZread.data = woz_readByte(track, trackOffset); -//if (outdev) fprintf(outdev, "[%02X.%u:%u]: d:%02X (%016llX)\n", track, trackOffset, bitOffset, WOZwrite.data, WOZwrite.shift); +//if (outdev) fprintf(outdev, "[%02X.%u:%u]: d:%02X (%016llX)\n", track, trackOffset, bitShift, WOZwrite.data, WOZwrite.shift); trackNextOffset = woz_incTrackOffset(trackOffset, usedBytes); // load original following data WOZwrite.next = woz_readByte(track, trackNextOffset); -//if (outdev) fprintf(outdev, "[%02X.%u:%u]: n:%02X (%016llX)\n", track, trackNextOffset, bitOffset, WOZwrite.next, WOZwrite.shift); +//if (outdev) fprintf(outdev, "[%02X.%u:%u]: n:%02X (%016llX)\n", track, trackNextOffset, bitShift, WOZwrite.next, WOZwrite.shift); } @@ -451,7 +683,7 @@ void woz_write( uint8_t data ) { WOZwrite.shift <<= 1; if ( WOZread.valid ) { -//if (outdev) fprintf(outdev, "[%02X.%u:%u]: r:%02X (%016llX) {%llu}\n", track, trackOffset, bitOffset, WOZwrite.latch, WOZwrite.shift, bitForward); +//if (outdev) fprintf(outdev, "[%02X.%u:%u]: r:%02X (%016llX) {%llu}\n", track, trackOffset, bitShift, WOZwrite.latch, WOZwrite.shift, bitForward); //printf("%2X ", WOZread.latch); // we do not clear write latch as we need that @@ -468,22 +700,22 @@ void woz_write( uint8_t data ) { // feed write buffer WOZwrite.latch = data; -//if (outdev) fprintf(outdev, "[%02X.%u:%u]: D:%02X (%016llX)\n", track, trackNextOffset, bitOffset, WOZwrite.latch, WOZwrite.shift); +//if (outdev) fprintf(outdev, "[%02X.%u:%u]: D:%02X (%016llX)\n", track, trackNextOffset, bitShift, WOZwrite.latch, WOZwrite.shift); // shift to byte alignment so we can write to the byte stream - WOZwrite.shift >>= bitOffset + 1; + WOZwrite.shift >>= bitShift + 1; // write out upper part -//if (outdev) fprintf(outdev, "[%02X.%u:%u]: R:%02X -> %02X (%016llX)\n", track, trackOffset, 0, (*woz_trks)[track].data[trackOffset], WOZwrite.latch, WOZwrite.shift); - (*woz_trks)[track].data[trackOffset] = WOZwrite.latch; +//if (outdev) fprintf(outdev, "[%02X.%u:%u]: R:%02X -> %02X (%016llX)\n", track, trackOffset, 0, trkdata[trackOffset], WOZwrite.latch, WOZwrite.shift); + trkdata[trackOffset] = WOZwrite.latch; // write out lower part -//if (outdev) fprintf(outdev, "[%02X.%u:%u]: R:%02X -> %02X (%016llX)\n", track, trackNextOffset, 0, (*woz_trks)[track].data[trackNextOffset], WOZwrite.data, WOZwrite.shift); +//if (outdev) fprintf(outdev, "[%02X.%u:%u]: R:%02X -> %02X (%016llX)\n", track, trackNextOffset, 0, trkdata[trackNextOffset], WOZwrite.data, WOZwrite.shift); trackNextOffset = woz_incTrackOffset(trackOffset, usedBytes); - (*woz_trks)[track].data[trackNextOffset] = WOZwrite.data; + trkdata[trackNextOffset] = WOZwrite.data; // shift back to actual bit alignment - WOZwrite.shift <<= bitOffset + 1; + WOZwrite.shift <<= bitShift + 1; } } } @@ -495,7 +727,8 @@ void woz_free_buffer(void) { woz_file_buffer = NULL; woz_header = NULL; woz_tmap = NULL; - woz_trks = NULL; + woz1_trks = NULL; + woz2_trks = NULL; } } @@ -561,7 +794,8 @@ int woz_parseBuffer(void) { break; case WOZ_TRKS_CHUNK_ID: - woz_trks = (woz1_trks_t*) &woz_file_buffer[bufOffs]; + woz1_trks = (woz1_trks_t*) &woz_file_buffer[bufOffs]; + woz2_trks = (woz2_trks_t*) &woz_file_buffer[bufOffs]; break; case WOZ_META_CHUNK_ID: diff --git a/woz_debug.rtf b/woz_debug.rtf index 75cbd5b..3b07b3d 100644 --- a/woz_debug.rtf +++ b/woz_debug.rtf @@ -1,5 +1,353 @@ -{\rtf1\ansi\ansicpg1252\cocoartf949 -{\fonttbl} -{\colortbl;\red255\green255\blue255;} +{\rtf1\ansi\ansicpg1252\cocoartf2709 +\cocoatextscaling0\cocoaplatform0{\fonttbl\f0\fnil\fcharset0 Menlo-Regular;} +{\colortbl;\red255\green255\blue255;\red255\green255\blue255;\red24\green23\blue27;} +{\*\expandedcolortbl;;\csgenericrgb\c100000\c100000\c100000;\csgenericrgb\c9220\c9172\c10609;} \margl1440\margr1440\vieww9000\viewh8400\viewkind0 +\deftab593 +\pard\tx593\pardeftab593\partightenfactor0 + +\f0\fs24 \cf2 \cb3 \ +*** D5 Sector Marker 1st byte\ +*** D5 AA Sector Marker 2nd byte\ +*** D5 AA 96 Sector Marker 3rd byte\ +*** Sector Header ***\ +*** Vol:254 Track:0 Sector:0 at bitOffset:7\ +*** DE Epoligue Marker 1st byte\ +*** DE AA Epilogue Marker 2nd byte\ +*** DE AA EB\ +*** Sector Epilogue\ +*** D5 Sector Marker 1st byte\ +*** D5 AA Sector Marker 2nd byte\ +*** D5 AA AD\ +*** Sector Data\ +*** DE Epoligue Marker 1st byte\ +*** Broken Epilogue Marker: DE E9\ +*** DE Epoligue Marker 1st byte\ +*** DE Epoligue Marker 1st byte\ +*** Broken Epilogue Marker: DE A7\ +*** DE Epoligue Marker 1st byte\ +*** DE AA Epilogue Marker 2nd byte\ +*** DE AA EB\ +*** Sector Epilogue\ +*** D5 Sector Marker 1st byte\ +*** D5 AA Sector Marker 2nd byte\ +*** D5 AA 96 Sector Marker 3rd byte\ +*** Sector Header ***\ +*** Vol:254 Track:0 Sector:1 at bitOffset:0\ +*** DE Epoligue Marker 1st byte\ +*** DE AA Epilogue Marker 2nd byte\ +*** DE AA EB\ +*** Sector Epilogue\ +*** D5 Sector Marker 1st byte\ +*** D5 AA Sector Marker 2nd byte\ +*** D5 AA AD\ +*** Sector Data\ +*** DE Epoligue Marker 1st byte\ +*** DE AA Epilogue Marker 2nd byte\ +*** DE AA EB\ +*** Sector Epilogue\ +*** D5 Sector Marker 1st byte\ +*** D5 AA Sector Marker 2nd byte\ +*** D5 AA 96 Sector Marker 3rd byte\ +*** Sector Header ***\ +*** Vol:254 Track:0 Sector:2 at bitOffset:2\ +*** DE Epoligue Marker 1st byte\ +*** DE AA Epilogue Marker 2nd byte\ +*** DE AA EB\ +*** Sector Epilogue\ +*** D5 Sector Marker 1st byte\ +*** D5 AA Sector Marker 2nd byte\ +*** D5 AA AD\ +*** Sector Data\ +*** DE Epoligue Marker 1st byte\ +*** DE AA Epilogue Marker 2nd byte\ +*** DE AA EB\ +*** Sector Epilogue\ +*** D5 Sector Marker 1st byte\ +*** D5 AA Sector Marker 2nd byte\ +*** D5 AA 96 Sector Marker 3rd byte\ +*** Sector Header ***\ +*** Vol:254 Track:0 Sector:3 at bitOffset:4\ +*** DE Epoligue Marker 1st byte\ +*** DE AA Epilogue Marker 2nd byte\ +*** DE AA EB\ +*** Sector Epilogue\ +*** D5 Sector Marker 1st byte\ +*** D5 AA Sector Marker 2nd byte\ +*** D5 AA AD\ +*** Sector Data\ +*** DE Epoligue Marker 1st byte\ +*** DE AA Epilogue Marker 2nd byte\ +*** DE AA EB\ +*** Sector Epilogue\ +*** D5 Sector Marker 1st byte\ +*** D5 AA Sector Marker 2nd byte\ +*** D5 AA 96 Sector Marker 3rd byte\ +*** Sector Header ***\ +*** Vol:254 Track:0 Sector:4 at bitOffset:6\ +*** DE Epoligue Marker 1st byte\ +*** DE AA Epilogue Marker 2nd byte\ +*** DE AA EB\ +*** Sector Epilogue\ +*** D5 Sector Marker 1st byte\ +*** D5 AA Sector Marker 2nd byte\ +*** D5 AA AD\ +*** Sector Data\ +*** DE Epoligue Marker 1st byte\ +*** DE AA Epilogue Marker 2nd byte\ +*** DE AA EB\ +*** Sector Epilogue\ +*** D5 Sector Marker 1st byte\ +*** D5 AA Sector Marker 2nd byte\ +*** D5 AA 96 Sector Marker 3rd byte\ +*** Sector Header ***\ +*** Vol:254 Track:0 Sector:5 at bitOffset:0\ +*** DE Epoligue Marker 1st byte\ +*** DE AA Epilogue Marker 2nd byte\ +*** DE AA EB\ +*** Sector Epilogue\ +*** D5 Sector Marker 1st byte\ +*** D5 AA Sector Marker 2nd byte\ +*** D5 AA AD\ +*** Sector Data\ +*** DE Epoligue Marker 1st byte\ +*** DE AA Epilogue Marker 2nd byte\ +*** DE AA EB\ +*** Sector Epilogue\ +*** D5 Sector Marker 1st byte\ +*** D5 AA Sector Marker 2nd byte\ +*** D5 AA 96 Sector Marker 3rd byte\ +*** Sector Header ***\ +*** Vol:254 Track:0 Sector:6 at bitOffset:2\ +*** DE Epoligue Marker 1st byte\ +*** DE AA Epilogue Marker 2nd byte\ +*** DE AA EB\ +*** Sector Epilogue\ +*** D5 Sector Marker 1st byte\ +*** D5 AA Sector Marker 2nd byte\ +*** D5 AA AD\ +*** Sector Data\ +*** DE Epoligue Marker 1st byte\ +*** DE AA Epilogue Marker 2nd byte\ +*** DE AA EB\ +*** Sector Epilogue\ +*** D5 Sector Marker 1st byte\ +*** D5 AA Sector Marker 2nd byte\ +*** D5 AA 96 Sector Marker 3rd byte\ +*** Sector Header ***\ +*** Vol:254 Track:0 Sector:7 at bitOffset:4\ +*** DE Epoligue Marker 1st byte\ +*** DE AA Epilogue Marker 2nd byte\ +*** DE AA EB\ +*** Sector Epilogue\ +*** D5 Sector Marker 1st byte\ +*** D5 AA Sector Marker 2nd byte\ +*** D5 AA AD\ +*** Sector Data\ +*** DE Epoligue Marker 1st byte\ +*** DE AA Epilogue Marker 2nd byte\ +*** DE AA EB\ +*** Sector Epilogue\ +*** D5 Sector Marker 1st byte\ +*** D5 AA Sector Marker 2nd byte\ +*** D5 AA 96 Sector Marker 3rd byte\ +*** Sector Header ***\ +*** Vol:254 Track:0 Sector:8 at bitOffset:6\ +*** DE Epoligue Marker 1st byte\ +*** DE AA Epilogue Marker 2nd byte\ +*** DE AA EB\ +*** Sector Epilogue\ +*** D5 Sector Marker 1st byte\ +*** D5 AA Sector Marker 2nd byte\ +*** D5 AA AD\ +*** Sector Data\ +*** DE Epoligue Marker 1st byte\ +*** DE AA Epilogue Marker 2nd byte\ +*** DE AA EB\ +*** Sector Epilogue\ +*** D5 Sector Marker 1st byte\ +*** D5 AA Sector Marker 2nd byte\ +*** D5 AA 96 Sector Marker 3rd byte\ +*** Sector Header ***\ +*** Vol:254 Track:0 Sector:9 at bitOffset:0\ +*** DE Epoligue Marker 1st byte\ +*** DE AA Epilogue Marker 2nd byte\ +*** DE AA EB\ +*** Sector Epilogue\ +*** D5 Sector Marker 1st byte\ +*** D5 AA Sector Marker 2nd byte\ +*** D5 AA AD\ +*** Sector Data\ +*** DE Epoligue Marker 1st byte\ +*** Broken Epilogue Marker: DE BE\ +*** DE Epoligue Marker 1st byte\ +*** Broken Epilogue Marker: DE 97\ +*** DE Epoligue Marker 1st byte\ +*** Broken Epilogue Marker: DE FF\ +*** DE Epoligue Marker 1st byte\ +*** Broken Epilogue Marker: DE DD\ +*** DE Epoligue Marker 1st byte\ +*** DE AA Epilogue Marker 2nd byte\ +*** DE AA EB\ +*** Sector Epilogue\ +*** D5 Sector Marker 1st byte\ +*** D5 AA Sector Marker 2nd byte\ +*** D5 AA 96 Sector Marker 3rd byte\ +*** Sector Header ***\ +*** Vol:254 Track:0 Sector:10 at bitOffset:2\ +*** DE Epoligue Marker 1st byte\ +*** DE AA Epilogue Marker 2nd byte\ +*** DE AA EB\ +*** Sector Epilogue\ +*** D5 Sector Marker 1st byte\ +*** D5 AA Sector Marker 2nd byte\ +*** D5 AA AD\ +*** Sector Data\ +*** DE Epoligue Marker 1st byte\ +*** Broken Epilogue Marker: DE AB\ +*** DE Epoligue Marker 1st byte\ +*** Broken Epilogue Marker: DE 9F\ +*** DE Epoligue Marker 1st byte\ +*** Broken Epilogue Marker: DE B2\ +*** DE Epoligue Marker 1st byte\ +*** DE AA Epilogue Marker 2nd byte\ +*** DE AA EB\ +*** Sector Epilogue\ +*** D5 Sector Marker 1st byte\ +*** D5 AA Sector Marker 2nd byte\ +*** D5 AA 96 Sector Marker 3rd byte\ +*** Sector Header ***\ +*** Vol:254 Track:0 Sector:11 at bitOffset:4\ +*** DE Epoligue Marker 1st byte\ +*** DE AA Epilogue Marker 2nd byte\ +*** DE AA EB\ +*** Sector Epilogue\ +*** D5 Sector Marker 1st byte\ +*** D5 AA Sector Marker 2nd byte\ +*** D5 AA AD\ +*** Sector Data\ +*** DE Epoligue Marker 1st byte\ +*** Broken Epilogue Marker: DE D7\ +*** DE Epoligue Marker 1st byte\ +*** Broken Epilogue Marker: DE D6\ +*** DE Epoligue Marker 1st byte\ +*** Broken Epilogue Marker: DE B4\ +*** DE Epoligue Marker 1st byte\ +*** DE Epoligue Marker 1st byte\ +*** Broken Epilogue Marker: DE D7\ +*** DE Epoligue Marker 1st byte\ +*** DE Epoligue Marker 1st byte\ +*** Broken Epilogue Marker: DE FE\ +*** DE Epoligue Marker 1st byte\ +*** DE Epoligue Marker 1st byte\ +*** Broken Epilogue Marker: DE F5\ +*** DE Epoligue Marker 1st byte\ +*** DE AA Epilogue Marker 2nd byte\ +*** DE AA EB\ +*** Sector Epilogue\ +*** D5 Sector Marker 1st byte\ +*** D5 AA Sector Marker 2nd byte\ +*** D5 AA 96 Sector Marker 3rd byte\ +*** Sector Header ***\ +*** Vol:254 Track:0 Sector:12 at bitOffset:6\ +*** DE Epoligue Marker 1st byte\ +*** DE AA Epilogue Marker 2nd byte\ +*** DE AA EB\ +*** Sector Epilogue\ +*** D5 Sector Marker 1st byte\ +*** D5 AA Sector Marker 2nd byte\ +*** D5 AA AD\ +*** Sector Data\ +*** DE Epoligue Marker 1st byte\ +*** Broken Epilogue Marker: DE 9E\ +*** DE Epoligue Marker 1st byte\ +*** Broken Epilogue Marker: DE 97\ +*** DE Epoligue Marker 1st byte\ +*** Broken Epilogue Marker: DE EA\ +*** DE Epoligue Marker 1st byte\ +*** Broken Epilogue Marker: DE F5\ +*** DE Epoligue Marker 1st byte\ +*** Broken Epilogue Marker: DE AB\ +*** DE Epoligue Marker 1st byte\ +*** DE AA Epilogue Marker 2nd byte\ +*** DE AA EB\ +*** Sector Epilogue\ +*** D5 Sector Marker 1st byte\ +*** D5 AA Sector Marker 2nd byte\ +*** D5 AA 96 Sector Marker 3rd byte\ +*** Sector Header ***\ +*** Vol:254 Track:0 Sector:13 at bitOffset:0\ +*** DE Epoligue Marker 1st byte\ +*** DE AA Epilogue Marker 2nd byte\ +*** DE AA EB\ +*** Sector Epilogue\ +*** D5 Sector Marker 1st byte\ +*** D5 AA Sector Marker 2nd byte\ +*** D5 AA AD\ +*** Sector Data\ +*** DE Epoligue Marker 1st byte\ +*** Broken Epilogue Marker: DE 96\ +*** DE Epoligue Marker 1st byte\ +*** DE AA Epilogue Marker 2nd byte\ +*** DE AA EB\ +*** Sector Epilogue\ +*** D5 Sector Marker 1st byte\ +*** D5 AA Sector Marker 2nd byte\ +*** D5 AA 96 Sector Marker 3rd byte\ +*** Sector Header ***\ +*** Vol:254 Track:0 Sector:14 at bitOffset:2\ +*** DE Epoligue Marker 1st byte\ +*** DE AA Epilogue Marker 2nd byte\ +*** DE AA EB\ +*** Sector Epilogue\ +*** D5 Sector Marker 1st byte\ +*** D5 AA Sector Marker 2nd byte\ +*** D5 AA AD\ +*** Sector Data\ +*** DE Epoligue Marker 1st byte\ +*** Broken Epilogue Marker: DE BF\ +*** DE Epoligue Marker 1st byte\ +*** DE Epoligue Marker 1st byte\ +*** Broken Epilogue Marker: DE E5\ +*** DE Epoligue Marker 1st byte\ +*** DE Epoligue Marker 1st byte\ +*** Broken Epilogue Marker: DE 96\ +*** DE Epoligue Marker 1st byte\ +*** DE Epoligue Marker 1st byte\ +*** Broken Epilogue Marker: DE 96\ +*** DE Epoligue Marker 1st byte\ +*** DE Epoligue Marker 1st byte\ +*** Broken Epilogue Marker: DE 96\ +*** DE Epoligue Marker 1st byte\ +*** DE AA Epilogue Marker 2nd byte\ +*** DE AA EB\ +*** Sector Epilogue\ +*** D5 Sector Marker 1st byte\ +*** D5 AA Sector Marker 2nd byte\ +*** D5 AA 96 Sector Marker 3rd byte\ +*** Sector Header ***\ +*** Vol:254 Track:0 Sector:15 at bitOffset:4\ +*** DE Epoligue Marker 1st byte\ +*** DE AA Epilogue Marker 2nd byte\ +*** DE AA EB\ +*** Sector Epilogue\ +*** D5 Sector Marker 1st byte\ +*** D5 AA Sector Marker 2nd byte\ +*** D5 AA AD\ +*** Sector Data\ +*** DE Epoligue Marker 1st byte\ +*** Broken Epilogue Marker: DE AD\ +*** DE Epoligue Marker 1st byte\ +*** DE AA Epilogue Marker 2nd byte\ +*** DE AA EB\ +*** Sector Epilogue\ +*** D5 Sector Marker 1st byte\ +*** D5 AA Sector Marker 2nd byte\ +*** D5 AA 96 Sector Marker 3rd byte\ +*** Sector Header ***\ +*** Vol:254 Track:0 Sector:0 at bitOffset:7\ +*** DE Epoligue Marker 1st byte\ +*** DE AA Epilogue Marker 2nd byte\ +*** DE AA EB\ +*** Sector Epilogue\ } \ No newline at end of file