Woz 2.0 + Better HiRes + Better Sound + Hard Hat Mack disk

This commit is contained in:
Tamas Rudnai 2024-05-07 20:10:16 -07:00
parent 41cfb1efde
commit 68ef567994
9 changed files with 923 additions and 210 deletions

View File

@ -639,6 +639,7 @@
32440BA22480D5C0000F9DA1 /* LoRes.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoRes.swift; sourceTree = "<group>"; };
324D15D224ADAC71008AAFB0 /* floppy.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = floppy.png; sourceTree = "<group>"; };
32544194264A6C1600B7E3ED /* DisplayView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DisplayView.swift; sourceTree = "<group>"; };
32583B682B5CAD8700A45F0A /* woz_debug.rtf */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; path = woz_debug.rtf; sourceTree = "<group>"; };
325B75DF2909F95000B29605 /* 6502_dbg.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = 6502_dbg.c; sourceTree = "<group>"; };
325B7652290A32CC00B29605 /* 6502_dbg.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = 6502_dbg.h; sourceTree = "<group>"; };
325DC40D24AC5ABC00EB8858 /* doc.on.doc.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = doc.on.doc.png; sourceTree = "<group>"; };
@ -1148,6 +1149,7 @@
32BFFB4E22EACC630003B53F = {
isa = PBXGroup;
children = (
32583B682B5CAD8700A45F0A /* woz_debug.rtf */,
32D08991291AF23500F2B486 /* Debug.storyboard */,
326426112328ADF4008B615F /* Apple_II_ROM.s */,
325EB63123F8861A00C6B4A4 /* src */,

View File

