Huge Speaker Improvements + Memory Handling is Lot Better + 6502 standard and undocumented instruction separation

This commit is contained in:
tudnai 2022-04-09 00:31:35 -07:00
parent 7a6b8c1f38
commit bfd590b722
10 changed files with 702 additions and 420 deletions

View File

@ -1703,17 +1703,17 @@
</textFieldCell>
</textField>
<scrollView hidden="YES" horizontalCompressionResistancePriority="250" verticalCompressionResistancePriority="250" borderType="none" horizontalLineScroll="0.0" horizontalPageScroll="0.0" verticalLineScroll="0.0" verticalPageScroll="0.0" hasHorizontalScroller="NO" hasVerticalScroller="NO" minMagnification="1" translatesAutoresizingMaskIntoConstraints="NO" id="ss1-M1-nGn" userLabel="Scroll View - Display View" customClass="DisplayScrollView" customModule="Steve___" customModuleProvider="target">
<rect key="frame" x="11" y="16" width="1131" height="768"/>
<rect key="frame" x="0.0" y="16" width="1152" height="768"/>
<clipView key="contentView" drawsBackground="NO" copiesOnScroll="NO" id="1wa-ZE-lex">
<rect key="frame" x="0.0" y="0.0" width="1131" height="768"/>
<rect key="frame" x="0.0" y="0.0" width="1152" height="768"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textView editable="NO" selectable="NO" drawsBackground="NO" importsGraphics="NO" richText="NO" horizontallyResizable="YES" verticallyResizable="YES" baseWritingDirection="leftToRight" findStyle="bar" allowsCharacterPickerTouchBarItem="NO" textCompletion="NO" id="ccC-Wu-3za" userLabel="Display" customClass="DisplayView" customModule="Steve___" customModuleProvider="target">
<rect key="frame" x="0.0" y="267" width="1131" height="768"/>
<rect key="frame" x="0.0" y="267" width="1152" height="768"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
<size key="minSize" width="1131" height="768"/>
<color key="backgroundColor" red="0.0" green="0.99143940210000003" blue="1" alpha="0.76658818490000002" colorSpace="custom" customColorSpace="sRGB"/>
<size key="minSize" width="1152" height="768"/>
<size key="maxSize" width="3840" height="58101"/>
<attributedString key="textStorage">
<fragment>
@ -1743,21 +1743,21 @@
</scroller>
</scrollView>
<customView hidden="YES" focusRingType="none" horizontalCompressionResistancePriority="250" verticalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="Gqh-qw-fjy" userLabel="LoRes" customClass="LoRes" customModule="Steve___" customModuleProvider="target">
<rect key="frame" x="16" y="16" width="1121" height="768"/>
<rect key="frame" x="5" y="16" width="1142" height="768"/>
</customView>
<customView hidden="YES" focusRingType="none" horizontalCompressionResistancePriority="250" verticalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="LlM-EV-ruZ" userLabel="HiRes" customClass="HiRes" customModule="Steve___" customModuleProvider="target">
<rect key="frame" x="16" y="16" width="1121" height="768"/>
<rect key="frame" x="0.0" y="16" width="1152" height="768"/>
</customView>
<imageView hidden="YES" focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="251" horizontalCompressionResistancePriority="250" verticalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="dGn-a4-c1t" userLabel="ScanLines">
<rect key="frame" x="16" y="16" width="1121" height="768"/>
<rect key="frame" x="0.0" y="16" width="1152" height="768"/>
<imageCell key="cell" refusesFirstResponder="YES" focusRingType="none" alignment="left" imageScaling="axesIndependently" image="scanlines" id="jJ6-qt-oZe"/>
</imageView>
<imageView hidden="YES" focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="251" horizontalCompressionResistancePriority="250" verticalCompressionResistancePriority="250" alphaValue="0.0" translatesAutoresizingMaskIntoConstraints="NO" id="Ghs-c1-ZkA" userLabel="DotmatrixEffect">
<rect key="frame" x="16" y="16" width="1121" height="768"/>
<rect key="frame" x="5" y="16" width="1142" height="768"/>
<imageCell key="cell" refusesFirstResponder="YES" focusRingType="none" alignment="left" imageScaling="axesIndependently" image="dotmatrix_effect" id="nPr-Un-zjz"/>
</imageView>
<customView focusRingType="none" horizontalCompressionResistancePriority="250" verticalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="D0w-YC-YlJ" userLabel="Splash Screen">
<rect key="frame" x="16" y="16" width="1121" height="768"/>
<rect key="frame" x="5" y="16" width="1142" height="768"/>
<subviews>
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="9jr-eX-yOC">
<rect key="frame" x="14" y="711" width="291" height="41"/>
@ -1800,7 +1800,7 @@
</textFieldCell>
</textField>
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="bUo-E1-CYC">
<rect key="frame" x="809" y="16" width="298" height="13"/>
<rect key="frame" x="830" y="16" width="298" height="13"/>
<textFieldCell key="cell" lineBreakMode="clipping" refusesFirstResponder="YES" focusRingType="none" title="© by Tamas Rudnai, 2019-2022" id="tm6-Cq-r7H">
<font key="font" size="12" name="PrintChar21"/>
<color key="textColor" red="0.18823529411764706" green="0.83529411764705885" blue="0.84705882352941175" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
@ -1808,7 +1808,7 @@
</textFieldCell>
</textField>
<imageView focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="251" horizontalCompressionResistancePriority="250" verticalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="M1E-lz-4q8" userLabel="Splash Logo">
<rect key="frame" x="413" y="199" width="384" height="308"/>
<rect key="frame" x="425" y="199" width="384" height="308"/>
<imageCell key="cell" scrollable="YES" lineBreakMode="clipping" refusesFirstResponder="YES" focusRingType="none" alignment="left" imageScaling="proportionallyUpOrDown" image="imageCell:Zax-kI-rxd:image" id="Zax-kI-rxd"/>
</imageView>
</subviews>
@ -2109,7 +2109,7 @@
<constraint firstItem="D0w-YC-YlJ" firstAttribute="trailing" secondItem="ss1-M1-nGn" secondAttribute="trailing" constant="-5" id="5wF-ul-W4h"/>
<constraint firstItem="D0w-YC-YlJ" firstAttribute="top" secondItem="ss1-M1-nGn" secondAttribute="top" id="8bz-WZ-Szj"/>
<constraint firstItem="dGn-a4-c1t" firstAttribute="top" secondItem="ss1-M1-nGn" secondAttribute="top" id="8g8-nm-CxE"/>
<constraint firstItem="ss1-M1-nGn" firstAttribute="trailing" secondItem="iIF-Q5-Onc" secondAttribute="trailing" constant="-10" identifier="Display Margin Trailing" id="AYX-tI-fE9"/>
<constraint firstItem="ss1-M1-nGn" firstAttribute="trailing" secondItem="iIF-Q5-Onc" secondAttribute="trailing" identifier="Display Margin Trailing" id="AYX-tI-fE9"/>
<constraint firstItem="Ghs-c1-ZkA" firstAttribute="bottom" secondItem="ss1-M1-nGn" secondAttribute="bottom" id="DgS-2W-eVa"/>
<constraint firstItem="dGn-a4-c1t" firstAttribute="bottom" secondItem="ss1-M1-nGn" secondAttribute="bottom" id="EBM-Pm-MJ8"/>
<constraint firstItem="Gqh-qw-fjy" firstAttribute="top" secondItem="ss1-M1-nGn" secondAttribute="top" id="FF5-Ke-cOk"/>
@ -2119,23 +2119,23 @@
<constraint firstItem="iIF-Q5-Onc" firstAttribute="leading" secondItem="m2S-Jp-Qdl" secondAttribute="leading" identifier="Display Background Leading" id="LGA-tZ-gFh"/>
<constraint firstItem="Gqh-qw-fjy" firstAttribute="trailing" secondItem="ss1-M1-nGn" secondAttribute="trailing" constant="-5" id="Mbh-RX-74d"/>
<constraint firstItem="Gqh-qw-fjy" firstAttribute="bottom" secondItem="ss1-M1-nGn" secondAttribute="bottom" id="NJ1-qp-iku"/>
<constraint firstItem="ss1-M1-nGn" firstAttribute="leading" secondItem="iIF-Q5-Onc" secondAttribute="leading" constant="11" identifier="Display Margin Leading" id="QGx-a9-RR9"/>
<constraint firstItem="ss1-M1-nGn" firstAttribute="leading" secondItem="iIF-Q5-Onc" secondAttribute="leading" identifier="Display Margin Leading" id="QGx-a9-RR9"/>
<constraint firstItem="D0w-YC-YlJ" firstAttribute="leading" secondItem="ss1-M1-nGn" secondAttribute="leading" constant="5" id="SVU-d6-DH1"/>
<constraint firstItem="Fdf-pv-iEw" firstAttribute="top" secondItem="m2S-Jp-Qdl" secondAttribute="top" constant="8" id="Umg-3A-zmv"/>
<constraint firstItem="Gqh-qw-fjy" firstAttribute="leading" secondItem="ss1-M1-nGn" secondAttribute="leading" constant="5" id="VcW-Wh-wiF"/>
<constraint firstItem="ss1-M1-nGn" firstAttribute="top" secondItem="iIF-Q5-Onc" secondAttribute="top" constant="16" identifier="Display Margin Top" id="VdT-jM-SRU"/>
<constraint firstItem="dGn-a4-c1t" firstAttribute="trailing" secondItem="ss1-M1-nGn" secondAttribute="trailing" constant="-5" id="XM9-i5-GOP"/>
<constraint firstItem="dGn-a4-c1t" firstAttribute="trailing" secondItem="ss1-M1-nGn" secondAttribute="trailing" id="XM9-i5-GOP"/>
<constraint firstItem="Fdf-pv-iEw" firstAttribute="leading" secondItem="iIF-Q5-Onc" secondAttribute="trailing" constant="8" id="Xbh-Ub-1Ng"/>
<constraint firstAttribute="bottom" secondItem="iIF-Q5-Onc" secondAttribute="bottom" identifier="Display Background Bottom" id="acb-Dy-fu5"/>
<constraint firstAttribute="trailing" secondItem="iIF-Q5-Onc" secondAttribute="trailing" constant="136" identifier="Display Background Trailing" id="dO5-Md-6fz"/>
<constraint firstItem="LlM-EV-ruZ" firstAttribute="top" secondItem="ss1-M1-nGn" secondAttribute="top" id="lDs-jy-edU"/>
<constraint firstItem="LlM-EV-ruZ" firstAttribute="bottom" secondItem="ss1-M1-nGn" secondAttribute="bottom" id="ltj-Ea-Vtb"/>
<constraint firstItem="iIF-Q5-Onc" firstAttribute="top" secondItem="m2S-Jp-Qdl" secondAttribute="top" identifier="Display Background Top" id="m3e-ww-N7S"/>
<constraint firstItem="LlM-EV-ruZ" firstAttribute="trailing" secondItem="ss1-M1-nGn" secondAttribute="trailing" constant="-5" id="nAy-xD-Y3s"/>
<constraint firstItem="LlM-EV-ruZ" firstAttribute="trailing" secondItem="ss1-M1-nGn" secondAttribute="trailing" id="nAy-xD-Y3s"/>
<constraint firstItem="D0w-YC-YlJ" firstAttribute="bottom" secondItem="ss1-M1-nGn" secondAttribute="bottom" id="qTc-wn-Sqn"/>
<constraint firstItem="dGn-a4-c1t" firstAttribute="leading" secondItem="ss1-M1-nGn" secondAttribute="leading" constant="5" id="xqX-cb-8Hz"/>
<constraint firstItem="dGn-a4-c1t" firstAttribute="leading" secondItem="ss1-M1-nGn" secondAttribute="leading" id="xqX-cb-8Hz"/>
<constraint firstAttribute="trailing" secondItem="Fdf-pv-iEw" secondAttribute="trailing" constant="8" id="yy6-NU-JJX"/>
<constraint firstItem="LlM-EV-ruZ" firstAttribute="leading" secondItem="ss1-M1-nGn" secondAttribute="leading" constant="5" id="zkY-0O-xcA"/>
<constraint firstItem="LlM-EV-ruZ" firstAttribute="leading" secondItem="ss1-M1-nGn" secondAttribute="leading" id="zkY-0O-xcA"/>
</constraints>
<connections>
<outlet property="clipView" destination="1wa-ZE-lex" id="MHH-OC-OYI"/>

