diff --git a/A2Mac/Base.lproj/Main.storyboard b/A2Mac/Base.lproj/Main.storyboard
index c48a8aa..230fe62 100644
--- a/A2Mac/Base.lproj/Main.storyboard
+++ b/A2Mac/Base.lproj/Main.storyboard
@@ -1182,7 +1182,7 @@
-
+
@@ -1260,7 +1260,7 @@
-
+
@@ -1303,6 +1303,14 @@
+
+
+
+
+
+
+
+
@@ -1312,39 +1320,25 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
+
-
+
+
+
-
@@ -1394,13 +1388,26 @@
-
+
-
+
+
+
+
+
-
+
-
+
-
+
@@ -1485,18 +1492,21 @@
-
+
-
+
+
+
+
-
+
@@ -1507,7 +1517,7 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -1589,6 +1643,14 @@
+
+
+
+
+
+
+
+
@@ -1608,6 +1670,14 @@
+
+
+
+
+
+
+
+
@@ -1662,6 +1732,7 @@
+
@@ -1672,7 +1743,7 @@
-
+
diff --git a/A2Mac/HiRes.swift b/A2Mac/HiRes.swift
index 9816aa7..b5f1edd 100644
--- a/A2Mac/HiRes.swift
+++ b/A2Mac/HiRes.swift
@@ -709,8 +709,13 @@ class HiRes: NSView {
// refresh the entire screen
let boundingBox = CGRect(x: 0, y: 0, width: frame.width, height: frame.height)
- currentContext?.interpolationQuality = .none
-// currentContext?.interpolationQuality = .high // TODO: Make a switch that lets you turn on and off "old monitor effects"
+
+ if ( ViewController.current?.CRTMonitor ?? false ) {
+ currentContext?.interpolationQuality = .high // TODO: Make a switch that lets you turn on and off "old monitor effects"
+ }
+ else {
+ currentContext?.interpolationQuality = .none
+ }
currentContext?.draw(image, in: boundingBox)
}
diff --git a/A2Mac/ViewController.swift b/A2Mac/ViewController.swift
index 93fccc0..7e68a78 100644
--- a/A2Mac/ViewController.swift
+++ b/A2Mac/ViewController.swift
@@ -52,7 +52,9 @@ class ViewController: NSViewController {
@IBOutlet weak var lores: LoRes!
@IBOutlet weak var hires: HiRes!
@IBOutlet weak var splashScreen: NSView!
+ @IBOutlet weak var scanLines: NSImageView!
+ var CRTMonitor = false
var Keyboard2Joystick = true
var Mouse2Joystick = false
var MouseInterface = true
@@ -145,7 +147,7 @@ class ViewController: NSViewController {
@IBAction func Power(_ sender: Any) {
upd.suspend()
- halted = true
+ cpuState = cpuState_inited;
//------------------------------------------------------------
// Animated Splash Screen fade out and (Text) Monitor fade in
@@ -170,7 +172,7 @@ class ViewController: NSViewController {
m6502_ColdReset( Bundle.main.resourcePath, ViewController.romFileName )
- self.halted = false
+ cpuState = cpuState_running;
self.upd.resume()
}
//------------------------------------------------------------
@@ -284,6 +286,11 @@ class ViewController: NSViewController {
}
override func keyDown(with event: NSEvent) {
+
+ if ( cpuMode == cpuMode_eco ) {
+ cpuState = cpuState_running;
+ }
+
// print("keyDown")
// for i in 0...65536 {
@@ -524,8 +531,6 @@ class ViewController: NSViewController {
var clkCounter : Double = 0
let fpsHalf = fps / 2
- var halted = true;
-
var mouseLocation = NSPoint.zero
var shadowTxt : String = ""
@@ -726,35 +731,106 @@ class ViewController: NSViewController {
}
- func Update() {
- clkCounter += Double(clkfrm)
- // we start a new frame from here, so CPU is running even while rendering
- clkfrm = 0
+ func Input() {
+ // Mouse 2 JoyStick (Game Controller / Paddle)
+ mouseLocation = view.window!.mouseLocationOutsideOfEventStream
+
+ if ( Mouse2Joystick ) {
+ pdl_prevarr[0] = pdl_valarr[0]
+ pdl_valarr[0] = Double(mouseLocation.x / (displayField.frame.width) )
+ pdl_diffarr[0] = pdl_valarr[0] - pdl_prevarr[0]
+
+ pdl_prevarr[1] = pdl_valarr[1]
+ pdl_valarr[1] = 1 - Double(mouseLocation.y / (displayField.frame.height) )
+ pdl_diffarr[1] = pdl_valarr[1] - pdl_prevarr[1]
+ }
+
+ if ( MouseInterface ) {
+ pdl_prevarr[2] = pdl_valarr[2]
+ pdl_valarr[2] = Double(mouseLocation.x / (displayField.frame.width) )
+ pdl_diffarr[2] = pdl_valarr[2] - pdl_prevarr[2]
+
+ pdl_prevarr[3] = pdl_valarr[3]
+ pdl_valarr[3] = 1 - Double(mouseLocation.y / (displayField.frame.height) )
+ pdl_diffarr[3] = pdl_valarr[3] - pdl_prevarr[3]
+ }
+ }
- frameCounter += 1
-
- if ( frameCounter % fps == 0 ) {
- let currentTime = CACurrentMediaTime() as Double
- let elpasedTime = currentTime - lastFrameTime
- lastFrameTime = currentTime
- mhz = Double( clkCounter ) / (elpasedTime * M);
- clkCounter = 0
+
+ func Update() {
+ switch cpuState {
+ case cpuState_running:
+ clkCounter += Double(clkfrm)
+ // we start a new frame from here, so CPU is running even while rendering
+ clkfrm = 0
+
+ frameCounter += 1
+
+ if ( frameCounter % fps == 0 ) {
+ let currentTime = CACurrentMediaTime() as Double
+ let elpasedTime = currentTime - lastFrameTime
+ lastFrameTime = currentTime
+ mhz = Double( clkCounter ) / (elpasedTime * M);
+ clkCounter = 0
+ }
+
+ #if SPEEDTEST
+ #else
+
+ // poll input devices like mouse and joystick
+ Input()
+
+ // run some code
+ m6502_Run()
+
+ // video rendering
+// if ( frameCounter % 5 == 0 ) {
+ Render()
+// }
+
+ #endif
+
+ break
+
+ case cpuState_halting:
+ cpuState = cpuState_halted
+
+// clkCounter += Double(clkfrm)
+// // we start a new frame from here, so CPU is running even while rendering
+// clkfrm = 0
+//
+// frameCounter += 1
+//
+// if ( frameCounter % fps == 0 ) {
+// let currentTime = CACurrentMediaTime() as Double
+// let elpasedTime = currentTime - lastFrameTime
+// lastFrameTime = currentTime
+// mhz = Double( clkCounter ) / (elpasedTime * M);
+// clkCounter = 0
+// }
+//
+// #if SPEEDTEST
+// #else
+//
+// // poll input devices like mouse and joystick
+// Input()
+//
+// // run some code
+// m6502_Run()
+//
+ // video rendering
+ // if ( frameCounter % 5 == 0 ) {
+ Render()
+ // }
+
+// #endif
+
+ break
+
+ default:
+ break
}
-
-
-// if ( frameCounter % 5 == 0 ) {
- Render()
-// }
-
-
- #if SPEEDTEST
- #else
- if ( !halted ) {
- m6502_Run()
- }
- #endif
-
-
+
}
@@ -873,6 +949,23 @@ class ViewController: NSViewController {
}
+ @IBAction func setCPUMode(_ sender: NSButton) {
+ switch ( sender.title ) {
+ case "Eco":
+ cpuMode = cpuMode_eco
+ break
+
+ case "Game":
+ cpuMode = cpuMode_game
+ cpuState = cpuState_running
+ break
+
+ default:
+ cpuMode = cpuMode_normal
+ cpuState = cpuState_running
+ break
+ }
+ }
@IBOutlet weak var SoundGap: NSTextFieldCell!
@@ -881,6 +974,11 @@ class ViewController: NSViewController {
spkr_extra_buf = Int32( sender.integerValue )
}
+ @IBAction func CRTMonitorOnOff(_ sender: NSButton) {
+ CRTMonitor = sender.state == .on
+ scanLines.isHidden = !CRTMonitor
+ }
+
@IBAction func Keyboard2JoystickOnOff(_ sender: NSButton) {
Keyboard2Joystick = sender.state == .on
}
diff --git a/src/cpu/6502.c b/src/cpu/6502.c
index f525471..3ee6747 100644
--- a/src/cpu/6502.c
+++ b/src/cpu/6502.c
@@ -28,6 +28,10 @@ void ViewController_spk_up_play(void);
void ViewController_spk_dn_play(void);
+volatile cpuMode_s cpuMode = cpuMode_normal;
+volatile cpuState_s cpuState = cpuState_unknown;
+
+
#include "../util/common.h"
@@ -333,7 +337,7 @@ INLINE int m6502_Step() {
case 0x69: ADC( imm() ); return 2; // ADC imm
case 0x6A: RORA(); return 2; // ROR A
case 0x6B: ARC( imm() ); return 2; // ARR/ARC* imm 2 (undocumented)
- case 0x6C: JMP( ind_addr() ); return 5; // JMP ind
+ case 0x6C: JMP( ind_addr() ); return 5; // JMP ind
case 0x6D: ADC( src_abs() ); return 4; // ADC abs
case 0x6E: ROR( addr_abs() ); return 6; // ROR abs
case 0x6F: RRA( abs_addr() ); return 6; // RRA* abs 6 (undocumented)
@@ -367,7 +371,7 @@ INLINE int m6502_Step() {
case 0x8B: XAA( imm() ); return 2; // XAA* imm 2 (undocumented, highly unstable!)
case 0x8C: STY( addr_abs() ); return 4; // STY abs
case 0x8D: STA( addr_abs() ); return 4; // STA abs
- case 0x8E: STX( addr_abs() ); return 4; // STX abs
+ case 0x8E: STX( addr_abs() ); return 4; // STX abs
case 0x8F: SAX( addr_abs() ); return 4; // SAX* abs 4 (undocumented)
case 0x90: BCC( rel_addr() ); return 3; // BCC rel
case 0x91: STA( addr_ind_Y() ); return 6; // STA ind,Y
diff --git a/src/cpu/6502.h b/src/cpu/6502.h
index 1038459..9abe613 100644
--- a/src/cpu/6502.h
+++ b/src/cpu/6502.h
@@ -13,6 +13,22 @@
#include "common.h"
#include "woz.h"
+typedef enum cpuMode_e {
+ cpuMode_normal = 0,
+ cpuMode_eco,
+ cpuMode_game,
+} cpuMode_s;
+
+typedef enum cpuState_e {
+ cpuState_unknown = 0,
+ cpuState_inited,
+ cpuState_running,
+ cpuState_halting,
+ cpuState_halted,
+} cpuState_s;
+
+extern volatile cpuMode_s cpuMode;
+extern volatile cpuState_s cpuState;
extern const double default_MHz_6502;
extern const double iigs_MHz_6502;
diff --git a/src/dev/disk/woz.c b/src/dev/disk/woz.c
index 429464f..b039b10 100644
--- a/src/dev/disk/woz.c
+++ b/src/dev/disk/woz.c
@@ -91,17 +91,10 @@ typedef enum wozTrackState_e {
} wozTrackState_t;
-void woz_loadTrack( int track ) {
- trackEntry_t reg = {0};
- wozTrackState_t wozTrackState = wozTrackState_Start;
-
- reg.shift = 0;
- reg.data = 0;
- prepared_track[0] = reg;
-
- int vol = 0;
- int trk = 0;
- int sec = 0;
+int bitOffs_D5_SecHdr = 0;
+int vol = 0;
+int trk = 0;
+int sec = 0;
int bitOffs_D5_SecHdr = 0; // bit offset of D5 Sector Header
@@ -115,78 +108,78 @@ void woz_loadTrack( int track ) {
reg.shift16 <<= 1;
if (reg.shift & 0x80) {
- switch (wozTrackState) {
- case wozTrackState_D5:
+ switch (wozTrackState) {
+ case wozTrackState_D5:
switch (reg.shift) {
- case 0xAA:
-// printf("D5 AA at bitOffset:%d\n", bitOffs);
- wozTrackState = wozTrackState_D5_AA;
- break;
-
- default:
- wozTrackState = wozTrackState_Start;
- break;
- }
-
- break;
-
- case wozTrackState_D5_AA:
+ case 0xAA:
+// printf("D5 AA at bitOffset:%d\n", bitOffs);
+ wozTrackState = wozTrackState_D5_AA;
+ break;
+
+ default:
+ wozTrackState = wozTrackState_Start;
+ break;
+ }
+
+ break;
+
+ case wozTrackState_D5_AA:
switch (reg.shift) {
- case 0x96:
- wozTrackState = wozTrackState_vol1;
-// printf("D5 AA 96 at bitOffset:%d\n", bitOffs);
-// printf("Sector Header at bitOffset:%d\n", bitOffs_D5_SecHdr);
- break;
-
- default:
- wozTrackState = wozTrackState_Start;
- break;
- }
-
- break;
-
- case wozTrackState_vol1:
+ case 0x96:
+ wozTrackState = wozTrackState_vol1;
+// printf("D5 AA 96 at bitOffset:%d\n", bitOffs);
+// printf("Sector Header at bitOffset:%d\n", bitOffs_D5_SecHdr);
+ break;
+
+ default:
+ wozTrackState = wozTrackState_Start;
+ break;
+ }
+
+ break;
+
+ case wozTrackState_vol1:
vol = (reg.shift << 1) | 1;
- wozTrackState = wozTrackState_vol2;
- break;
-
- case wozTrackState_vol2:
+ wozTrackState = wozTrackState_vol2;
+ break;
+
+ case wozTrackState_vol2:
vol &= reg.shift;
- wozTrackState = wozTrackState_trk1;
- break;
-
- case wozTrackState_trk1:
+ wozTrackState = wozTrackState_trk1;
+ break;
+
+ case wozTrackState_trk1:
trk = (reg.shift << 1) | 1;
- wozTrackState = wozTrackState_trk2;
- break;
-
- case wozTrackState_trk2:
+ wozTrackState = wozTrackState_trk2;
+ break;
+
+ case wozTrackState_trk2:
trk &= reg.shift;
- wozTrackState = wozTrackState_sec1;
- break;
-
- case wozTrackState_sec1:
+ wozTrackState = wozTrackState_sec1;
+ break;
+
+ case wozTrackState_sec1:
sec = (reg.shift << 1) | 1;
- wozTrackState = wozTrackState_sec2;
- break;
-
- case wozTrackState_sec2:
+ wozTrackState = wozTrackState_sec2;
+ break;
+
+ case wozTrackState_sec2:
sec &= reg.shift;
wozTrackState = wozTrackState_Start;
-
+
printf("Vol:%d Track:%d Sector:%d at bitOffset:%d\n", vol, trk, sec, bitOffs_D5_SecHdr);
-
- break;
-
- default:
+
+ break;
+
+ default:
if ( reg.shift == 0xD5 ) {
-// printf("D5 at bitOffset:%d\n", bitOffs);
- wozTrackState = wozTrackState_D5;
- bitOffs_D5_SecHdr = bitOffs;
- }
- break;
- }
-
+// printf("D5 at bitOffset:%d\n", bitOffs);
+ wozTrackState = wozTrackState_D5;
+ bitOffs_D5_SecHdr = bitOffs;
+ }
+ break;
+ }
+
reg.shift = 0;
}
@@ -257,10 +250,11 @@ uint8_t woz_read() {
trackOffset++;
trackOffset %= usedBytes;
- WOZread.data = woz_trks[track].data[trackOffset];
+ WOZwrite.data = WOZread.data = woz_trks[track].data[trackOffset];
}
WOZread.shift16 <<= 1;
+ WOZwrite.shift16 <<= 1;
if ( WOZread.valid ) {
WOZread.shift = 0;
@@ -271,22 +265,29 @@ uint8_t woz_read() {
// to avoid infinite loop and to search for bit 7 high
for ( int i = 0; i < usedBytes * 8; i++ ) {
if ( WOZread.valid ) {
- uint8_t byte = WOZread.shift;
WOZread.shift = 0;
// if (outdev) fprintf(outdev, "byte: %02X\n", byte);
+
+ if ( woz_decodeTrkSec(WOZwrite.shift, clkelpased, trackOffset * 8 + bitOffset) == wozTrackState_END ) {
+ if (disk_sfx_enabled) printf("vol:%d trk:%d sec:%d\n", vol, trk, sec);
+ }
- return byte;
+ if (disk_sfx_enabled) printf("elpased:%lld read: %02X\n", clkelpased, WOZwrite.shift);
+
+ return WOZwrite.shift;
}
if ( ++bitOffset >= 8 ) {
bitOffset = 0;
+ trackWRoffset = trackOffset;
trackOffset++;
trackOffset %= usedBytes;
- WOZread.data = woz_trks[track].data[trackOffset];
+ WOZwrite.data = WOZread.data = woz_trks[track].data[trackOffset];
}
WOZread.shift16 <<= 1;
+ WOZwrite.shift16 <<= 1;
}
// if (outdev) fprintf(outdev, "TIME OUT!\n");
}
@@ -295,6 +296,97 @@ uint8_t woz_read() {
}
+void woz_write( uint8_t data ) {
+
+ 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");
+ return;
+ }
+
+ static int clkBeforeSync = 0;
+
+ clkelpased = m6502.clktime + clkfrm - m6502.clklast;
+ m6502.clklast = m6502.clktime + clkfrm;
+
+ clkBeforeSync += clkelpased;
+
+ uint16_t usedBytes = woz_trks[track].bytes_used < WOZ_TRACK_BYTE_COUNT ? woz_trks[track].bytes_used : WOZ_TRACK_BYTE_COUNT;
+
+ if ( usedBytes ) {
+ if ( disk_sfx_enabled ) printf("elpased:%llu data:$%02X\n", clkelpased, data);
+
+ if ( clkelpased > 40 ) {
+ if ( disk_sfx_enabled ) printf("I/O ERROR : %llu (clkBefRd:%d)\n", clkelpased, clkBeforeSync);
+ }
+
+
+ // sync data?
+ if ( WOZwrite.shift == 0xFF ) {
+ // yes, we have to push in extra 2 zeros
+ for ( int i = 0; i < 2; i++ ) {
+ WOZread.shift16 <<= 1;
+ WOZwrite.shift16 <<= 1;
+
+ if ( ++bitOffset >= 8 ) {
+ bitOffset = 0;
+ trackWRoffset = trackOffset;
+ trackOffset++;
+ trackOffset %= usedBytes;
+ }
+ }
+ }
+
+
+ // now we can latch data
+// uint8_t latch = data;
+ WOZwrite.data = WOZread.data = data;
+
+ // shift in 8 bits of data and write it out
+ for ( int i = 0; i < 8; i++ ) {
+ if ( ++bitOffset >= 8 ) {
+ // write out first part
+ woz_trks[track].data[trackWRoffset] = WOZwrite.shift;
+
+ bitOffset = 0;
+ trackWRoffset = trackOffset;
+ trackOffset++;
+ 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];
+ new &= (1 << i) - 1;
+ WOZread.data |= new;
+ WOZwrite.data |= new;
+
+ break;
+ }
+
+ WOZread.shift16 <<= 1;
+ WOZwrite.shift16 <<= 1;
+ };
+
+ // write the remaining bits without altering WOZ track offsets and indexes
+ WOZread_t WOZtmp = WOZwrite;
+ int bo = bitOffset;
+
+ // second half
+ for ( int i = 8; i; i-- ) {
+ if ( ++bo >= 8 ) {
+ // write out first part
+ woz_trks[track].data[trackWRoffset] = WOZtmp.shift;
+ break;
+ }
+
+ WOZtmp.shift16 <<= 1;
+ };
+
+ }
+
+}
+
+
int woz_loadFile( const char * filename ) {
// char fullpath[256];
diff --git a/src/dev/mem/mmio.h b/src/dev/mem/mmio.h
index fd3a23d..91f1975 100644
--- a/src/dev/mem/mmio.h
+++ b/src/dev/mem/mmio.h
@@ -50,6 +50,9 @@ uint8_t * WRD0MEM = Apple2_Dummy_RAM; // for writing $D000 - $DFFF
uint8_t * WRHIMEM = Apple2_Dummy_RAM; // for writing $E000 - $FFFF
+static uint8_t writeState = 0; // 1 if $C08D was written
+
+
MEMcfg_t MEMcfg = { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
MEMcfg_t newMEMcfg = { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
@@ -545,25 +548,44 @@ INLINE void io_RAM_EXP( uint16_t addr ) {
}
+static unsigned int lastIO = 0;
+
INLINE uint8_t ioRead( uint16_t addr ) {
// if (outdev) fprintf(outdev, "ioRead:%04X\n", addr);
// printf("ioRead:%04X (PC:%04X)\n", addr, m6502.PC);
+
+ unsigned int IOframe = clkfrm - lastIO;
+ lastIO = clkfrm;
- // TODO: This is for checking only, should be either removed or the entire ioRead should based on binary search, whatever is faster
+ // TODO: This is for speed demo only, should be either removed or the entire ioRead should based on binary search, whatever is faster
if ( addr == io_KBD ) {
// clk_6502_per_frm_max = clk_6502_per_frm_max > 32768 ? clk_6502_per_frm_max - 32768 : 0; // ECO Mode!
+
+ if ( cpuMode == cpuMode_eco ) {
+ // check if this is a busy keyboard poll (aka waiting for user input)
+ if ( IOframe < 16 ) {
+ clk_6502_per_frm_max = 6502; // Absolute low mode
+ cpuState = cpuState_halting;
+ }
+ }
+
return Apple2_64K_RAM[io_KBD];
}
switch ( (uint8_t)addr ) {
case (uint8_t)io_KBD:
-// if ( RAM[io_KBD] > 0x7F ) printf("io_KBD:%04X\n", addr);
+
return Apple2_64K_RAM[io_KBD];
case (uint8_t)io_KBDSTRB:
- // TODO: This is very slow!
-// printf("io_KBDSTRB\n");
Apple2_64K_RAM[io_KBD] &= ~(1 << 7);
+
+ if ( cpuMode == cpuMode_eco ) {
+ // check if this is a busy keyboard poll (aka waiting for user input)
+ clk_6502_per_frm_max = clk_6502_per_frm; // Absolute low mode
+ cpuState = cpuState_running;
+ }
+
return Apple2_64K_RAM[io_KBDSTRB];
case (uint8_t)io_SPKR:
@@ -737,12 +759,20 @@ INLINE uint8_t ioRead( uint16_t addr ) {
return 0;
case (uint8_t)io_DISK_READ + SLOT6:
- return disk_read();
-
+ if ( writeState ) {
+ writeState = 0;
+ woz_write( Apple2_64K_RAM[io_DISK_WRITE + SLOT6] );
+ return Apple2_64K_RAM[io_DISK_WRITE + SLOT6];
+ }
+ else {
+ return disk_read();
+ }
+
case (uint8_t)io_DISK_WRITE + SLOT6:
dbgPrintf2("io_DISK_WRITE (S%u)\n", 6);
- Apple2_64K_RAM[io_DISK_CLEAR + SLOT6] |= 1 << 7; // mark disk as write protected
+// Apple2_64K_RAM[io_DISK_CLEAR + SLOT6] |= 1 << 7; // mark disk as write protected
+ Apple2_64K_RAM[io_DISK_CLEAR + SLOT6] &= ~(1 << 7); // mark disk as write enabled
return Apple2_64K_RAM[io_DISK_WRITE + SLOT6];
case (uint8_t)io_DISK_CLEAR + SLOT6:
@@ -961,6 +991,60 @@ INLINE void ioWrite( uint16_t addr, uint8_t val ) {
io_RAM_EXP(addr);
break;
+ // TODO: Make code "card insertable to slot" / aka slot independent and dynamically add/remove
+ case (uint8_t)io_DISK_PHASE0_OFF + SLOT6:
+ case (uint8_t)io_DISK_PHASE1_OFF + SLOT6:
+ case (uint8_t)io_DISK_PHASE2_OFF + SLOT6:
+ case (uint8_t)io_DISK_PHASE3_OFF + SLOT6:
+ disk_phase_off( (addr - io_DISK_PHASE0_OFF - SLOT6) / 2 );
+ break;
+
+ case (uint8_t)io_DISK_PHASE0_ON + SLOT6:
+ case (uint8_t)io_DISK_PHASE1_ON + SLOT6:
+ case (uint8_t)io_DISK_PHASE2_ON + SLOT6:
+ case (uint8_t)io_DISK_PHASE3_ON + SLOT6:
+ disk_phase_on( (addr - io_DISK_PHASE0_ON - SLOT6) / 2 );
+ break;
+
+ case (uint8_t)io_DISK_POWER_OFF + SLOT6:
+ dbgPrintf2("io_DISK_POWER_OFF (S%u)\n", 6);
+ disk_motor_off();
+ break;
+
+ case (uint8_t)io_DISK_POWER_ON + SLOT6:
+ dbgPrintf2("io_DISK_POWER_ON (S%u)\n", 6);
+ disk_motor_on();
+ break;
+
+ case (uint8_t)io_DISK_SELECT_1 + SLOT6:
+ dbgPrintf2("io_DISK_SELECT_1 (S%u)\n", 6);
+ break;
+
+ case (uint8_t)io_DISK_SELECT_2 + SLOT6:
+ dbgPrintf2("io_DISK_SELECT_2 (S%u)\n", 6);
+ break;
+
+ case (uint8_t)io_DISK_READ + SLOT6:
+ Apple2_64K_RAM[io_DISK_READ + SLOT6] = val;
+ woz_write( Apple2_64K_RAM[io_DISK_WRITE + SLOT6] );
+ writeState = 0;
+ break;
+
+ case (uint8_t)io_DISK_WRITE + SLOT6:
+ dbgPrintf2("io_DISK_WRITE (S%u)\n", 6);
+ Apple2_64K_RAM[io_DISK_WRITE + SLOT6] = val;
+ writeState = 1;
+ break;
+
+ case (uint8_t)io_DISK_CLEAR + SLOT6:
+ dbgPrintf2("io_DISK_CLEAR (S%u)\n", 6);
+ break;
+
+ case (uint8_t)io_DISK_SHIFT + SLOT6:
+ dbgPrintf2("io_DISK_SHIFT (S%u)\n", 6);
+ break;
+
+
default:
break;
}