@ -3,22 +3,10 @@
version = "1.0">
<ContextStates>
<ContextState
contextName = "HiRes.initMetal():HiRes.swift">
contextName = "ViewController.newUpdateTimer(timeInterval:):ViewController.swift">
<PersistentStrings>
<PersistentString
value = "mtlBufferB">
</PersistentString>
<PersistentString
value = "addFunction">
</PersistentString>
<PersistentString
value = "device">
</PersistentString>
<PersistentString
value = "mtlBufferA">
</PersistentString>
<PersistentString
value = "mtlBufferC">
value = "upd">
</PersistentString>
</PersistentStrings>
</ContextState>
@ -26,30 +14,59 @@
contextName = "HiRes.compute():HiRes.swift">
<PersistentStrings>
<PersistentString
value = "UnsafeRawBufferPointer(result)">
value = "computePipelineState.maxTotalThreadsPerThreadgroup">
</PersistentString>
<PersistentString
value = "result[2]">
</PersistentString>
<PersistentString
value = "computePipelineState.maxTotalThreadsPerThreadgroup">
value = "UnsafeRawBufferPointer(result)">
</PersistentString>
</PersistentStrings>
</ContextState>
<ContextState
contextName = "AND:6502_instr_logic.h">
</ContextState>
<ContextState
contextName = "specialized closure #1 in DebuggerViewController.DisplayDisassembly():DebuggerViewController.swift">
contextName = "_memwrite8_low:mmio.c">
<PersistentStrings>
<PersistentString
value = "line_number">
value = "MEMcfg">
</PersistentString>
<PersistentString
value = "currentScrollLine">
value = "currentLowWRMEM == Apple2_64K_MEM">
</PersistentString>
<PersistentString
value = "current_line_number">
value = "WRLOMEM == currentLowWRMEM">
</PersistentString>
<PersistentString
value = "currentLowWRMEM == Apple2_64K_RAM">
</PersistentString>
<PersistentString
value = "m6502.PC">
</PersistentString>
<PersistentString
value = "WRLOMEM == Apple2_64K_MEM">
</PersistentString>
<PersistentString
value = "RDLOMEM == WRLOMEM">
</PersistentString>
<PersistentString
value = "currentLowWRMEM == Apple2_64K_AUX">
</PersistentString>
<PersistentString
value = "WRLOMEM[0x3F6]">
</PersistentString>
</PersistentStrings>
</ContextState>
<ContextState
contextName = "m6502_Debug:6502.c">
<PersistentStrings>
<PersistentString
value = "m6502.SP">
</PersistentString>
<PersistentString
value = "m6502.debugger.mask.ret">
</PersistentString>
<PersistentString
value = "m6502.debugger.SP">
</PersistentString>
</PersistentStrings>
</ContextState>
@ -74,16 +91,13 @@
</PersistentStrings>
</ContextState>
<ContextState
contextName = "ViewController.mouseMoved(with:):ViewController.swift">
contextName = "memwrite8_bank2:mmio.h">
<PersistentStrings>
<PersistentString
value = "oldLocation">
value = "WRD0MEM">
</PersistentString>
<PersistentString
value = "mouseLocation">
</PersistentString>
<PersistentString
value = "view.bounds">
value = "WRHIMEM">
</PersistentString>
</PersistentStrings>
</ContextState>
@ -102,30 +116,36 @@
value = "disassLineRange[forLine]">
</PersistentString>
<PersistentString
value = "disassLineRange.count">
value = "disassLineRange">
</PersistentString>
<PersistentString
value = "disassLineRange">
value = "disassLineRange.count">
</PersistentString>
</PersistentStrings>
</ContextState>
<ContextState
contextName = "closure #1 in ViewController.Update():ViewController.swift">
contextName = "woz_write:woz.c">
<PersistentStrings>
<PersistentString
value = "MEMcfg.is_80STORE">
value = "WOZwrite.data">
</PersistentString>
<PersistentString
value = "self.shadowTxt">
value = "new">
</PersistentString>
<PersistentString
value = "txt">
value = "WOZwrite.shift16">
</PersistentString>
<PersistentString
value = "MEMcfg.txt_page_2">
value = "WOZwrite.shift">
</PersistentString>
<PersistentString
value = "txtArr">
value = "bitOffset">
</PersistentString>
<PersistentString
value = "(1 &lt;&lt; i) - 1">
</PersistentString>
<PersistentString
value = "WOZtmp.shift16">
</PersistentString>
</PersistentStrings>
</ContextState>
@ -165,10 +185,10 @@
contextName = "HiRes.draw(_:):HiRes.swift">
<PersistentStrings>
<PersistentString
value = "HiRes.blockCols">
value = "linAddr">
</PersistentString>
<PersistentString
value = "ctx?.data">
value = "ctx?.bitsPerComponent">
</PersistentString>
<PersistentString
value = "ctx?.width">
@ -185,6 +205,9 @@
<PersistentString
value = "HiResLineAddrTbl">
</PersistentString>
<PersistentString
value = "HiRes.blockCols">
</PersistentString>
<PersistentString
value = "shadowScreen">
</PersistentString>
@ -195,10 +218,7 @@
value = "ctx?.height">
</PersistentString>
<PersistentString
value = "linAddr">
</PersistentString>
<PersistentString
value = "ctx?.bitsPerComponent">
value = "ctx?.data">
</PersistentString>
</PersistentStrings>
</ContextState>
@ -226,7 +246,7 @@
contextName = "DebuggerViewController.DisplayDisassembly():DebuggerViewController.swift">
<PersistentStrings>
<PersistentString
value = "disass_addr_min">
value = "line_number">
</PersistentString>
<PersistentString
value = "disass_addr">
@ -235,7 +255,7 @@
value = "m6502.PC">
</PersistentString>
<PersistentString
value = "line_number">
value = "disass_addr_min">
</PersistentString>
</PersistentStrings>
</ContextState>
@ -472,10 +492,10 @@
value = "WRLOMEM == Apple2_64K_RAM">
</PersistentString>
<PersistentString
value = "currentLowWRMEM == newWriteMEM">
value = "newReadMEM == Apple2_64K_RAM + 0x200">
</PersistentString>
<PersistentString
value = "newReadMEM == Apple2_64K_RAM + 0x200">
value = "currentLowWRMEM == newWriteMEM">
</PersistentString>
<PersistentString
value = "newReadMEM == currentLowRDMEM">
@ -534,7 +554,7 @@
value = "m6502_saved.PC">
</PersistentString>
<PersistentString
value = "isCurrentLine">
value = "scroll_line_number">
</PersistentString>
<PersistentString
value = "highlighted_line_number">
@ -543,7 +563,7 @@
value = "m6502.PC">
</PersistentString>
<PersistentString
value = "scroll_line_number">
value = "isCurrentLine">
</PersistentString>
</PersistentStrings>
</ContextState>
@ -557,7 +577,7 @@
value = "textDisplay_height_diff">
</PersistentString>
<PersistentString
value = "textDisplay_width_diff">
value = "textDisplay.frame">
</PersistentString>
<PersistentString
value = "MonitorView.textViewBounds">
@ -566,10 +586,10 @@
value = "frame.size">
</PersistentString>
<PersistentString
value = "textDisplay.bounds">
value = "textDisplay_width_diff">
</PersistentString>
<PersistentString
value = "textDisplay.frame">
value = "textDisplay.bounds">
</PersistentString>
</PersistentStrings>
</ContextState>
@ -635,10 +655,10 @@
contextName = "set_flags_NZC:common.h">
<PersistentStrings>
<PersistentString
value = "(unsigned)0xFF">
value = "(unsigned)test ">
</PersistentString>
<PersistentString
value = "(unsigned)test ">
value = "(unsigned)0xFF">
</PersistentString>
</PersistentStrings>
</ContextState>
@ -748,10 +768,10 @@
value = "MEMcfg.int_Cx_ROM">
</PersistentString>
<PersistentString
value = "m6502.clkfrm">
value = "(int)IOframe">
</PersistentString>
<PersistentString
value = "(int)IOframe">
value = "m6502.clkfrm">
</PersistentString>
</PersistentStrings>
</ContextState>
@ -762,10 +782,10 @@
value = "Apple2_64K_AUX + 0xC600">
</PersistentString>
<PersistentString
value = "Apple2_64K_RAM + 0xC600">
value = "(void*)rom">
</PersistentString>
<PersistentString
value = "(void*)rom">
value = "Apple2_64K_RAM + 0xC600">
</PersistentString>
<PersistentString
value = "strlen(fullPath)">
@ -897,16 +917,16 @@
contextName = "DisplayScrollView.scrollWheel(with:):DisplayScrollView.swift">
<PersistentStrings>
<PersistentString
value = "textView.defaultParagraphStyle?.lineSpacing">
value = "subviews[1].subviews">
</PersistentString>
<PersistentString
value = "subviews">
</PersistentString>
<PersistentString
value = "subviews[1].subviews">
value = "documentView">
</PersistentString>
<PersistentString
value = "documentView">
value = "textView.defaultParagraphStyle?.lineSpacing">
</PersistentString>
</PersistentStrings>
</ContextState>
@ -1006,10 +1026,10 @@
contextName = "_fetch_dbg:mmio.c">
<PersistentStrings>
<PersistentString
value = "disassembly.pOpcode">
value = "memread8_low(m6502.PC)">
</PersistentString>
<PersistentString
value = "memread8_low(m6502.PC)">
value = "disassembly.pOpcode">
</PersistentString>
</PersistentStrings>
</ContextState>
@ -1017,13 +1037,13 @@
contextName = "m6502_dbg_bp_add:6502_bp.c">
<PersistentStrings>
<PersistentString
value = "bp">
value = "bp_array">
</PersistentString>
<PersistentString
value = "mem_bp_arr">
</PersistentString>
<PersistentString
value = "bp_array">
value = "bp">
</PersistentString>
</PersistentStrings>
</ContextState>
@ -1098,7 +1118,7 @@
contextName = "DebuggerViewController.DisplayDisassembly(scrollY:):DebuggerViewController.swift">
<PersistentStrings>
<PersistentString
value = "scroll_line_number">
value = "isCurrentLine">
</PersistentString>
<PersistentString
value = "highlighted_line_number">
@ -1107,7 +1127,7 @@
value = "m6502.PC">
</PersistentString>
<PersistentString
value = "isCurrentLine">
value = "scroll_line_number">
</PersistentString>
</PersistentStrings>
</ContextState>
@ -1136,20 +1156,20 @@
</PersistentString>
</PersistentStrings>
</ContextState>
<ContextState
contextName = "CMP:6502_instr_compare_test.h">
</ContextState>
<ContextState
contextName = "LoRes.Render():LoRes.swift">
<PersistentStrings>
<PersistentString
value = "shadowScreen">
</PersistentString>
<PersistentString
value = "blockChanged">
</PersistentString>
<PersistentString
value = "shadowScreen">
</PersistentString>
</PersistentStrings>
</ContextState>
<ContextState
contextName = "CMP:6502_instr_compare_test.h">
</ContextState>
<ContextState
contextName = "specialized closure #1 in ViewController.Update():ViewController.swift">
<PersistentStrings>
@ -1200,6 +1220,9 @@
<ContextState
contextName = "woz_read:woz.c">
<PersistentStrings>
<PersistentString
value = "(*woz1_trks)[track].bytes_used">
</PersistentString>
<PersistentString
value = "m6502.clktime">
</PersistentString>
@ -1212,6 +1235,12 @@
<PersistentString
value = "m6502.clklast">
</PersistentString>
<PersistentString
value = "WOZread.latch">
</PersistentString>
<PersistentString
value = "getTrackBitsUsed(track) - bitOffset">
</PersistentString>
</PersistentStrings>
</ContextState>
<ContextState
@ -1234,7 +1263,7 @@
contextName = "LoRes.Update():LoRes.swift">
<PersistentStrings>
<PersistentString
value = "UInt8( (block &gt;&gt; 4) &amp; 0x0F )">
value = "blockChanged[ screenIdx ]">
</PersistentString>
<PersistentString
value = "UInt8(block)">
@ -1243,7 +1272,7 @@
value = "UInt8(block &amp; 4)">
</PersistentString>
<PersistentString
value = "blockChanged[ screenIdx ]">
value = "UInt8( (block &gt;&gt; 4) &amp; 0x0F )">
</PersistentString>
</PersistentStrings>
</ContextState>
@ -1300,22 +1329,22 @@
value = "m6502">
</PersistentString>
<PersistentString
value = "m6502.PC">
value = "(void*)Apple2_64K_RAM">
</PersistentString>
<PersistentString
value = "m6502.clkfrm">
value = "Apple2_64K_RAM + 0x3600">
</PersistentString>
<PersistentString
value = "m6502.ecoSpindown">
</PersistentString>
<PersistentString
value = "m6502.PC">
</PersistentString>
<PersistentString
value = "Apple2_64K_AUX + 0x3600">
</PersistentString>
<PersistentString
value = "(void*)Apple2_64K_RAM">
</PersistentString>
<PersistentString
value = "Apple2_64K_RAM + 0x3600">
value = "m6502.clkfrm">
</PersistentString>
</PersistentStrings>
</ContextState>
@ -1329,7 +1358,7 @@
value = "pdl_value[pdl]">
</PersistentString>
<PersistentString
value = "normalized_time">
value = "normalized_time &gt;= pdl_value[pdl] ? 255 : 0">
</PersistentString>
<PersistentString
value = "(3300 * 255/3300)">
@ -1341,7 +1370,7 @@
value = "1 * 512 * (1 - ( 3300 / 3300.0 ))">
</PersistentString>
<PersistentString
value = "normalized_time &gt;= pdl_value[pdl] ? 255 : 0">
value = "normalized_time">
</PersistentString>
</PersistentStrings>
</ContextState>
@ -1360,10 +1389,10 @@
contextName = "ToolBarController.GamePort(_:):ToolBarController.swift">
<PersistentStrings>
<PersistentString
value = "ViewController.current?.mouseCursorHidden">
value = "ViewController.current?.mouseCursorJoystickEmulation">
</PersistentString>
<PersistentString
value = "ViewController.current?.mouseCursorJoystickEmulation">
value = "ViewController.current?.mouseCursorHidden">
</PersistentString>
</PersistentStrings>
</ContextState>
@ -1447,6 +1476,14 @@
</PersistentString>
</PersistentStrings>
</ContextState>
<ContextState
contextName = "woz_decodeTrkSec:woz.c">
<PersistentStrings>
<PersistentString
value = "bitOffset">
</PersistentString>
</PersistentStrings>
</ContextState>
<ContextState
contextName = "DisplayView.mouseExited(with:):DisplayView.swift">
<PersistentStrings>
@ -1586,7 +1623,7 @@
value = "m6502.PC">
</PersistentString>
<PersistentString
value = "m6502.debugger.on">
value = "m6502.clkfrm">
</PersistentString>
<PersistentString
value = "textLines * (textCols+1) + textCols">
@ -1595,7 +1632,7 @@
value = "frameCounter">
</PersistentString>
<PersistentString
value = "m6502.clkfrm">
value = "m6502.debugger.on">
</PersistentString>
<PersistentString
value = "spkr_play_disk_motor_time">
@ -1640,6 +1677,26 @@
</PersistentString>
</PersistentStrings>
</ContextState>
<ContextState
contextName = "HiRes.initMetal():HiRes.swift">
<PersistentStrings>
<PersistentString
value = "mtlBufferB">
</PersistentString>
<PersistentString
value = "addFunction">
</PersistentString>
<PersistentString
value = "device">
</PersistentString>
<PersistentString
value = "mtlBufferA">
</PersistentString>
<PersistentString
value = "mtlBufferC">
</PersistentString>
</PersistentStrings>
</ContextState>
<ContextState
contextName = "spkr_toggle:speaker.c">
<PersistentStrings>
@ -1647,7 +1704,7 @@
value = "default_MHz_6502 * 1000 * 1000 / spkr_sample_rate">
</PersistentString>
<PersistentString
value = "( (spkr_clk + m6502.clkfrm) / ( default_MHz_6502 * 1000 * 1000 / spkr_sample_rate)) * 2">
value = "( (spkr_clk + m6502.clkfrm) / ( 1024000 / spkr_sample_rate ) ) * 2">
</PersistentString>
<PersistentString
value = "(int16_t)28000 + (int16_t)-32768">
@ -1665,98 +1722,58 @@
value = "(spkr_clk + m6502.clkfrm)">
</PersistentString>
<PersistentString
value = "( (spkr_clk + m6502.clkfrm) / ( 1024000 / spkr_sample_rate ) ) * 2">
value = "( (spkr_clk + m6502.clkfrm) / ( default_MHz_6502 * 1000 * 1000 / spkr_sample_rate)) * 2">
</PersistentString>
</PersistentStrings>
</ContextState>
<ContextState
contextName = "ViewController.newUpdateTimer(timeInterval:):ViewController.swift">
contextName = "AND:6502_instr_logic.h">
</ContextState>
<ContextState
contextName = "specialized closure #1 in DebuggerViewController.DisplayDisassembly():DebuggerViewController.swift">
<PersistentStrings>
<PersistentString
value = "upd">
value = "line_number">
</PersistentString>
<PersistentString
value = "currentScrollLine">
</PersistentString>
<PersistentString
value = "current_line_number">
</PersistentString>
</PersistentStrings>
</ContextState>
<ContextState
contextName = "_memwrite8_low:mmio.c">
contextName = "ViewController.mouseMoved(with:):ViewController.swift">
<PersistentStrings>
<PersistentString
value = "MEMcfg">
value = "oldLocation">
</PersistentString>
<PersistentString
value = "currentLowWRMEM == Apple2_64K_MEM">
value = "mouseLocation">
</PersistentString>
<PersistentString
value = "WRLOMEM == currentLowWRMEM">
</PersistentString>
<PersistentString
value = "RDLOMEM == WRLOMEM">
</PersistentString>
<PersistentString
value = "m6502.PC">
</PersistentString>
<PersistentString
value = "currentLowWRMEM == Apple2_64K_RAM">
</PersistentString>
<PersistentString
value = "WRLOMEM == Apple2_64K_MEM">
</PersistentString>
<PersistentString
value = "currentLowWRMEM == Apple2_64K_AUX">
</PersistentString>
<PersistentString
value = "WRLOMEM[0x3F6]">
value = "view.bounds">
</PersistentString>
</PersistentStrings>
</ContextState>
<ContextState
contextName = "m6502_Debug:6502.c">
contextName = "closure #1 in ViewController.Update():ViewController.swift">
<PersistentStrings>
<PersistentString
value = "m6502.debugger.SP">
value = "txtArr">
</PersistentString>
<PersistentString
value = "m6502.debugger.mask.ret">
value = "self.shadowTxt">
</PersistentString>
<PersistentString
value = "m6502.SP">
</PersistentString>
</PersistentStrings>
</ContextState>
<ContextState
contextName = "memwrite8_bank2:mmio.h">
<PersistentStrings>
<PersistentString
value = "WRD0MEM">
value = "txt">
</PersistentString>
<PersistentString
value = "WRHIMEM">
</PersistentString>
</PersistentStrings>
</ContextState>
<ContextState
contextName = "woz_write:woz.c">
<PersistentStrings>
<PersistentString
value = "WOZwrite.data">
value = "MEMcfg.is_80STORE">
</PersistentString>
<PersistentString
value = "new">
</PersistentString>
<PersistentString
value = "WOZtmp.shift16">
</PersistentString>
<PersistentString
value = "WOZwrite.shift">
</PersistentString>
<PersistentString
value = "bitOffset">
</PersistentString>
<PersistentString
value = "(1 &lt;&lt; i) - 1">
</PersistentString>
<PersistentString
value = "WOZwrite.shift16">
value = "MEMcfg.txt_page_2">
</PersistentString>
</PersistentStrings>
</ContextState>

View File

@ -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

View File

@ -23,7 +23,7 @@
<key>CFBundleVersion</key>
<string>1</string>
<key>LSApplicationCategoryType</key>
<string>public.app-category.education</string>
<string>public.app-category.arcade-games</string>
<key>LSMinimumSystemVersion</key>
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
<key>NSHumanReadableCopyright</key>

Binary file not shown.

Binary file not shown.

View File

@ -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 );

View File

@ -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 ) {