View File

@ -37,7 +37,7 @@ class MonitorView: NSView {
var textDisplay_height_diff : CGFloat?
let monitorView_textViewBounds = NSSize(width: 1120, height: 768)
let textDisplay_frameSize = NSSize(width: 1120 + overscan_h, height: 768 + overscan_v)
static let textDisplay_frameSize = NSSize(width: 1120 + overscan_h, height: 768 + overscan_v)
override func viewDidMoveToWindow() {
print("Added to NEW window")
@ -47,12 +47,13 @@ class MonitorView: NSView {
var textFrameSize = frame.size
if textDisplay_width_diff == nil {
textDisplay_width_diff = textFrameSize.width - textDisplay_frameSize.width
textDisplay_height_diff = textFrameSize.height - textDisplay_frameSize.height
textDisplay_width_diff = textFrameSize.width - MonitorView.textDisplay_frameSize.width
textDisplay_height_diff = textFrameSize.height - MonitorView.textDisplay_frameSize.height
}
textFrameSize.width -= textDisplay_width_diff!
// textFrameSize.width -= textDisplay_width_diff!
// textFrameSize.height -= textDisplay_height_diff!
textFrameSize.width = scanlinesView.frame.size.width
textFrameSize.height = scanlinesView.frame.size.height
// print( String(

View File

@ -0,0 +1,113 @@
//
// main.c
// 6502
//
// Created by Tamas Rudnai on 7/14/19.
// Copyright © 2019, 2020 Tamas Rudnai. All rights reserved.
//
// This file is part of Steve ][ -- The Apple ][ Emulator.
//
// Steve ][ is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Steve ][ is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Steve ][. If not, see <https://www.gnu.org/licenses/>.
//
#ifndef __6502_INSTR_CALL_RET_JUMP_H__
#define __6502_INSTR_CALL_RET_JUMP_H__
/**
JMP Jump to New Location
(PC+1) -> PCL N Z C I D V
(PC+2) -> PCH - - - - - -
addressing assembler opc bytes cyles
--------------------------------------------
absolute JMP oper 4C 3 3
indirect JMP (oper) 6C 3 5
**/
INLINE void JMP( uint16_t addr ) {
dbgPrintf("JMP %04X ", addr);
disPrintf(disassembly.inst, "JMP");
// disPrintf(disassembly.comment, "to:%04X", addr)
#ifdef DEBUG
if ( addr == m6502.PC - 3 ) {
dbgPrintf("Infinite Loop at %04X!\n", m6502.PC);
}
#endif
if (m6502.PC >> 8 != addr >> 8) {
m6502.clkfrm += 1;
}
m6502.PC = addr;
}
/**
JSR Jump to New Location Saving Return Address
push (PC+2), N Z C I D V
(PC+1) -> PCL - - - - - -
(PC+2) -> PCH
addressing assembler opc bytes cyles
--------------------------------------------
absolute JSR oper 20 3 6
**/
INLINE void JSR( uint16_t addr ) {
dbgPrintf("JSR ");
disPrintf(disassembly.inst, "JSR");
PUSH_addr(m6502.PC -1);
m6502.PC = addr;
}
/**
RTS Return from Subroutine
pull PC, PC+1 -> PC N Z C I D V
- - - - - -
addressing assembler opc bytes cyles
--------------------------------------------
implied RTS 60 1 6
**/
INLINE void RTS() {
dbgPrintf("RTS ");
disPrintf(disassembly.inst, "RTS");
m6502.PC = POP_addr() +1;
// disk accelerator would only work for a certain amount of time
// currently it is 200ms simulated times
// if ( m6502.clktime - disk.clk_last_access > clk_diskAcceleratorTimeout ) {
// clk_6502_per_frm = clk_6502_per_frm_set;
// }
}
/**
RTI Return from Interrupt
pull SR, pull PC N Z C I D V
from stack
addressing assembler opc bytes cyles
--------------------------------------------
implied RTI 40 1 6
**/
INLINE void RTI() {
dbgPrintf("RTI ");
disPrintf(disassembly.inst, "RTI");
setFlags( POP() );
// m6502.I = 0;
m6502.PC = POP_addr();
}
#endif // __6502_INSTR_CALL_RET_JUMP_H__

View File

@ -256,262 +256,266 @@ INLINE int m6502_Step() {
disNewInstruction();
switch ( fetch() ) {
case 0x00: BRK(); return 7; // BRK
case 0x01: ORA( src_X_ind() ); return 6; // ORA X,ind
case 0x02: HLT(); return 0; // JAM / KIL / HLT* - Halts / Hangs / Jams / Kills the CPU (undocumented)
case 0x03: SLO( addr_zp_X() ); return 8; // SLO* zpg,X (undocumented)
case 0x04: NOP(); src_zp(); return 3; // NOP* zpg (undocumented)
case 0x05: ORA( src_zp() ); return 3; // ORA zpg
case 0x06: ASL( addr_zp() ); return 5; // ASL zpg
case 0x07: SLO( addr_zp() ); return 5; // SLO* zpg (undocumented)
case 0x08: PHP(); return 3; // PHP
case 0x09: ORA( imm() ); return 2; // ORA imm
case 0x0A: ASLA(); return 2; // ASL A
case 0x0B: ANC( imm() ); return 2; // ANC** imm (undocumented)
case 0x0C: NOP(); src_abs(); return 4; // NOP* (undocumented)
case 0x0D: ORA( src_abs() ); return 4; // ORA abs
case 0x0E: ASL( addr_abs() ); return 6; // ASL abs
case 0x0F: SLO( addr_abs() ); return 6; // SLO* (undocumented)
case 0x10: BPL( rel_addr() ); return 2; // BPL rel
case 0x11: ORA( src_ind_Y() ); return 5; // ORA ind,Y
case 0x12: HLT(); return 0; // JAM / KIL / HLT* - Halts / Hangs / Jams / Kills the CPU (undocumented)
case 0x13: SLO( addr_zp_Y() ); return 8; // SLO* zpg,Y (undocumented)
case 0x14: NOP(); addr_zp_X(); return 4; // NOP* zpg,X (undocumented)
case 0x15: ORA( src_zp_X() ); return 4; // ORA zpg,X
case 0x16: ASL( addr_zp_X() ); return 6; // ASL zpg,X
case 0x17: SLO( addr_zp_X() ); return 6; // SLO* zpg,X (undocumented)
case 0x18: CLC(); return 2; // CLC
case 0x19: ORA( src_abs_Y() ); return 4+1; // ORA abs,Y
case 0x1A: NOP(); return 2; // NOP* (undocumented)
case 0x1B: SLO( addr_abs_Y() ); return 7; // SLO* abs,Y (undocumented)
case 0x1C: NOP(); src_abs_X(); return 4; // NOP* (undocumented)
case 0x1D: ORA( src_abs_X() ); return 4+1; // ORA abs,X
case 0x1E: ASL( addr_abs_X() ); return 7; // ASL abs,X
case 0x1F: SLO( addr_abs_X() ); return 7; // SLO* abs,X (undocumented)
case 0x20: JSR( abs_addr() ); return 6; // JSR abs
case 0x21: AND( src_X_ind() ); return 6; // AND X,ind
case 0x22: HLT(); return 0; // JAM / KIL / HLT* - Halts / Hangs / Jams / Kills the CPU (undocumented)
case 0x23: RLA( addr_ind_X() ); return 8; // RLA* ind,X 8 (undocumented)
case 0x24: BIT( src_zp() ); return 3; // BIT zpg
case 0x25: AND( src_zp() ); return 3; // AND zpg
case 0x26: ROL( addr_zp() ); return 5; // ROL zpg
case 0x27: RLA( addr_zp() ); return 5; // RLA* zpg 5 (undocumented)
case 0x28: PLP(); return 4; // PLP
case 0x29: AND( imm() ); return 2; // AND imm
case 0x2A: ROLA(); return 2; // ROL A
case 0x2B: ANC( imm() ); return 2; // ANC* imm 2 (undocumented)
case 0x2C: BIT( src_abs() ); return 4; // BIT abs
case 0x2D: AND( src_abs() ); return 4; // AND abs
case 0x2E: ROL( addr_abs() ); return 6; // ROL abs
case 0x2F: RLA( addr_abs() ); return 6; // RLA* abs 6 (undocumented)
case 0x30: BMI( rel_addr() ); return 2; // BMI rel
case 0x31: AND( src_ind_Y() ); return 5; // AND ind,Y
case 0x32: HLT(); return 0; // JAM / KIL / HLT* - Halts / Hangs / Jams / Kills the CPU (undocumented)
case 0x33: RLA( addr_ind_Y() ); return 8; // RLA* izy 8 (undocumented)
case 0x34: NOP(); src_zp_X(); return 4; // NOP* zpx 4 (undocumented)
case 0x35: AND( src_zp_X() ); return 4; // AND zpg,X
case 0x36: ROL( addr_zp_X() ); return 6; // ROL zpg,X
case 0x37: RLA( addr_zp_X() ); return 6; // RLA* zpx 6 (undocumented)
case 0x38: SEC(); return 2; // SEC
case 0x39: AND( src_abs_Y() ); return 4+1; // AND abs,Y
case 0x3A: NOP(); return 2; // NOP* 2 (undocumented)
case 0x3B: RLA( addr_abs_Y() ); return 7; // RLA* aby 7 (undocumented)
case 0x3C: NOP(); src_abs_X(); return 4; // NOP* abx 4 (undocumented)
case 0x3D: AND( src_abs_X() ); return 4+1; // AND abs,X
case 0x3E: ROL( addr_abs_X() ); return 7; // ROL abs,X
case 0x3F: RLA( addr_abs_X() ); return 7; // RLA* abx 7 (undocumented)
case 0x40: RTI(); return 6; // RTI
case 0x41: EOR( src_X_ind() ); return 6; // EOR X,ind
case 0x42: HLT(); return 0; // JAM / KIL / HLT* - Halts / Hangs / Jams / Kills the CPU (undocumented)
case 0x43: SRE( addr_ind_X() ); return 8; // SRE* izx 8 (undocumented)
case 0x44: NOP(); src_zp(); return 3; // NOP* zp 3 (undocumented)
case 0x45: EOR( src_zp() ); return 3; // EOR zpg
case 0x46: LSR( addr_zp() ); return 5; // LSR zpg
case 0x47: SRE( addr_zp() ); return 5; // SRE* zp 5 (undocumented)
case 0x48: PHA(); return 3; // PHA
case 0x49: EOR( imm() ); return 2; // EOR imm
case 0x4A: LSRA(); return 2; // LSR A
case 0x4B: ASR( imm() ); return 2; // TODO: ALR / ASR* imm 2 (undocumented)
case 0x4C: JMP( abs_addr() ); return 3; // JMP abs
case 0x4D: EOR( src_abs() ); return 4; // EOR abs
case 0x4E: LSR( addr_abs() ); return 6; // LSR abs
case 0x4F: SRE( abs_addr() ); return 6; // SRE* abs 6 (undocumented)
case 0x50: BVC( rel_addr() ); return 2; // BVC rel
case 0x51: EOR( src_ind_Y() ); return 5; // EOR ind,Y
case 0x52: HLT(); return 0; // JAM / KIL / HLT* - Halts / Hangs / Jams / Kills the CPU (undocumented)
case 0x53: SRE( addr_ind_Y() ); return 8; // SRE* izy 8 (undocumented)
case 0x54: NOP(); src_zp_X(); return 4; // NOP* zpx 4 (undocumented)
case 0x55: EOR( src_zp_X() ); return 4; // AND zpg,X
case 0x56: LSR( addr_zp_X() ); return 6; // LSR zpg,X
case 0x57: SRE( addr_ind_X() ); return 6; // SRE* zpx 6 (undocumented)
case 0x58: CLI(); return 2; // CLI
case 0x59: EOR( src_abs_Y() ); return 4+1; // EOR abs,Y
case 0x5A: NOP(); return 2; // NOP* 2 (undocumented)
case 0x5B: SRE( addr_abs_Y() ); return 7; // SRE* aby 7 (undocumented)
case 0x5C: NOP(); src_abs_X(); return 4; // NOP* abx 4 (undocumented)
case 0x5D: EOR( src_abs_X() ); return 4+1; // EOR abs,X
case 0x5E: LSR( addr_abs_X() ); return 7; // LSR abs,X
case 0x5F: SRE( addr_abs_X() ); return 7; // SRE* abx 7 (undocumented)
case 0x60: RTS(); return 6; // RTS
case 0x61: ADC( src_X_ind() ); return 6; // ADC X,ind
case 0x62: HLT(); return 0; // JAM / KIL / HLT* - Halts / Hangs / Jams / Kills the CPU (undocumented)
case 0x63: RRA( addr_ind_X() ); return 8; // RRA* izx 8 (undocumented)
case 0x64: NOP(); src_zp(); return 3; // NOP* zp 3 (undocumented)
case 0x65: ADC( src_zp() ); return 3; // ADC zpg
case 0x66: ROR( addr_zp() ); return 5; // ROR zpg
case 0x67: RRA( addr_zp() ); return 5; // RRA* zp 5 (undocumented)
case 0x68: PLA(); return 4; // PLA
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 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)
case 0x70: BVS( rel_addr() ); return 2; // BVS rel
case 0x71: ADC( src_ind_Y() ); return 5; // ADC ind,Y
case 0x72: HLT(); return 0; // JAM / KIL / HLT* - Halts / Hangs / Jams / Kills the CPU (undocumented)
case 0x73: RRA( addr_ind_Y() ); return 8; // RRA* izy 8 (undocumented)
case 0x74: NOP(); src_zp_X(); return 4; // NOP* zpx 4 (undocumented)
case 0x75: ADC( src_zp_X() ); return 4; // ADC zpg,X
case 0x76: ROR( addr_zp_X() ); return 6; // ROR zpg,X
case 0x77: RRA( addr_zp_X() ); return 6; // RRA* zpx 6 (undocumented)
case 0x78: SEI(); return 2; // SEI
case 0x79: ADC( src_abs_Y() ); return 4+1; // ADC abs,Y
case 0x7A: NOP(); return 2; // NOP* 2 (undocumented)
case 0x7B: RRA( addr_abs_Y() ); return 7; // RRA* aby 7 (undocumented)
case 0x7C: NOP(); src_abs_X(); return 4; // NOP* abx 4 (undocumented)
case 0x7D: ADC( src_abs_X() ); return 4+1; // ADC abs,X
case 0x7E: ROR( addr_abs_X() ); return 7; // ROR abs,X
case 0x7F: RRA( addr_abs_X() ); return 7; // RRA* abx 7 (undocumented)
case 0x80: NOP(); imm(); return 2; // NOP* imm 2 (undocumented)
case 0x81: STA( addr_ind_X() ) ; return 6; // STA X,ind
case 0x82: NOP(); imm(); return 2; // NOP* imm 2 (undocumented)
case 0x83: SAX( addr_ind_X() ); return 6; // SAX* izx 6 (undocumented)
case 0x84: STY( addr_zp() ); return 3; // STY zpg
case 0x85: STA( addr_zp() ); return 3; // STA zpg
case 0x86: STX( addr_zp() ); return 3; // STX zpg
case 0x87: SAX( addr_zp() ); return 3; // SAX* izx 6 (undocumented)
case 0x88: DEY(); return 2; // DEY
case 0x89: NOP(); imm(); return 2; // NOP* imm (undocumented)
case 0x8A: TXA(); return 2; // TXA
case 0x8B: XAA( imm() ); return 2; // ANE / 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 0x8F: SAX( addr_abs() ); return 4; // SAX* abs 4 (undocumented)
case 0x90: BCC( rel_addr() ); return 2; // BCC rel
case 0x91: STA( addr_ind_Y() ); return 6; // STA ind,Y
case 0x92: HLT(); return 0; // JAM / KIL / HLT* - Halts / Hangs / Jams / Kills the CPU (undocumented)
case 0x93: SHA( addr_ind_Y() ); return 6; // SHA* izy 6 (undocumented, unstable)
case 0x94: STY( addr_zp_X() ); return 4; // STY zpg,X
case 0x95: STA( addr_zp_X() ); return 4; // STA zpg,X
case 0x96: STX( addr_zp_Y() ); return 4; // STX zpg,Y
case 0x97: SAX( addr_zp_Y() ); return 4; // SAX* izy 4 (undocumented)
case 0x98: TYA(); return 2; // TYA
case 0x99: STA( addr_abs_Y() ); return 5; // STA abs,Y
case 0x9A: TXS(); return 2; // TXS
case 0x9B: SAS( addr_abs_Y() ); return 5; // TAS / XAS / SHS / SAS* aby 5 (undocumented, unstable)
case 0x9C: SHY( addr_abs_X() ); return 5; // SHY* abx 5 (undocumented, unstable)
case 0x9D: STA( addr_abs_X() ); return 5; // STA abs,X
case 0x9E: SHX( addr_abs_Y() ); return 5; // SHX* aby 5 (undocumented, unstable)
case 0x9F: SAX( addr_abs_Y() ); return 5; // TODO: SHA / SAX* aby 5 (undocumented, unstable)
case 0xA0: LDY( imm() ); return 2; // LDY imm
case 0xA1: LDA( src_X_ind() ) ; return 6; // LDA X,ind
case 0xA2: LDX( imm() ); return 2; // LDX imm
case 0xA3: LAX( src_X_ind() ); return 6; // LAX* izx 6 (undocumented)
case 0xA4: LDY( src_zp() ); return 3; // LDY zpg
case 0xA5: LDA( src_zp() ); return 3; // LDA zpg
case 0xA6: LDX( src_zp() ); return 3; // LDX zpg
case 0xA7: LAX( src_zp() ); return 3; // LAX* zpg 3 (undocumented)
case 0xA8: TAY(); return 2; // TAY
case 0xA9: LDA( imm() ); return 2; // LDA imm
case 0xAA: TAX(); return 2; // TAX
case 0xAB: LAX( imm() ); return 2; // LAX* imm 2 (undocumented, highly unstable)
case 0xAC: LDY( src_abs() ); return 4; // LDY abs
case 0xAD: LDA( src_abs() ); return 4; // LDA abs
case 0xAE: LDX( src_abs() ); return 4; // LDX abs
case 0xAF: LAX( src_abs() ); return 4; // LAX* abs 4 (undocumented)
case 0xB0: BCS( rel_addr() ); return 2; // BCS rel
case 0xB1: LDA( src_ind_Y() ); return 5; // LDA ind,Y
case 0xB2: HLT(); return 0; // JAM / KIL / HLT* - Halts / Hangs / Jams / Kills the CPU (undocumented)
case 0xB3: LAX( src_ind_Y() ); return 5; // LAX* izy 5 (undocumented)
case 0xB4: LDY( src_zp_X() ); return 4+1; // LDY zpg,X
case 0xB5: LDA( src_zp_X() ); return 4+1; // LDA zpg,X
case 0xB6: LDX( src_zp_Y() ); return 4+1; // LDX zpg,Y
case 0xB7: LAX( src_zp_Y() ); return 4+1; // LAX* zpy 4 (undocumented)
case 0xB8: CLV(); return 2; // CLV
case 0xB9: LDA( src_abs_Y() ); return 4; // LDA abs,Y
case 0xBA: TSX(); return 2; // TSX
case 0xBB: LAS( src_abs_Y() ); return 4; // TODO: LAS / LAR / LAX* aby 4 (undocumented)
case 0xBC: LDY( src_abs_X() ); return 4; // LDY abs,X
case 0xBD: LDA( src_abs_X() ); return 4; // LDA abs,X
case 0xBE: LDX( src_abs_Y() ); return 4; // LDX abs,Y
case 0xBF: LAX( src_abs_Y() ); return 4; // LAX* aby 4 (undocumented)
case 0xC0: CPY( imm() ); return 2; // CPY imm
case 0xC1: CMP( src_X_ind() ) ; return 6; // LDA X,ind
case 0xC2: NOP(); imm(); return 2; // NOP* imm 2 (undocumented)
case 0xC3: DCP( addr_ind_X() ); return 8; // DCP* izx 8 (undocumented)
case 0xC4: CPY( src_zp() ); return 3; // CPY zpg
case 0xC5: CMP( src_zp() ); return 3; // CMP zpg
case 0xC6: DEC( addr_zp() ); return 5; // DEC zpg
case 0xC7: DCP( addr_zp() ); return 5; // DCP* zpg 5 (undocumented)
case 0xC8: INY(); return 2; // INY
case 0xC9: CMP( imm() ); return 2; // CMP imm
case 0xCA: DEX(); return 2; // DEX
case 0xCB: SBX( imm() ); return 2; // SBX* imm 2 (undocumented)
case 0xCC: CPY( src_abs() ); return 4; // CPY abs
case 0xCD: CMP( src_abs() ); return 4; // CMP abs
case 0xCE: DEC( addr_abs() ); return 6; // DEC abs
case 0xCF: DCP( addr_abs() ); return 6; // DCP* abs 6 (undocumented)
case 0xD0: BNE( rel_addr() ); return 2; // BNE rel
case 0xD1: CMP( src_ind_Y() ); return 5; // CMP ind,Y
case 0xD2: HLT(); return 0; // JAM / KIL / HLT* - Halts / Hangs / Jams / Kills the CPU (undocumented)
case 0xD3: DCP( addr_ind_Y() ); return 8; // DCP* izy 8 (undocumented)
case 0xD4: NOP(); src_zp_X(); return 4; // NOP* zpx 4 (undocumented)
case 0xD5: CMP( src_zp_X() ); return 4; // CMP zpg,X
case 0xD6: DEC( addr_zp_X() ); return 6; // DEC zpg,X
case 0xD7: DCP( addr_zp_X() ); return 6; // DCP* zpx 6 (undocumented)
case 0xD8: CLD(); return 2; // CLD
case 0xD9: CMP( src_abs_Y() ); return 4; // CMP abs,Y
case 0xDA: NOP(); return 2; // NOP* 2 (undocumented)
case 0xDB: DCP( addr_abs_Y() ); return 7; // DCP* aby 7 (undocumented)
case 0xDC: NOP(); src_abs_X(); return 4; // NOP* abx 4 (undocumented)
case 0xDD: CMP( src_abs_X() ); return 4; // CMP abs,X
case 0xDE: DEC( addr_abs_X() ); return 7; // DEC abs,X
case 0xDF: DCP( addr_abs_X() ); return 7; // DCP* abx 7 (undocumented)
case 0xE0: CPX( imm() ); return 2; // CPX imm
case 0xE1: SBC( src_X_ind() ) ; return 6; // SBC (X,ind)
case 0xE2: NOP(); imm(); return 2; // NOP* imm 2 (undocumented)
case 0xE3: ISB( addr_ind_X() ); return 8; // ISC / INS / ISB* izx 8 (undocumented)
case 0xE4: CPX( src_zp() ); return 3; // CPX zpg
case 0xE5: SBC( src_zp() ); return 3; // SBC zpg
case 0xE6: INC( addr_zp() ); return 5; // INC zpg
case 0xE7: ISB( addr_zp() ); return 5; // ISC / INS / ISB* zpg 5 (undocumented)
case 0xE8: INX(); return 2; // INX
case 0xE9: SBC( imm() ); return 2; // SBC imm
case 0xEA: NOP(); return 2; // NOP
case 0xEB: SBC( imm() ); return 2; // USBC / SBC* imm 2 (undocumented)
case 0xEC: CPX( src_abs() ); return 4; // CPX abs
case 0xED: SBC( src_abs() ); return 4; // SBC abs
case 0xEE: INC( addr_abs() ); return 6; // INC abs
case 0xEF: ISB( addr_abs() ); return 6; // ISC / INS / ISB* abs 6 (undocumented)
case 0xF0: BEQ( rel_addr() ); return 2; // BEQ rel
case 0xF1: SBC( src_ind_Y() ); return 5; // SBC ind,Y
case 0xF2: HLT(); return 0; // JAM / KIL / HLT* - Halts / Hangs / Jams / Kills the CPU (undocumented)
case 0xF3: ISB( addr_ind_Y() ); return 8; // ISC / INS / ISB* izy 8 (undocumented)
case 0xF4: NOP(); src_zp_X(); return 4; // NOP* zpx 4 (undocumented)
case 0xF5: SBC( src_zp_X() ); return 4; // SBC zpg,X
case 0xF6: INC( addr_zp_X() ); return 6; // INC zpg,X
case 0xF7: ISB( addr_zp_X() ); return 6; // ISC / INS / ISB* zpx 6 (undocumented)
case 0xF8: SED(); return 2; // SED
case 0xF9: SBC( src_abs_Y() ); return 4+1; // SBC abs,Y
case 0xFA: NOP(); return 2; // NOP (undocumented)
case 0xFB: ISB( addr_abs_Y() ); return 7; // ISB* aby 7 (undocumented)
case 0xFC: NOP(); src_abs_X(); return 4; // NOP* abx 4 (undocumented)
case 0xFD: SBC( src_abs_X() ); return 4+1; // SBC abs,X
case 0xFE: INC( addr_abs_X() ); return 7; // INC abs,X
case 0xFF: ISB( addr_abs_X() ); return 7; // ISC / INS / ISB* abx 7 (undocumented)
#include "6502_std.h" // Standard 6502 instructions
#include "6502_und.h" // Undocumented 6502 instructions
//#include "6502_C.h" // Extended 65C02 instructions
// case 0x00: BRK(); return 7; // BRK
// case 0x01: ORA( src_X_ind() ); return 6; // ORA X,ind
// case 0x02: HLT(); return 0; // JAM / KIL / HLT* - Halts / Hangs / Jams / Kills the CPU (undocumented)
// case 0x03: SLO( addr_zp_X() ); return 8; // SLO* zpg,X (undocumented)
// case 0x04: NOP(); src_zp(); return 3; // NOP* zpg (undocumented)
// case 0x05: ORA( src_zp() ); return 3; // ORA zpg
// case 0x06: ASL( addr_zp() ); return 5; // ASL zpg
// case 0x07: SLO( addr_zp() ); return 5; // SLO* zpg (undocumented)
// case 0x08: PHP(); return 3; // PHP
// case 0x09: ORA( imm() ); return 2; // ORA imm
// case 0x0A: ASLA(); return 2; // ASL A
// case 0x0B: ANC( imm() ); return 2; // ANC** imm (undocumented)
// case 0x0C: NOP(); src_abs(); return 4; // NOP* (undocumented)
// case 0x0D: ORA( src_abs() ); return 4; // ORA abs
// case 0x0E: ASL( addr_abs() ); return 6; // ASL abs
// case 0x0F: SLO( addr_abs() ); return 6; // SLO* (undocumented)
// case 0x10: BPL( rel_addr() ); return 2; // BPL rel
// case 0x11: ORA( src_ind_Y() ); return 5; // ORA ind,Y
// case 0x12: HLT(); return 0; // JAM / KIL / HLT* - Halts / Hangs / Jams / Kills the CPU (undocumented)
// case 0x13: SLO( addr_zp_Y() ); return 8; // SLO* zpg,Y (undocumented)
// case 0x14: NOP(); addr_zp_X(); return 4; // NOP* zpg,X (undocumented)
// case 0x15: ORA( src_zp_X() ); return 4; // ORA zpg,X
// case 0x16: ASL( addr_zp_X() ); return 6; // ASL zpg,X
// case 0x17: SLO( addr_zp_X() ); return 6; // SLO* zpg,X (undocumented)
// case 0x18: CLC(); return 2; // CLC
// case 0x19: ORA( src_abs_Y() ); return 4+1; // ORA abs,Y
// case 0x1A: NOP(); return 2; // NOP* (undocumented)
// case 0x1B: SLO( addr_abs_Y() ); return 7; // SLO* abs,Y (undocumented)
// case 0x1C: NOP(); src_abs_X(); return 4; // NOP* (undocumented)
// case 0x1D: ORA( src_abs_X() ); return 4+1; // ORA abs,X
// case 0x1E: ASL( addr_abs_X() ); return 7; // ASL abs,X
// case 0x1F: SLO( addr_abs_X() ); return 7; // SLO* abs,X (undocumented)
// case 0x20: JSR( abs_addr() ); return 6; // JSR abs
// case 0x21: AND( src_X_ind() ); return 6; // AND X,ind
// case 0x22: HLT(); return 0; // JAM / KIL / HLT* - Halts / Hangs / Jams / Kills the CPU (undocumented)
// case 0x23: RLA( addr_ind_X() ); return 8; // RLA* ind,X 8 (undocumented)
// case 0x24: BIT( src_zp() ); return 3; // BIT zpg
// case 0x25: AND( src_zp() ); return 3; // AND zpg
// case 0x26: ROL( addr_zp() ); return 5; // ROL zpg
// case 0x27: RLA( addr_zp() ); return 5; // RLA* zpg 5 (undocumented)
// case 0x28: PLP(); return 4; // PLP
// case 0x29: AND( imm() ); return 2; // AND imm
// case 0x2A: ROLA(); return 2; // ROL A
// case 0x2B: ANC( imm() ); return 2; // ANC* imm 2 (undocumented)
// case 0x2C: BIT( src_abs() ); return 4; // BIT abs
// case 0x2D: AND( src_abs() ); return 4; // AND abs
// case 0x2E: ROL( addr_abs() ); return 6; // ROL abs
// case 0x2F: RLA( addr_abs() ); return 6; // RLA* abs 6 (undocumented)
// case 0x30: BMI( rel_addr() ); return 2; // BMI rel
// case 0x31: AND( src_ind_Y() ); return 5; // AND ind,Y
// case 0x32: HLT(); return 0; // JAM / KIL / HLT* - Halts / Hangs / Jams / Kills the CPU (undocumented)
// case 0x33: RLA( addr_ind_Y() ); return 8; // RLA* izy 8 (undocumented)
// case 0x34: NOP(); src_zp_X(); return 4; // NOP* zpx 4 (undocumented)
// case 0x35: AND( src_zp_X() ); return 4; // AND zpg,X
// case 0x36: ROL( addr_zp_X() ); return 6; // ROL zpg,X
// case 0x37: RLA( addr_zp_X() ); return 6; // RLA* zpx 6 (undocumented)
// case 0x38: SEC(); return 2; // SEC
// case 0x39: AND( src_abs_Y() ); return 4+1; // AND abs,Y
// case 0x3A: NOP(); return 2; // NOP* 2 (undocumented)
// case 0x3B: RLA( addr_abs_Y() ); return 7; // RLA* aby 7 (undocumented)
// case 0x3C: NOP(); src_abs_X(); return 4; // NOP* abx 4 (undocumented)
// case 0x3D: AND( src_abs_X() ); return 4+1; // AND abs,X
// case 0x3E: ROL( addr_abs_X() ); return 7; // ROL abs,X
// case 0x3F: RLA( addr_abs_X() ); return 7; // RLA* abx 7 (undocumented)
// case 0x40: RTI(); return 6; // RTI
// case 0x41: EOR( src_X_ind() ); return 6; // EOR X,ind
// case 0x42: HLT(); return 0; // JAM / KIL / HLT* - Halts / Hangs / Jams / Kills the CPU (undocumented)
// case 0x43: SRE( addr_ind_X() ); return 8; // SRE* izx 8 (undocumented)
// case 0x44: NOP(); src_zp(); return 3; // NOP* zp 3 (undocumented)
// case 0x45: EOR( src_zp() ); return 3; // EOR zpg
// case 0x46: LSR( addr_zp() ); return 5; // LSR zpg
// case 0x47: SRE( addr_zp() ); return 5; // SRE* zp 5 (undocumented)
// case 0x48: PHA(); return 3; // PHA
// case 0x49: EOR( imm() ); return 2; // EOR imm
// case 0x4A: LSRA(); return 2; // LSR A
// case 0x4B: ASR( imm() ); return 2; // TODO: ALR / ASR* imm 2 (undocumented)
// case 0x4C: JMP( abs_addr() ); return 3; // JMP abs
// case 0x4D: EOR( src_abs() ); return 4; // EOR abs
// case 0x4E: LSR( addr_abs() ); return 6; // LSR abs
// case 0x4F: SRE( abs_addr() ); return 6; // SRE* abs 6 (undocumented)
// case 0x50: BVC( rel_addr() ); return 2; // BVC rel
// case 0x51: EOR( src_ind_Y() ); return 5; // EOR ind,Y
// case 0x52: HLT(); return 0; // JAM / KIL / HLT* - Halts / Hangs / Jams / Kills the CPU (undocumented)
// case 0x53: SRE( addr_ind_Y() ); return 8; // SRE* izy 8 (undocumented)
// case 0x54: NOP(); src_zp_X(); return 4; // NOP* zpx 4 (undocumented)
// case 0x55: EOR( src_zp_X() ); return 4; // AND zpg,X
// case 0x56: LSR( addr_zp_X() ); return 6; // LSR zpg,X
// case 0x57: SRE( addr_ind_X() ); return 6; // SRE* zpx 6 (undocumented)
// case 0x58: CLI(); return 2; // CLI
// case 0x59: EOR( src_abs_Y() ); return 4+1; // EOR abs,Y
// case 0x5A: NOP(); return 2; // NOP* 2 (undocumented)
// case 0x5B: SRE( addr_abs_Y() ); return 7; // SRE* aby 7 (undocumented)
// case 0x5C: NOP(); src_abs_X(); return 4; // NOP* abx 4 (undocumented)
// case 0x5D: EOR( src_abs_X() ); return 4+1; // EOR abs,X
// case 0x5E: LSR( addr_abs_X() ); return 7; // LSR abs,X
// case 0x5F: SRE( addr_abs_X() ); return 7; // SRE* abx 7 (undocumented)
// case 0x60: RTS(); return 6; // RTS
// case 0x61: ADC( src_X_ind() ); return 6; // ADC X,ind
// case 0x62: HLT(); return 0; // JAM / KIL / HLT* - Halts / Hangs / Jams / Kills the CPU (undocumented)
// case 0x63: RRA( addr_ind_X() ); return 8; // RRA* izx 8 (undocumented)
// case 0x64: NOP(); src_zp(); return 3; // NOP* zp 3 (undocumented)
// case 0x65: ADC( src_zp() ); return 3; // ADC zpg
// case 0x66: ROR( addr_zp() ); return 5; // ROR zpg
// case 0x67: RRA( addr_zp() ); return 5; // RRA* zp 5 (undocumented)
// case 0x68: PLA(); return 4; // PLA
// 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 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)
// case 0x70: BVS( rel_addr() ); return 2; // BVS rel
// case 0x71: ADC( src_ind_Y() ); return 5; // ADC ind,Y
// case 0x72: HLT(); return 0; // JAM / KIL / HLT* - Halts / Hangs / Jams / Kills the CPU (undocumented)
// case 0x73: RRA( addr_ind_Y() ); return 8; // RRA* izy 8 (undocumented)
// case 0x74: NOP(); src_zp_X(); return 4; // NOP* zpx 4 (undocumented)
// case 0x75: ADC( src_zp_X() ); return 4; // ADC zpg,X
// case 0x76: ROR( addr_zp_X() ); return 6; // ROR zpg,X
// case 0x77: RRA( addr_zp_X() ); return 6; // RRA* zpx 6 (undocumented)
// case 0x78: SEI(); return 2; // SEI
// case 0x79: ADC( src_abs_Y() ); return 4+1; // ADC abs,Y
// case 0x7A: NOP(); return 2; // NOP* 2 (undocumented)
// case 0x7B: RRA( addr_abs_Y() ); return 7; // RRA* aby 7 (undocumented)
// case 0x7C: NOP(); src_abs_X(); return 4; // NOP* abx 4 (undocumented)
// case 0x7D: ADC( src_abs_X() ); return 4+1; // ADC abs,X
// case 0x7E: ROR( addr_abs_X() ); return 7; // ROR abs,X
// case 0x7F: RRA( addr_abs_X() ); return 7; // RRA* abx 7 (undocumented)
// case 0x80: NOP(); imm(); return 2; // NOP* imm 2 (undocumented)
// case 0x81: STA( addr_ind_X() ) ; return 6; // STA X,ind
// case 0x82: NOP(); imm(); return 2; // NOP* imm 2 (undocumented)
// case 0x83: SAX( addr_ind_X() ); return 6; // SAX* izx 6 (undocumented)
// case 0x84: STY( addr_zp() ); return 3; // STY zpg
// case 0x85: STA( addr_zp() ); return 3; // STA zpg
// case 0x86: STX( addr_zp() ); return 3; // STX zpg
// case 0x87: SAX( addr_zp() ); return 3; // SAX* izx 6 (undocumented)
// case 0x88: DEY(); return 2; // DEY
// case 0x89: NOP(); imm(); return 2; // NOP* imm (undocumented)
// case 0x8A: TXA(); return 2; // TXA
// case 0x8B: XAA( imm() ); return 2; // ANE / 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 0x8F: SAX( addr_abs() ); return 4; // SAX* abs 4 (undocumented)
// case 0x90: BCC( rel_addr() ); return 2; // BCC rel
// case 0x91: STA( addr_ind_Y() ); return 6; // STA ind,Y
// case 0x92: HLT(); return 0; // JAM / KIL / HLT* - Halts / Hangs / Jams / Kills the CPU (undocumented)
// case 0x93: SHA( addr_ind_Y() ); return 6; // SHA* izy 6 (undocumented, unstable)
// case 0x94: STY( addr_zp_X() ); return 4; // STY zpg,X
// case 0x95: STA( addr_zp_X() ); return 4; // STA zpg,X
// case 0x96: STX( addr_zp_Y() ); return 4; // STX zpg,Y
// case 0x97: SAX( addr_zp_Y() ); return 4; // SAX* izy 4 (undocumented)
// case 0x98: TYA(); return 2; // TYA
// case 0x99: STA( addr_abs_Y() ); return 5; // STA abs,Y
// case 0x9A: TXS(); return 2; // TXS
// case 0x9B: SAS( addr_abs_Y() ); return 5; // TAS / XAS / SHS / SAS* aby 5 (undocumented, unstable)
// case 0x9C: SHY( addr_abs_X() ); return 5; // SHY* abx 5 (undocumented, unstable)
// case 0x9D: STA( addr_abs_X() ); return 5; // STA abs,X
// case 0x9E: SHX( addr_abs_Y() ); return 5; // SHX* aby 5 (undocumented, unstable)
// case 0x9F: SAX( addr_abs_Y() ); return 5; // TODO: SHA / SAX* aby 5 (undocumented, unstable)
// case 0xA0: LDY( imm() ); return 2; // LDY imm
// case 0xA1: LDA( src_X_ind() ) ; return 6; // LDA X,ind
// case 0xA2: LDX( imm() ); return 2; // LDX imm
// case 0xA3: LAX( src_X_ind() ); return 6; // LAX* izx 6 (undocumented)
// case 0xA4: LDY( src_zp() ); return 3; // LDY zpg
// case 0xA5: LDA( src_zp() ); return 3; // LDA zpg
// case 0xA6: LDX( src_zp() ); return 3; // LDX zpg
// case 0xA7: LAX( src_zp() ); return 3; // LAX* zpg 3 (undocumented)
// case 0xA8: TAY(); return 2; // TAY
// case 0xA9: LDA( imm() ); return 2; // LDA imm
// case 0xAA: TAX(); return 2; // TAX
// case 0xAB: LAX( imm() ); return 2; // LAX* imm 2 (undocumented, highly unstable)
// case 0xAC: LDY( src_abs() ); return 4; // LDY abs
// case 0xAD: LDA( src_abs() ); return 4; // LDA abs
// case 0xAE: LDX( src_abs() ); return 4; // LDX abs
// case 0xAF: LAX( src_abs() ); return 4; // LAX* abs 4 (undocumented)
// case 0xB0: BCS( rel_addr() ); return 2; // BCS rel
// case 0xB1: LDA( src_ind_Y() ); return 5; // LDA ind,Y
// case 0xB2: HLT(); return 0; // JAM / KIL / HLT* - Halts / Hangs / Jams / Kills the CPU (undocumented)
// case 0xB3: LAX( src_ind_Y() ); return 5; // LAX* izy 5 (undocumented)
// case 0xB4: LDY( src_zp_X() ); return 4+1; // LDY zpg,X
// case 0xB5: LDA( src_zp_X() ); return 4+1; // LDA zpg,X
// case 0xB6: LDX( src_zp_Y() ); return 4+1; // LDX zpg,Y
// case 0xB7: LAX( src_zp_Y() ); return 4+1; // LAX* zpy 4 (undocumented)
// case 0xB8: CLV(); return 2; // CLV
// case 0xB9: LDA( src_abs_Y() ); return 4; // LDA abs,Y
// case 0xBA: TSX(); return 2; // TSX
// case 0xBB: LAS( src_abs_Y() ); return 4; // TODO: LAS / LAR / LAX* aby 4 (undocumented)
// case 0xBC: LDY( src_abs_X() ); return 4; // LDY abs,X
// case 0xBD: LDA( src_abs_X() ); return 4; // LDA abs,X
// case 0xBE: LDX( src_abs_Y() ); return 4; // LDX abs,Y
// case 0xBF: LAX( src_abs_Y() ); return 4; // LAX* aby 4 (undocumented)
// case 0xC0: CPY( imm() ); return 2; // CPY imm
// case 0xC1: CMP( src_X_ind() ) ; return 6; // LDA X,ind
// case 0xC2: NOP(); imm(); return 2; // NOP* imm 2 (undocumented)
// case 0xC3: DCP( addr_ind_X() ); return 8; // DCP* izx 8 (undocumented)
// case 0xC4: CPY( src_zp() ); return 3; // CPY zpg
// case 0xC5: CMP( src_zp() ); return 3; // CMP zpg
// case 0xC6: DEC( addr_zp() ); return 5; // DEC zpg
// case 0xC7: DCP( addr_zp() ); return 5; // DCP* zpg 5 (undocumented)
// case 0xC8: INY(); return 2; // INY
// case 0xC9: CMP( imm() ); return 2; // CMP imm
// case 0xCA: DEX(); return 2; // DEX
// case 0xCB: SBX( imm() ); return 2; // SBX* imm 2 (undocumented)
// case 0xCC: CPY( src_abs() ); return 4; // CPY abs
// case 0xCD: CMP( src_abs() ); return 4; // CMP abs
// case 0xCE: DEC( addr_abs() ); return 6; // DEC abs
// case 0xCF: DCP( addr_abs() ); return 6; // DCP* abs 6 (undocumented)
// case 0xD0: BNE( rel_addr() ); return 2; // BNE rel
// case 0xD1: CMP( src_ind_Y() ); return 5; // CMP ind,Y
// case 0xD2: HLT(); return 0; // JAM / KIL / HLT* - Halts / Hangs / Jams / Kills the CPU (undocumented)
// case 0xD3: DCP( addr_ind_Y() ); return 8; // DCP* izy 8 (undocumented)
// case 0xD4: NOP(); src_zp_X(); return 4; // NOP* zpx 4 (undocumented)
// case 0xD5: CMP( src_zp_X() ); return 4; // CMP zpg,X
// case 0xD6: DEC( addr_zp_X() ); return 6; // DEC zpg,X
// case 0xD7: DCP( addr_zp_X() ); return 6; // DCP* zpx 6 (undocumented)
// case 0xD8: CLD(); return 2; // CLD
// case 0xD9: CMP( src_abs_Y() ); return 4; // CMP abs,Y
// case 0xDA: NOP(); return 2; // NOP* 2 (undocumented)
// case 0xDB: DCP( addr_abs_Y() ); return 7; // DCP* aby 7 (undocumented)
// case 0xDC: NOP(); src_abs_X(); return 4; // NOP* abx 4 (undocumented)
// case 0xDD: CMP( src_abs_X() ); return 4; // CMP abs,X
// case 0xDE: DEC( addr_abs_X() ); return 7; // DEC abs,X
// case 0xDF: DCP( addr_abs_X() ); return 7; // DCP* abx 7 (undocumented)
// case 0xE0: CPX( imm() ); return 2; // CPX imm
// case 0xE1: SBC( src_X_ind() ) ; return 6; // SBC (X,ind)
// case 0xE2: NOP(); imm(); return 2; // NOP* imm 2 (undocumented)
// case 0xE3: ISB( addr_ind_X() ); return 8; // ISC / INS / ISB* izx 8 (undocumented)
// case 0xE4: CPX( src_zp() ); return 3; // CPX zpg
// case 0xE5: SBC( src_zp() ); return 3; // SBC zpg
// case 0xE6: INC( addr_zp() ); return 5; // INC zpg
// case 0xE7: ISB( addr_zp() ); return 5; // ISC / INS / ISB* zpg 5 (undocumented)
// case 0xE8: INX(); return 2; // INX
// case 0xE9: SBC( imm() ); return 2; // SBC imm
// case 0xEA: NOP(); return 2; // NOP
// case 0xEB: SBC( imm() ); return 2; // USBC / SBC* imm 2 (undocumented)
// case 0xEC: CPX( src_abs() ); return 4; // CPX abs
// case 0xED: SBC( src_abs() ); return 4; // SBC abs
// case 0xEE: INC( addr_abs() ); return 6; // INC abs
// case 0xEF: ISB( addr_abs() ); return 6; // ISC / INS / ISB* abs 6 (undocumented)
// case 0xF0: BEQ( rel_addr() ); return 2; // BEQ rel
// case 0xF1: SBC( src_ind_Y() ); return 5; // SBC ind,Y
// case 0xF2: HLT(); return 0; // JAM / KIL / HLT* - Halts / Hangs / Jams / Kills the CPU (undocumented)
// case 0xF3: ISB( addr_ind_Y() ); return 8; // ISC / INS / ISB* izy 8 (undocumented)
// case 0xF4: NOP(); src_zp_X(); return 4; // NOP* zpx 4 (undocumented)
// case 0xF5: SBC( src_zp_X() ); return 4; // SBC zpg,X
// case 0xF6: INC( addr_zp_X() ); return 6; // INC zpg,X
// case 0xF7: ISB( addr_zp_X() ); return 6; // ISC / INS / ISB* zpx 6 (undocumented)
// case 0xF8: SED(); return 2; // SED
// case 0xF9: SBC( src_abs_Y() ); return 4+1; // SBC abs,Y
// case 0xFA: NOP(); return 2; // NOP (undocumented)
// case 0xFB: ISB( addr_abs_Y() ); return 7; // ISB* aby 7 (undocumented)
// case 0xFC: NOP(); src_abs_X(); return 4; // NOP* abx 4 (undocumented)
// case 0xFD: SBC( src_abs_X() ); return 4+1; // SBC abs,X
// case 0xFE: INC( addr_abs_X() ); return 7; // INC abs,X
// case 0xFF: ISB( addr_abs_X() ); return 7; // ISC / INS / ISB* abx 7 (undocumented)
default:
dbgPrintf("%04X: Unimplemented Instruction 0x%02X\n", m6502.PC -1, memread( m6502.PC -1 ));
@ -715,7 +719,10 @@ void rom_loadFile( const char * bundlePath, const char * filename ) {
read_rom( bundlePath, filename, INT_64K_ROM + 0xD000, 0x1000, 12 * KB);
memcpy(Apple2_64K_MEM + 0xD000, INT_64K_ROM + 0xD000, 12 * KB);
}
// make a copy of the perfieral ROM area -- so it will fall back to this if no card inserted
memcpy(EXP_64K_ROM + 0xC100, INT_64K_ROM + 0xC100, 0x0F00);
}

View File

@ -34,14 +34,14 @@
// 6502 instructions with additional addressing modes
// ADC AND CMP EOR LDA ORA SBC STA - (zp) addressing mode
case 0x12: ORA( src_zp_0() ); return 5; // ORA (zpg)
case 0x32: AND( src_zp_0() ); return 5; // AND (zpg)
case 0x52: EOR( src_zp_0() ); return 5; // EOR (zpg)
case 0x72: ADC( src_zp_0() ); return 5; // ADC (zpg)
case 0x92: STA( src_zp_0() ); return 5; // STA (zpg)
case 0xB2: LDA( src_zp_0() ); return 5; // LDA (zpg)
case 0xD2: CMP( src_zp_0() ); return 5; // CMP (zpg)
case 0xF2: SBC( src_zp_0() ); return 5; // SBC (zpg)
case 0x12: ORA( src_ind() ); return 5; // ORA (zpg)
case 0x32: AND( src_ind() ); return 5; // AND (zpg)
case 0x52: EOR( src_ind() ); return 5; // EOR (zpg)
case 0x72: ADC( src_ind() ); return 5; // ADC (zpg)
case 0x92: STA( src_ind() ); return 5; // STA (zpg)
case 0xB2: LDA( src_ind() ); return 5; // LDA (zpg)
case 0xD2: CMP( src_ind() ); return 5; // CMP (zpg)
case 0xF2: SBC( src_ind() ); return 5; // SBC (zpg)
// BIT - imm abs,X zp,X addressing modes
case 0x34: BIT( src_zp_X() ); return 4; // BIT zpg,X

View File

@ -44,7 +44,7 @@
case 0x0D: ORA( src_abs() ); return 4; // ORA abs
case 0x0E: ASL( addr_abs() ); return 6; // ASL abs
case 0x10: BPL( rel_addr() ); return 3; // BPL rel
case 0x10: BPL( rel_addr() ); return 2; // BPL rel
case 0x11: ORA( src_ind_Y() ); return 5; // ORA ind,Y
case 0x15: ORA( src_zp_X() ); return 4; // ORA zpg,X
@ -71,7 +71,7 @@
case 0x2D: AND( src_abs() ); return 4; // AND abs
case 0x2E: ROL( addr_abs() ); return 6; // ROL abs
case 0x30: BMI( rel_addr() ); return 3; // BMI rel
case 0x30: BMI( rel_addr() ); return 2; // BMI rel
case 0x31: AND( src_ind_Y() ); return 5; // AND ind,Y
case 0x35: AND( src_zp_X() ); return 4; // AND zpg,X
@ -97,7 +97,7 @@
case 0x4D: EOR( src_abs() ); return 4; // EOR abs
case 0x4E: LSR( addr_abs() ); return 6; // LSR abs
case 0x50: BVC( rel_addr() ); return 3; // BVC rel
case 0x50: BVC( rel_addr() ); return 2; // BVC rel
case 0x51: EOR( src_ind_Y() ); return 5; // EOR ind,Y
case 0x55: EOR( src_zp_X() ); return 4; // AND zpg,X
@ -123,7 +123,7 @@
case 0x6D: ADC( src_abs() ); return 4; // ADC abs
case 0x6E: ROR( addr_abs() ); return 6; // ROR abs
case 0x70: BVS( rel_addr() ); return 3; // BVS rel
case 0x70: BVS( rel_addr() ); return 2; // BVS rel
case 0x71: ADC( src_ind_Y() ); return 5; // ADC ind,Y
case 0x75: ADC( src_zp_X() ); return 4; // ADC zpg,X
@ -149,7 +149,7 @@
case 0x8D: STA( addr_abs() ); return 4; // STA abs
case 0x8E: STX( addr_abs() ); return 4; // STX abs
case 0x90: BCC( rel_addr() ); return 3; // BCC rel
case 0x90: BCC( rel_addr() ); return 2; // BCC rel
case 0x91: STA( addr_ind_Y() ); return 6; // STA ind,Y
case 0x94: STY( addr_zp_X() ); return 4; // STY zpg,X
@ -178,7 +178,7 @@
case 0xAD: LDA( src_abs() ); return 4; // LDA abs
case 0xAE: LDX( src_abs() ); return 4; // LDX abs
case 0xB0: BCS( rel_addr() ); return 3; // BCS rel
case 0xB0: BCS( rel_addr() ); return 2; // BCS rel
case 0xB1: LDA( src_ind_Y() ); return 5; // LDA ind,Y
case 0xB4: LDY( src_zp_X() ); return 4+1; // LDY zpg,X
@ -191,8 +191,8 @@
case 0xBC: LDY( src_abs_X() ); return 4; // LDY abs,X
case 0xBD: LDA( src_abs_X() ); return 4; // LDA abs,X
case 0xBE: LDX( src_abs_Y() ); return 4;
// LDX abs,Y
case 0xBE: LDX( src_abs_Y() ); return 4; // LDX abs,Y
case 0xC0: CPY( imm() ); return 2; // CPY imm
case 0xC1: CMP( src_X_ind() ) ; return 6; // LDA X,ind
@ -208,7 +208,7 @@
case 0xCD: CMP( src_abs() ); return 4; // CMP abs
case 0xCE: DEC( addr_abs() ); return 6; // DEC abs
case 0xD0: BNE( rel_addr() ); return 3; // BNE rel
case 0xD0: BNE( rel_addr() ); return 2; // BNE rel
case 0xD1: CMP( src_ind_Y() ); return 5; // CMP ind,Y
case 0xD5: CMP( src_zp_X() ); return 4; // CMP zpg,X
@ -235,7 +235,7 @@
case 0xED: SBC( src_abs() ); return 4; // SBC abs
case 0xEE: INC( addr_abs() ); return 6; // INC abs
case 0xF0: BEQ( rel_addr() ); return 3; // BEQ rel
case 0xF0: BEQ( rel_addr() ); return 2; // BEQ rel
case 0xF1: SBC( src_ind_Y() ); return 5; // SBC ind,Y
case 0xF5: SBC( src_zp_X() ); return 4; // SBC zpg,X

View File

@ -70,6 +70,8 @@ ALCcontext *ctx = NULL;
int spkr_att = 0;
int spkr_level = SPKR_LEVEL_ZERO;
int spkr_level_ema = SPKR_LEVEL_ZERO;
int spkr_level_dema = SPKR_LEVEL_ZERO;
int spkr_level_tema = SPKR_LEVEL_ZERO;
int spkr_last_level = SPKR_LEVEL_ZERO;
#define BUFFER_COUNT 256
@ -170,9 +172,11 @@ void spkr_load_sfx( const char * bundlePath ) {
diskioerr_sfx_len = load_sfx(bundlePath, "disk_ii_io_error.sfx", &diskioerr_sfx);
}
#define NO_SPKR_KEEP_PITCH
#undef SPKR_KEEP_PITCH
#undef SPKR_DEBUG
#undef SPKR_DEBUG_BEFORE_EMA
#define NO_SPKR_DEBUG
#ifdef SPKR_DEBUG
static const char * spkr_debug_filename = "steve2_audio_debug.bin";
FILE * spkr_debug_file = NULL;
@ -475,7 +479,8 @@ void spkr_toggle() {
// indexer = (double)spkr_sample_rate / MHZ(default_MHz_6502) * MHz_6502;
}
#endif
// spkr_sample_idx = round( (spkr_clk + m6502.clkfrm) / ( MHZ(default_MHz_6502) / (double)spkr_sample_rate)) * SPKR_CHANNELS;
spkr_sample_idx = round( (double)(spkr_clk + m6502.clkfrm) * multiplier ) * SPKR_CHANNELS;
spkr_sample_idx &= UINTMAX_MAX - 1;
@ -568,7 +573,9 @@ void spkr_update() {
spkr_sample_last_idx = 0;
spkr_level = SPKR_LEVEL_ZERO;
spkr_level_ema = SPKR_LEVEL_ZERO;
spkr_level_dema = SPKR_LEVEL_ZERO;
spkr_level_tema = SPKR_LEVEL_ZERO;
// spkr_last_level = SPKR_LEVEL_ZERO;
}
@ -613,15 +620,34 @@ void spkr_update() {
#endif
#endif
static const int ema_len = 30; // soft: 70;
// to use with EMA
// static const int ema_len_sharper = 30;
// static const int ema_len_soft = 70;
// static const int ema_len_supersoft = 200;
// to use with TEMA
static const int ema_len_sharper = 7;
static const int ema_len_sharp = 14;
static const int ema_len_normal = 20;
static const int ema_len_soft = 30;
static const int ema_len_supersoft = 40;
static const int ema_len = ema_len_normal;
int i = 0;
while ( i <= spkr_buf_size ) {
spkr_level_ema = ema(spkr_samples[i], spkr_level_ema, ema_len);
spkr_level_dema = ema(spkr_level_ema, spkr_level_dema, ema_len);
spkr_level_tema = ema(spkr_level_dema, spkr_level_tema, ema_len);
// super smooth Quadratic EMA
spkr_samples[i++] = spkr_level_ema;
spkr_samples[i++] = spkr_level_ema;
// int level = spkr_level_tema;
// if (abs(spkr_level_ema) < 1000 ) {
// level = 0;
// }
// smoothing with Tripple EMA
spkr_samples[i++] = spkr_level_tema;
spkr_samples[i++] = spkr_level_tema;
}
#ifdef SPKR_DEBUG // Debug SPKR Buffer After EMA

View File

@ -22,6 +22,8 @@
//
#include <stdlib.h>
#include "mmio.h"
#include "common.h"
#include "6502.h"
@ -78,7 +80,8 @@ MEMcfg_t newMEMcfg = INIT_MEMCFG;
const uint8_t * const shadowLowMEM = Apple2_64K_MEM + 0x200;
const uint8_t * currentLowMEM = Apple2_64K_RAM + 0x200;
const uint8_t * currentLowRDMEM = Apple2_64K_RAM + 0x200;
uint8_t * currentLowWRMEM = Apple2_64K_RAM;
/// No writing (Readonly), and mark it as NO need to commit from Shadow RAM
@ -91,11 +94,24 @@ INLINE void set_MEM_readonly() {
}
/// Returns TRUE if already writeable or second of the "two consecutive" reads on appropriate soft switches
INLINE int is_wr_enabled() {
uint64_t clk = m6502.clktime + m6502.clkfrm;
uint64_t elapsed = clk - m6502.clk_wrenable;
int is_enabled = ( elapsed < 16 ) || MEMcfg.WR_RAM;
printf("is_wr_enabled elapsed:%llu was_enabled:%i to_be_enabled:%i\n", elapsed, MEMcfg.WR_RAM, is_enabled);
m6502.clk_wrenable = clk;
return is_enabled;
}
/// Make AUX RAM writeable -- This is when AUX is also readable, othwrwise use set_AUX_write...
INLINE void set_MEM_write() {
// two consecutive read or write needs for write enable
// Note: if it is already writeable and was previously a ROM read + RAM write, then we also need to bound AUX to MEM
if ( ( (m6502.clktime + m6502.clkfrm - m6502.clk_wrenable) < 8 ) || (MEMcfg.WR_RAM) ) {
if ( is_wr_enabled() ) {
printf("WR_AUX\n");
// will write to Shadow RAM, and mark it as need to commit from Shadow RAM
@ -103,8 +119,6 @@ INLINE void set_MEM_write() {
WRD0MEM = Apple2_64K_MEM; // for Write $D000 - $DFFF (shadow memory) - BANK X
WRHIMEM = Apple2_64K_MEM; // for Write $E000 - $FFFF (shadow memory)
}
m6502.clk_wrenable = m6502.clktime + m6502.clkfrm;
}
@ -112,7 +126,7 @@ INLINE void set_MEM_write() {
INLINE void set_AUX_write() {
// will write directly to Auxiliary RAM, and mark it as NO need to commit from Shadow RAM
// Note: if it is already writeable and was previously a RAM read + RAM write, then we also need to bound AUX to MEM
if ( ( (m6502.clktime + m6502.clkfrm - m6502.clk_wrenable) < 8 ) || (MEMcfg.WR_RAM) ) {
if ( is_wr_enabled() ) {
printf("WR_AUX\n");
MEMcfg.WR_RAM = 1;
@ -124,8 +138,6 @@ INLINE void set_AUX_write() {
}
WRHIMEM = Apple2_64K_AUX; // for Write $E000 - $FFFF (shadow memory)
}
m6502.clk_wrenable = m6502.clktime + m6502.clkfrm;
}
@ -196,6 +208,7 @@ INLINE void io_RAM_EXP( uint16_t addr ) {
MEMcfg.RD_INT_RAM = 0;
// TODO: What about CX (Slot) ROM?
// load the content of ROM Memory
memcpy(Apple2_64K_MEM + 0xD000, INT_64K_ROM + 0xD000, 0x3000);
@ -246,16 +259,48 @@ INLINE void io_RAM_EXP( uint16_t addr ) {
}
INLINE int is_io_interesting(addr) {
switch(addr) {
case io_KBD:
case io_KBDSTRB:
case io_TAPEOUT:
case io_SPKR:
case io_VID_ALTCHAR:
case io_VID_RD80VID:
case io_RDCXROM:
// Ignore Disk IO
case 0xC0E0:
case 0xC0E1:
case 0xC0E2:
case 0xC0E3:
case 0xC0E4:
case 0xC0E5:
case 0xC0E6:
case 0xC0E7:
case 0xC0E8:
case 0xC0E9:
case 0xC0EA:
case 0xC0EB:
case 0xC0EC:
case 0xC0ED:
case 0xC0EE:
case 0xC0EF:
return 0;
default:
break;
}
return 1;
}
INLINE uint8_t ioRead( uint16_t addr ) {
// if (outdev) fprintf(outdev, "ioRead:%04X\n", addr);
// switch(addr) {
// case io_KBD:
// case io_KBDSTRB:
// case io_SPKR:
// break;
// default:
// printf("ioRead:%04X (PC:%04X)\n", addr, m6502.PC);
// if ( is_io_interesting(addr) ) {
// printf("ioRead:%04X (PC:%04X)\n", addr, m6502.PC);
// }
unsigned int IOframe = m6502.clkfrm - lastIO;
@ -277,25 +322,6 @@ INLINE uint8_t ioRead( uint16_t addr ) {
}
switch ( (uint8_t)addr ) {
// case 0x20:
case 0x21:
case 0x22:
case 0x23:
case 0x24:
case 0x25:
case 0x26:
case 0x27:
case 0x28:
case 0x29:
case 0x2A:
case 0x2B:
case 0x2C:
case 0x2D:
case 0x2E:
case 0x2F:
printf("RD TAPEIO: %04X\n", addr);
return 0;
case (uint8_t)io_KBD:
return Apple2_64K_RAM[io_KBD];
@ -312,9 +338,25 @@ INLINE uint8_t ioRead( uint16_t addr ) {
return Apple2_64K_RAM[io_KBDSTRB];
case (uint8_t)io_TAPEOUT:
// TODO: 1. Sound problem in Castle Wolfensein if we output this to speaker all the time
// 2. Implement Tape
return rand(); // no tape, floating I/O
case (uint8_t)io_SPKR:
spkr_toggle();
return Apple2_64K_RAM[io_SPKR];
return rand(); // Floating I/O -- used for random number genet=ration in Games
case (uint8_t)io_STROBE:
case (uint8_t)io_CLRAN0:
case (uint8_t)io_SETAN0:
case (uint8_t)io_CLRAN1:
case (uint8_t)io_SETAN1:
case (uint8_t)io_CLRAN2:
case (uint8_t)io_SETAN2:
case (uint8_t)io_CLRAN3:
case (uint8_t)io_SETAN3:
// TODO: Simulate Attenuator
return rand(); // Apple2_64K_RAM[io_SPKR];
case (uint8_t)io_VID_RDVBL:
return (m6502.clkfrm < 4550) ? 0x80 : 0;
@ -536,43 +578,26 @@ INLINE uint8_t ioRead( uint16_t addr ) {
INLINE void ioWrite( uint16_t addr, uint8_t val ) {
// if (outdev) fprintf(outdev, "ioWrite:%04X (A:%02X)\n", addr, m6502.A);
// switch(addr) {
// case io_KBD:
// case io_KBDSTRB:
// case io_SPKR:
// break;
// default:
// printf("ioWrite:%04X (PC:%04X, val:%02X)\n", addr, m6502.PC, val);
// if ( is_io_interesting(addr) ) {
// printf("ioWrite:%04X (PC:%04X, val:%02X)\n", addr, m6502.PC, val);
// }
switch ( (uint8_t)addr ) {
// case 0x20:
case 0x21:
case 0x22:
case 0x23:
case 0x24:
case 0x25:
case 0x26:
case 0x27:
case 0x28:
case 0x29:
case 0x2A:
case 0x2B:
case 0x2C:
case 0x2D:
case 0x2E:
case 0x2F:
printf("WR TAPEIO: %04X\n", addr);
return;
case (uint8_t)io_KBDSTRB:
Apple2_64K_RAM[io_KBD] &= 0x7F;
break;
case (uint8_t)io_TAPEOUT:
// TODO: 1. Sound problem in Castle Wolfensein if we output this to speaker all the time
// 2. Implement Tape
break;
case (uint8_t)io_SPKR:
spkr_toggle();
// TODO: Theoretically it toggles the speaker twice
// m6502.clkfrm++; // to simulate RMW
// spkr_toggle();
break;
case (uint8_t)io_RDMAINRAM:
@ -614,27 +639,39 @@ INLINE void ioWrite( uint16_t addr, uint8_t val ) {
break;
case (uint8_t)io_SETSLOTCXROM:
// printf("io_SETSLOTCXROM\n");
MEMcfg.int_Cx_ROM = 0;
// TODO: set Cx00 ROM area table to SLOT
// printf("io_SETSLOTCXROM\n");
newMEMcfg = MEMcfg;
newMEMcfg.int_Cx_ROM = 0;
auxMemorySelect(newMEMcfg);
CxMemorySelect(newMEMcfg);
break;
case (uint8_t)io_SETINTCXROM:
// printf("io_SETINTCXROM\n");
MEMcfg.int_Cx_ROM = 1;
// TODO: set Cx00 ROM area table to INT
newMEMcfg = MEMcfg;
newMEMcfg.int_Cx_ROM = 1;
auxMemorySelect(newMEMcfg);
CxMemorySelect(newMEMcfg);
break;
case (uint8_t)io_SETSLOTC3ROM:
// printf("io_SETSLOTC3ROM\n");
MEMcfg.slot_C3_ROM = 1;
// TODO: set C300 ROM area table to SLOT
newMEMcfg = MEMcfg;
newMEMcfg.slot_C3_ROM = 1;
auxMemorySelect(newMEMcfg);
C3MemorySelect(newMEMcfg);
break;
case (uint8_t)io_SETINTC3ROM:
// printf("io_SETINTC3ROM\n");
MEMcfg.slot_C3_ROM = 0;
// TODO: set C300 ROM area table to INT
newMEMcfg = MEMcfg;
newMEMcfg.slot_C3_ROM = 0;
auxMemorySelect(newMEMcfg);
C3MemorySelect(newMEMcfg);
break;
case (uint8_t)io_VID_CLR80VID:
@ -1032,6 +1069,21 @@ INLINE uint8_t src_zp() {
// return memread16(addr);
//}
/**
ind .... indirect OPC ($LL)
operand is zeropage address;
effective address is word in (LL, LL + 1), inc. without carry: C.w($00LL)
**/
INLINE uint16_t addr_ind() {
dbgPrintf("zpi:%02X:%04X(%02X) ", RAM[m6502.PC], *((uint16_t*)&RAM[m6502.PC]), RAM[*((uint16_t*)&RAM[m6502.PC])]);
disPrintf(disassembly.oper, "($%02X,X)", memread8(m6502.PC) )
disPrintf(disassembly.comment, "ind_addr:%04X", memread16( memread8(m6502.PC)) );
return memread16( fetch() );
}
INLINE uint8_t src_ind() {
return memread( addr_ind() );
}
/**
X,ind .... X-indexed, indirect OPC ($LL,X)
operand is zeropage address;
@ -1069,6 +1121,7 @@ INLINE uint8_t src_ind_Y() {
// return WRLOMEM + addr_ind_Y();
//}
/**
zpg,X .... zeropage, X-indexed OPC $LL,X
operand is zeropage address;
@ -1103,7 +1156,70 @@ INLINE uint8_t src_zp_Y() {
void auxMemorySelect( MEMcfg_t newMEMcfg ) {
const uint8_t * newLowMEM = currentLowMEM;
const uint8_t * newReadMEM = currentLowRDMEM;
uint8_t * newWriteMEM = currentLowWRMEM;
if ( newMEMcfg.is_80STORE ) {
if ( newMEMcfg.RD_AUX_MEM ) {
newReadMEM = Apple2_64K_AUX + 0x200;
}
else {
newReadMEM = Apple2_64K_RAM + 0x200;
}
if ( newMEMcfg.WR_AUX_MEM ) {
newWriteMEM = Apple2_64K_AUX;
}
else {
newWriteMEM = Apple2_64K_RAM;
}
}
else {
newReadMEM = Apple2_64K_RAM + 0x200;
newWriteMEM = Apple2_64K_RAM;
}
// save old content to shadow memory
if ( ( newWriteMEM != currentLowWRMEM ) && (WRLOMEM == Apple2_64K_MEM) ) {
// save the content of Shadow Memory
memcpy( (void*) currentLowWRMEM + 0x200, WRLOMEM + 0x200, 0xBE00);
}
// else {
// // page in the new memory area
// memcpy( (void*) shadowLowMEM + 0x200, newWriteMEM + 0x200, 0xBE00);
// // mark new as the current one
// }
currentLowWRMEM = newWriteMEM;
// printf("nrm:%p nwm:%p\n", newReadMEM, newWriteMEM + 0x200);
// we are reading and writing to the same memory (either Internal or Aux)
if ( newReadMEM == newWriteMEM + 0x200 ) {
WRLOMEM = Apple2_64K_MEM;
}
else {
WRLOMEM = newWriteMEM;
}
// load new content to shadow memory
if ( newReadMEM != currentLowRDMEM ) {
// page in the new memory area
memcpy( (void*) shadowLowMEM, newReadMEM, 0xBE00);
// mark new as the current one
currentLowRDMEM = newReadMEM;
}
MEMcfg = newMEMcfg;
}
void auxMemorySelect_old( MEMcfg_t newMEMcfg ) {
const uint8_t * newLowMEM = currentLowRDMEM;
if ( newMEMcfg.is_80STORE ) {
if ( newMEMcfg.RD_AUX_MEM ) {
@ -1114,21 +1230,21 @@ void auxMemorySelect( MEMcfg_t newMEMcfg ) {
}
if ( newMEMcfg.WR_AUX_MEM ) {
if ( newMEMcfg.RD_INT_RAM ) {
if ( newMEMcfg.RD_AUX_MEM ) {
WRLOMEM = Apple2_64K_MEM;
}
else {
WRLOMEM = Apple2_64K_AUX;
}
}
else {
if ( newMEMcfg.RD_AUX_MEM ) {
WRLOMEM = Apple2_64K_AUX;
}
else {
WRLOMEM = Apple2_64K_MEM;
}
}
else {
if ( newMEMcfg.RD_INT_RAM ) {
WRLOMEM = Apple2_64K_MEM;
}
else {
WRLOMEM = Apple2_64K_RAM;
}
}
}
else {
newLowMEM = Apple2_64K_RAM + 0x200;
@ -1136,29 +1252,32 @@ void auxMemorySelect( MEMcfg_t newMEMcfg ) {
}
// load new content to shadow memory
if ( newLowMEM != currentLowMEM ) {
if ( newLowMEM != currentLowRDMEM ) {
// save the content of Shadow Memory
memcpy( (void*) currentLowMEM, shadowLowMEM, 0xBE00);
memcpy( (void*) currentLowRDMEM, shadowLowMEM, 0xBE00);
// page in the new memory area
memcpy( (void*) shadowLowMEM, newLowMEM, 0xBE00);
// mark new as the current one
currentLowMEM = newLowMEM;
currentLowRDMEM = newLowMEM;
}
MEMcfg = newMEMcfg;
}
//void (*auxMemorySelect)( MEMcfg_t newMEMcfg ) = & auxMemorySelect_new;
void C3MemorySelect( MEMcfg_t newMEMcfg ) {
if ( newMEMcfg.slot_C3_ROM ) {
// load internal ROM to memory
memcpy(Apple2_64K_MEM + 0xC300, INT_64K_ROM + 0xC300, 0x100);
}
else {
// load peripheral ROM to memory
memcpy(Apple2_64K_MEM + 0xC300, EXP_64K_ROM + 0xC300, 0x100);
}
else {
// load internal ROM to memory
memcpy(Apple2_64K_MEM + 0xC300, INT_64K_ROM + 0xC300, 0x100);
}
MEMcfg = newMEMcfg;
}

View File

@ -290,6 +290,16 @@ enum mmio {
// C R7 Status of 80/40 Column Switch
// Game Controller
io_STROBE = 0xC040,
io_CLRAN0 = 0xC058,
io_SETAN0 = 0xC059,
io_CLRAN1 = 0xC05A,
io_SETAN1 = 0xC05B,
io_CLRAN2 = 0xC05C,
io_SETAN2 = 0xC05D,
io_CLRAN3 = 0xC05E,
io_SETAN3 = 0xC05F,
io_PDL0 = 0xC064,
io_PDL1 = 0xC065,
io_PDL2 = 0xC066,
@ -363,7 +373,8 @@ enum mmio {
#define PAGES 16
extern const uint8_t * const shadowLowMEM;
extern const uint8_t * currentLowMEM;
extern const uint8_t * currentLowRDMEM;
extern uint8_t * currentLowWRMEM;
extern uint8_t activeTextAuxPage;
extern uint8_t * activeTextPage;
@ -371,6 +382,8 @@ extern uint8_t * shadowTextPage;
extern uint8_t * current_RAM_bank;
extern void auxMemorySelect( MEMcfg_t newMEMcfg );
//extern void (*auxMemorySelect)( MEMcfg_t newMEMcfg );
extern void C3MemorySelect( MEMcfg_t newMEMcfg );
extern void CxMemorySelect( MEMcfg_t newMEMcfg );
extern void resetMemory(void);
@ -408,6 +421,8 @@ INLINE uint8_t src_abs_Y(void);
INLINE uint8_t imm(void);
INLINE uint8_t addr_zp(void);
INLINE uint8_t src_zp(void);
INLINE uint16_t addr_ind(void);
INLINE uint8_t src_ind(void);
INLINE uint16_t addr_ind_X(void);
INLINE uint8_t src_X_ind(void);
INLINE uint16_t addr_ind_Y(void);

View File

@ -67,34 +67,14 @@ void printDisassembly( FILE * f ) {
// disassembly.comment
// );
// Virtual ][ Style
fprintf( f, "%llu\t%llu\t%s: %-11s%-4s%s\t0x%02X\t0x%02X\t0x%02X\t0x%02X\t0x%02X\n", // Virtual ][ style
++discnt,
disassembly.clk,
disassembly.addr,
disassembly.opcode,
disassembly.inst,
disassembly.oper,
m6502.A,
m6502.X,
m6502.Y,
getFlags2().SR,
m6502.SP
);
// static char line[256];
// // Steve ][ Style
// snprintf( line, sizeof(line), "%10llu %10llu %s: %-11s%-4s%s", // Steve ][ style
// ++discnt,
// disassembly.clk,
// disassembly.addr,
// disassembly.opcode,
// disassembly.inst,
// disassembly.oper
// );
//
// fprintf( f, "%-55s; 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X\n", // Steve ][ style
// line,
// // Virtual ][ Style
// fprintf( f, "%llu\t%llu\t%s: %-11s%-4s%s\t0x%02X\t0x%02X\t0x%02X\t0x%02X\t0x%02X\n", // Virtual ][ style
// ++discnt,
// disassembly.clk,
// disassembly.addr,
// disassembly.opcode,
// disassembly.inst,
// disassembly.oper,
// m6502.A,
// m6502.X,
// m6502.Y,
@ -102,6 +82,27 @@ void printDisassembly( FILE * f ) {
// m6502.SP
// );
static char line[256];
// Steve ][ Style
snprintf( line, sizeof(line), "%10llu %10llu %s: %-11s%-4s%s", // Steve ][ style
++discnt,
disassembly.clk,
disassembly.addr,
disassembly.opcode,
disassembly.inst,
disassembly.oper
);
fprintf( f, "%-55s; 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X ; %s\n", // Steve ][ style
line,
m6502.A,
m6502.X,
m6502.Y,
getFlags2().SR,
m6502.SP,
disassembly.comment
);
}
}