mirror of
https://github.com/trudnai/Steve2.git
synced 2024-06-01 07:41:49 +00:00
Much better sound + improved memory handling
This commit is contained in:
parent
12e458116c
commit
a97614cba7
14
.gitignore
vendored
14
.gitignore
vendored
|
@ -8,3 +8,17 @@
|
|||
# XCode debugger settings
|
||||
A2Mac.xcodeproj/xcuserdata/trudnai.xcuserdatad/xcdebugger/
|
||||
|
||||
convert_spkr_buf_to_wav.wav
|
||||
steve2_audio_debug_ema.wav
|
||||
steve2_audio_debug_raw.wav
|
||||
steve2_audio_debug.wav
|
||||
XPS_Aux_Mem_test.txt
|
||||
XPS_Aux_Mem_test.txt.dis
|
||||
Resources/rom/Downloads/Apple II ROMs.zip
|
||||
Resources/rom/Downloads/Apple II ROMs.zip
|
||||
Resources/rom/Downloads/apple_2e_unenhanced_rom.zip
|
||||
Resources/rom/Downloads/APPLE_IIe_ROM_KRK.zip
|
||||
Resources/rom/Downloads/APPLE_IIe_ROM_KRK1.zip
|
||||
Resources/rom/Downloads/APPLE_IIe_ROM_KRK2.zip
|
||||
Resources/rom/Downloads/apple_iie_rom.zip
|
||||
Resources/rom/Downloads/077-0026-0027 for IIe.zip
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -2016,21 +2016,36 @@
|
|||
<action selector="trailingEdgeSelected:" target="XfG-lQ-9wD" id="UQ6-Lt-f9t"/>
|
||||
</connections>
|
||||
</slider>
|
||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="adp-hx-NvD">
|
||||
<rect key="frame" x="-2" y="111" width="40" height="16"/>
|
||||
<textField hidden="YES" focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="adp-hx-NvD">
|
||||
<rect key="frame" x="-2" y="142" width="40" height="16"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" refusesFirstResponder="YES" focusRingType="none" alignment="right" title="WE: 4" id="M1e-h1-C5X">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<slider focusRingType="none" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="alH-N3-GYS">
|
||||
<rect key="frame" x="-2" y="79" width="92" height="24"/>
|
||||
<slider hidden="YES" focusRingType="none" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="alH-N3-GYS">
|
||||
<rect key="frame" x="-2" y="134" width="92" height="24"/>
|
||||
<sliderCell key="cell" continuous="YES" refusesFirstResponder="YES" state="on" focusRingType="none" alignment="left" maxValue="40" doubleValue="4.1025641025641022" tickMarkPosition="above" numberOfTickMarks="40" allowsTickMarkValuesOnly="YES" sliderType="linear" id="M38-l2-wW3"/>
|
||||
<connections>
|
||||
<action selector="wozExtraSelected:" target="XfG-lQ-9wD" id="jyY-27-Hdz"/>
|
||||
</connections>
|
||||
</slider>
|
||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="cUp-BM-2iO">
|
||||
<rect key="frame" x="-2" y="111" width="54" height="16"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" refusesFirstResponder="YES" focusRingType="none" alignment="right" title="EMA: 18" id="11J-tH-xLe">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<slider focusRingType="none" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="ND1-4Z-iF3">
|
||||
<rect key="frame" x="-2" y="79" width="92" height="24"/>
|
||||
<sliderCell key="cell" continuous="YES" refusesFirstResponder="YES" state="on" focusRingType="none" alignment="left" minValue="1" maxValue="41" doubleValue="18.435897435897434" tickMarkPosition="above" numberOfTickMarks="40" allowsTickMarkValuesOnly="YES" sliderType="linear" id="WQL-gS-1BT"/>
|
||||
<connections>
|
||||
<action selector="EMASelected:" target="XfG-lQ-9wD" id="dhd-xf-5TT"/>
|
||||
</connections>
|
||||
</slider>
|
||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="FFM-zm-Wjx">
|
||||
<rect key="frame" x="-2" y="57" width="13" height="16"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" refusesFirstResponder="YES" focusRingType="none" alignment="right" title="0" id="yIR-MN-Hdl">
|
||||
|
@ -2078,6 +2093,8 @@
|
|||
<integer value="1000"/>
|
||||
<integer value="1000"/>
|
||||
<integer value="1000"/>
|
||||
<integer value="1000"/>
|
||||
<integer value="1000"/>
|
||||
</visibilityPriorities>
|
||||
<customSpacing>
|
||||
<real value="3.4028234663852886e+38"/>
|
||||
|
@ -2096,6 +2113,8 @@
|
|||
<real value="3.4028234663852886e+38"/>
|
||||
<real value="3.4028234663852886e+38"/>
|
||||
<real value="3.4028234663852886e+38"/>
|
||||
<real value="3.4028234663852886e+38"/>
|
||||
<real value="3.4028234663852886e+38"/>
|
||||
</customSpacing>
|
||||
</stackView>
|
||||
</subviews>
|
||||
|
@ -2152,6 +2171,7 @@
|
|||
<connections>
|
||||
<outlet property="DiskSound_Disk1" destination="5cI-3C-PMM" id="ptG-tm-GZs"/>
|
||||
<outlet property="DiskSound_Disk2" destination="vmR-CG-qdv" id="22u-xi-nHH"/>
|
||||
<outlet property="EMALabel" destination="11J-tH-xLe" id="BHX-Gf-xsl"/>
|
||||
<outlet property="QuickDisk_Disk1" destination="cth-H6-Drg" id="cFI-9E-kYv"/>
|
||||
<outlet property="QuickDisk_Disk2" destination="yDH-Ob-i3N" id="hvi-ZC-Pk4"/>
|
||||
<outlet property="hires" destination="LlM-EV-ruZ" id="E60-pA-HM1"/>
|
||||
|
|
|
@ -1318,6 +1318,13 @@ class ViewController: NSViewController {
|
|||
}
|
||||
|
||||
|
||||
@IBOutlet weak var EMALabel: NSTextFieldCell!
|
||||
@IBAction func EMASelected(_ sender: NSSlider) {
|
||||
spkr_ema_len = Int32(sender.floatValue)
|
||||
EMALabel.title = "EMA: " + String( spkr_ema_len )
|
||||
}
|
||||
|
||||
|
||||
func setSimulationMode( mode : String ) {
|
||||
switch ( mode ) {
|
||||
case "Eco":
|
||||
|
|
291
A2iOS/src/cpu/instructions/6502_instr_branch.h
Normal file
291
A2iOS/src/cpu/instructions/6502_instr_branch.h
Normal file
|
@ -0,0 +1,291 @@
|
|||
//
|
||||
// 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_BRANCH_H__
|
||||
#define __6502_INSTR_BRANCH_H__
|
||||
|
||||
INLINE void BRA( int8_t reladdr ) {
|
||||
m6502.PC += reladdr;
|
||||
//#ifdef CLK_ABSOLUTE_PRECISE
|
||||
uint8_t pg = m6502.PC >> 8;
|
||||
m6502.clkfrm += m6502.PC >> 8 == pg ? 1 : 2;
|
||||
|
||||
// if ( m6502.PC >> 8 != pg ) {
|
||||
// m6502.clkfrm += 1;
|
||||
// }
|
||||
//#else
|
||||
// m6502.clktime++;
|
||||
//#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
if ( reladdr == -2 ) {
|
||||
dbgPrintf2("Infinite Loop at %04X!\n", m6502.PC);
|
||||
}
|
||||
#endif
|
||||
dbgPrintf("BRA %04X ", m6502.PC);
|
||||
}
|
||||
|
||||
/**
|
||||
BCC Branch on Carry Clear
|
||||
|
||||
branch on C = 0 N Z C I D V
|
||||
- - - - - -
|
||||
|
||||
addressing assembler opc bytes cyles
|
||||
--------------------------------------------
|
||||
relative BCC oper 90 2 2**
|
||||
**/
|
||||
INLINE void BCC( int8_t reladdr ) {
|
||||
dbgPrintf("BCC ");
|
||||
disPrintf(disassembly.inst, "BCC");
|
||||
if ( ! m6502.C ) {
|
||||
BRA( reladdr );
|
||||
}
|
||||
else {
|
||||
dbgPrintf("-no-");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
BCS Branch on Carry Set
|
||||
|
||||
branch on C = 1 N Z C I D V
|
||||
- - - - - -
|
||||
|
||||
addressing assembler opc bytes cyles
|
||||
--------------------------------------------
|
||||
relative BCS oper B0 2 2**
|
||||
**/
|
||||
INLINE void BCS( int8_t reladdr ) {
|
||||
dbgPrintf("BCS ");
|
||||
disPrintf(disassembly.inst, "BCS");
|
||||
if ( m6502.C ) {
|
||||
BRA( reladdr );
|
||||
}
|
||||
else {
|
||||
dbgPrintf("-no-");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
BNE Branch on Result not Zero
|
||||
|
||||
branch on Z = 0 N Z C I D V
|
||||
- - - - - -
|
||||
|
||||
addressing assembler opc bytes cyles
|
||||
--------------------------------------------
|
||||
relative BNE oper D0 2 2**
|
||||
**/
|
||||
INLINE void BNE( int8_t reladdr ) {
|
||||
dbgPrintf("BNE ");
|
||||
disPrintf(disassembly.inst, "BNE");
|
||||
if ( ! m6502.Z ) {
|
||||
BRA( reladdr );
|
||||
}
|
||||
else {
|
||||
dbgPrintf("-no-");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
BEQ Branch on Result Zero
|
||||
|
||||
branch on Z = 1 N Z C I D V
|
||||
- - - - - -
|
||||
|
||||
addressing assembler opc bytes cyles
|
||||
--------------------------------------------
|
||||
relative BEQ oper F0 2 2**
|
||||
**/
|
||||
INLINE void BEQ( int8_t reladdr ) {
|
||||
dbgPrintf("BEQ ");
|
||||
disPrintf(disassembly.inst, "BEQ");
|
||||
if ( m6502.Z ) {
|
||||
BRA( reladdr );
|
||||
}
|
||||
else {
|
||||
dbgPrintf("-no-");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
BPL Branch on Result Plus
|
||||
|
||||
branch on N = 0 N Z C I D V
|
||||
- - - - - -
|
||||
|
||||
addressing assembler opc bytes cyles
|
||||
--------------------------------------------
|
||||
relative BPL oper 10 2 2**
|
||||
**/
|
||||
INLINE void BPL( int8_t reladdr ) {
|
||||
dbgPrintf("BPL ");
|
||||
disPrintf(disassembly.inst, "BPL");
|
||||
if ( ! m6502.N ) {
|
||||
BRA( reladdr );
|
||||
}
|
||||
else {
|
||||
dbgPrintf("-no-");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
BMI Branch on Result Minus
|
||||
|
||||
branch on N = 1 N Z C I D V
|
||||
- - - - - -
|
||||
|
||||
addressing assembler opc bytes cyles
|
||||
--------------------------------------------
|
||||
relative BMI oper 30 2 2**
|
||||
**/
|
||||
INLINE void BMI( int8_t reladdr ) {
|
||||
dbgPrintf("BMI ");
|
||||
disPrintf(disassembly.inst, "BMI");
|
||||
if ( m6502.N ) {
|
||||
BRA( reladdr );
|
||||
}
|
||||
else {
|
||||
dbgPrintf("-no-");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
BVC Branch on Overflow Clear
|
||||
|
||||
branch on V = 0 N Z C I D V
|
||||
- - - - - -
|
||||
|
||||
addressing assembler opc bytes cyles
|
||||
--------------------------------------------
|
||||
relative BVC oper 50 2 2**
|
||||
**/
|
||||
INLINE void BVC( int8_t reladdr ) {
|
||||
dbgPrintf("BVC ");
|
||||
disPrintf(disassembly.inst, "BVC");
|
||||
if ( ! m6502.V ) {
|
||||
BRA( reladdr );
|
||||
}
|
||||
else {
|
||||
dbgPrintf("-no-");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
BVS Branch on Overflow Set
|
||||
|
||||
branch on V = 1 N Z C I D V
|
||||
- - - - - -
|
||||
|
||||
addressing assembler opc bytes cyles
|
||||
--------------------------------------------
|
||||
relative BVC oper 70 2 2**
|
||||
**/
|
||||
INLINE void BVS( int8_t reladdr ) {
|
||||
dbgPrintf("BVS ");
|
||||
disPrintf(disassembly.inst, "BVS");
|
||||
if ( m6502.V ) {
|
||||
BRA( reladdr );
|
||||
}
|
||||
else {
|
||||
dbgPrintf("-no-");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
BBR BBS - Branch on Bit Reset or Set
|
||||
|
||||
BBR and BBS test the specified zero page location and branch if the specified bit is clear (BBR) or set (BBS).
|
||||
Note that as with TRB, the term reset in BBR is used to mean clear.
|
||||
|
||||
On the 6502 and 65C02, bit 7 is typically the most convenient bit to use for I/O and software flags because
|
||||
it can be tested by several instructions, such as BIT and LDA. BBR and BBS can test any of the 8 bits without
|
||||
affecting any flags or using any registers. Unlike other branch instructions, BBR and BBS always take the same
|
||||
number of cycles (five) whether the branch is taken or not. It is often useful to test bit 0, for example, to test
|
||||
whether a byte is even or odd. However, the usefulness of BBR and BBS is somewhat limited for a couple of reasons.
|
||||
First, there is only a single addressing mode for these instructions -- no indexing by X or Y, for instance.
|
||||
Second, they are restricted to zero page locations. For software flags this may be just fine, but it may not be very
|
||||
convenient (or cost effective) to add any additional address decoding hardware that may be necessary to
|
||||
map I/O locations to the zero page.
|
||||
|
||||
The addressing mode is a combination of zero page addressing and relative addressing -- really just a juxtaposition of the two.
|
||||
The bit to test is typically specified as part of the instruction name rather than the operand, i.e.
|
||||
|
||||
Flags affected: none
|
||||
|
||||
OP LEN CYC MODE FLAGS SYNTAX
|
||||
-- --- --- ---- ----- ------
|
||||
0F 3 5 zp,rel ........ BBR0 $12,LABEL
|
||||
1F 3 5 zp,rel ........ BBR1 $12,LABEL
|
||||
2F 3 5 zp,rel ........ BBR2 $12,LABEL
|
||||
3F 3 5 zp,rel ........ BBR3 $12,LABEL
|
||||
4F 3 5 zp,rel ........ BBR4 $12,LABEL
|
||||
5F 3 5 zp,rel ........ BBR5 $12,LABEL
|
||||
6F 3 5 zp,rel ........ BBR6 $12,LABEL
|
||||
7F 3 5 zp,rel ........ BBR7 $12,LABEL
|
||||
8F 3 5 zp,rel ........ BBS0 $12,LABEL
|
||||
9F 3 5 zp,rel ........ BBS1 $12,LABEL
|
||||
AF 3 5 zp,rel ........ BBS2 $12,LABEL
|
||||
BF 3 5 zp,rel ........ BBS3 $12,LABEL
|
||||
CF 3 5 zp,rel ........ BBS4 $12,LABEL
|
||||
DF 3 5 zp,rel ........ BBS5 $12,LABEL
|
||||
EF 3 5 zp,rel ........ BBS6 $12,LABEL
|
||||
FF 3 5 zp,rel ........ BBS7 $12,LABEL
|
||||
|
||||
**/
|
||||
#define BBR(n) INLINE void BBR##n( uint8_t src, int8_t reladdr ) { \
|
||||
dbgPrintf("BBR"#n" "); \
|
||||
disPrintf(disassembly.inst, "BBR"#n); \
|
||||
if ( ! (src & (1 << n) ) ) { \
|
||||
BRA( reladdr ); \
|
||||
} \
|
||||
}
|
||||
|
||||
BBR(0)
|
||||
BBR(1)
|
||||
BBR(2)
|
||||
BBR(3)
|
||||
BBR(4)
|
||||
BBR(5)
|
||||
BBR(6)
|
||||
BBR(7)
|
||||
|
||||
#define BBS(n) INLINE void BBS##n( uint8_t src, int8_t reladdr ) { \
|
||||
dbgPrintf("BBS"#n" "); \
|
||||
disPrintf(disassembly.inst, "BBS"#n); \
|
||||
if ( (src & (1 << n) ) ) { \
|
||||
BRA( reladdr ); \
|
||||
} \
|
||||
}
|
||||
|
||||
BBS(0)
|
||||
BBS(1)
|
||||
BBS(2)
|
||||
BBS(3)
|
||||
BBS(4)
|
||||
BBS(5)
|
||||
BBS(6)
|
||||
BBS(7)
|
||||
|
||||
#endif // __6502_INSTR_BRANCH_H__
|
|
@ -153,6 +153,8 @@ typedef struct MEMcfg_s {
|
|||
unsigned RD_AUX_MEM : 1;
|
||||
unsigned WR_AUX_MEM : 1;
|
||||
unsigned ALT_ZP : 1;
|
||||
|
||||
unsigned WR_RAM_cntr; // min 2 I/O to enable mem write
|
||||
} MEMcfg_t;
|
||||
|
||||
|
||||
|
|
|
@ -41,12 +41,12 @@
|
|||
#define CASE_RETURN(err) case (err): return #err
|
||||
const char* al_err_str(ALenum err) {
|
||||
switch(err) {
|
||||
CASE_RETURN(AL_NO_ERROR);
|
||||
CASE_RETURN(AL_INVALID_NAME);
|
||||
CASE_RETURN(AL_INVALID_ENUM);
|
||||
CASE_RETURN(AL_INVALID_VALUE);
|
||||
CASE_RETURN(AL_INVALID_OPERATION);
|
||||
CASE_RETURN(AL_OUT_OF_MEMORY);
|
||||
CASE_RETURN(AL_NO_ERROR);
|
||||
CASE_RETURN(AL_INVALID_NAME);
|
||||
CASE_RETURN(AL_INVALID_ENUM);
|
||||
CASE_RETURN(AL_INVALID_VALUE);
|
||||
CASE_RETURN(AL_INVALID_OPERATION);
|
||||
CASE_RETURN(AL_OUT_OF_MEMORY);
|
||||
}
|
||||
printf("alError: 0x%04X\n", err);
|
||||
return "AL_UNKNOWN_ERROR";
|
||||
|
@ -55,13 +55,22 @@ const char* al_err_str(ALenum err) {
|
|||
|
||||
#define __al_check_error(file,line) \
|
||||
for( ALenum err = alGetError(); err != AL_NO_ERROR; err = alGetError() ) { \
|
||||
printf( "AL Error %s at %s:%d\n", al_err_str(err), file, line ); \
|
||||
printf( "AL Error %s at %s:%d\n", al_err_str(err), file, line ); \
|
||||
}
|
||||
|
||||
#define al_check_error() \
|
||||
__al_check_error(__FILE__, __LINE__)
|
||||
|
||||
|
||||
#define __al_check_error2(file,line,src) \
|
||||
for( ALenum err = alGetError(); err != AL_NO_ERROR; err = alGetError() ) { \
|
||||
printf( "AL Error %s at %s:%d (%u)\n", al_err_str(err), file, line, src ); \
|
||||
}
|
||||
|
||||
#define al_check_error2(src) \
|
||||
__al_check_error2(__FILE__, __LINE__, src)
|
||||
|
||||
|
||||
ALCdevice *dev = NULL;
|
||||
ALCcontext *ctx = NULL;
|
||||
|
||||
|
@ -74,6 +83,15 @@ int spkr_level_dema = SPKR_LEVEL_ZERO;
|
|||
int spkr_level_tema = SPKR_LEVEL_ZERO;
|
||||
int spkr_last_level = SPKR_LEVEL_ZERO;
|
||||
|
||||
|
||||
static const int ema_len_sharper = 7;
|
||||
static const int ema_len_sharp = 14;
|
||||
static const int ema_len_normal = 18;
|
||||
static const int ema_len_soft = 20;
|
||||
static const int ema_len_supersoft = 40;
|
||||
|
||||
int spkr_ema_len = ema_len_normal;
|
||||
|
||||
#define BUFFER_COUNT 256
|
||||
#define SPKR_CHANNELS 2
|
||||
|
||||
|
@ -93,6 +111,8 @@ unsigned spkr_fps_divider = 1;
|
|||
unsigned spkr_frame_cntr = 0;
|
||||
unsigned spkr_clk = 0;
|
||||
|
||||
#define SPKR_BUF_SLOT(n) ( spkr_buf_size * DEFAULT_FPS * (n) )
|
||||
|
||||
const unsigned spkr_seconds = 1;
|
||||
const unsigned spkr_sample_rate = 192000;
|
||||
const unsigned sfx_sample_rate = 22050; // original sample rate
|
||||
|
@ -101,7 +121,7 @@ int spkr_extra_buf = 0; // 26; // 800 / spkr_fps;
|
|||
typedef int16_t spkr_sample_t;
|
||||
const unsigned spkr_buf_size = spkr_seconds * spkr_sample_rate * SPKR_CHANNELS / DEFAULT_FPS; // stereo
|
||||
const unsigned spkr_buf_alloc_size = spkr_buf_size * sizeof(spkr_sample_t);
|
||||
const unsigned sample_buf_array_len = spkr_buf_size * DEFAULT_FPS * BUFFER_COUNT;
|
||||
const unsigned sample_buf_array_len = SPKR_BUF_SLOT(BUFFER_COUNT);
|
||||
spkr_sample_t spkr_samples [ sample_buf_array_len ]; // can store up to 1 sec of sound
|
||||
unsigned spkr_sample_idx = 0;
|
||||
unsigned spkr_sample_last_idx = 0;
|
||||
|
@ -369,7 +389,9 @@ int spkr_unqueue( ALuint src ) {
|
|||
|
||||
if ( src ) {
|
||||
alGetSourcei ( src, AL_BUFFERS_PROCESSED, &processed );
|
||||
al_check_error();
|
||||
// al_check_error();
|
||||
al_check_error2(src);
|
||||
|
||||
// printf("%s alGetSourcei(%d)\n", __FUNCTION__, src);
|
||||
// printf("p:%d\n", processed);
|
||||
|
||||
|
@ -567,18 +589,18 @@ INLINE static void spkr_filter(int buf_len) {
|
|||
// 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 = 18;
|
||||
static const int ema_len_soft = 20;
|
||||
static const int ema_len_supersoft = 40;
|
||||
|
||||
static const int ema_len = ema_len_normal;
|
||||
// static const int ema_len_sharper = 7;
|
||||
// static const int ema_len_sharp = 14;
|
||||
// static const int ema_len_normal = 18;
|
||||
// static const int ema_len_soft = 20;
|
||||
// static const int ema_len_supersoft = 40;
|
||||
//
|
||||
// static const int ema_len = ema_len_soft;
|
||||
|
||||
for ( int i = 0; 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);
|
||||
spkr_level_ema = ema(spkr_samples[i], spkr_level_ema, spkr_ema_len);
|
||||
spkr_level_dema = ema(spkr_level_ema, spkr_level_dema, spkr_ema_len);
|
||||
spkr_level_tema = ema(spkr_level_dema, spkr_level_tema, spkr_ema_len);
|
||||
|
||||
// smoothing with Tripple EMA
|
||||
spkr_samples[i++] = spkr_level_tema;
|
||||
|
@ -601,6 +623,27 @@ INLINE void spkr_debug_spike() {
|
|||
}
|
||||
|
||||
|
||||
void spkr_play() {
|
||||
ALenum state;
|
||||
alGetSourcei( spkr_src[SPKR_SRC_GAME_SFX], AL_SOURCE_STATE, &state );
|
||||
// al_check_error();
|
||||
|
||||
switch (state) {
|
||||
case AL_PLAYING:
|
||||
// already playing, no need to do anything
|
||||
break;
|
||||
|
||||
case AL_INITIAL:
|
||||
case AL_STOPPED:
|
||||
case AL_PAUSED:
|
||||
default:
|
||||
// no we can play this empty buffer first and then later on the real one
|
||||
alSourcePlay(spkr_src[SPKR_SRC_GAME_SFX]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void spkr_play_with_prebuf() {
|
||||
ALenum state;
|
||||
alGetSourcei( spkr_src[SPKR_SRC_GAME_SFX], AL_SOURCE_STATE, &state );
|
||||
|
@ -652,6 +695,7 @@ void spkr_play_with_pause() {
|
|||
switch (state) {
|
||||
case AL_PAUSED:
|
||||
if ( --playDelay < 0 ) {
|
||||
printf("spkr_play_with_pause: PLAY\n");
|
||||
alSourcePlay(spkr_src[SPKR_SRC_GAME_SFX]);
|
||||
playDelay = SPKR_PLAY_DELAY;
|
||||
}
|
||||
|
@ -664,6 +708,7 @@ void spkr_play_with_pause() {
|
|||
case AL_INITIAL:
|
||||
case AL_STOPPED:
|
||||
default:
|
||||
printf("spkr_play_with_pause: PLAY-DELAY\n");
|
||||
alSourcePlay(spkr_src[SPKR_SRC_GAME_SFX]);
|
||||
// this is so we will set state to AL_PAUSED immediately
|
||||
// As a result there will be an extra queued buffer
|
||||
|
@ -675,6 +720,41 @@ void spkr_play_with_pause() {
|
|||
}
|
||||
|
||||
|
||||
void spkr_buffer_with_pause(int buf_len) {
|
||||
ALenum state;
|
||||
alGetSourcei( spkr_src[SPKR_SRC_GAME_SFX], AL_SOURCE_STATE, &state );
|
||||
// al_check_error();
|
||||
|
||||
switch (state) {
|
||||
case AL_PAUSED:
|
||||
case AL_PLAYING:
|
||||
// already playing
|
||||
break;
|
||||
|
||||
case AL_INITIAL:
|
||||
case AL_STOPPED:
|
||||
default:
|
||||
alBufferData(spkr_buffers[freeBuffers], AL_FORMAT_STEREO16, spkr_samples + SPKR_BUF_SLOT(BUFFER_COUNT - 2), buf_len * 2, spkr_sample_rate);
|
||||
al_check_error();
|
||||
alSourceQueueBuffers(spkr_src[SPKR_SRC_GAME_SFX], 1, &spkr_buffers[freeBuffers]);
|
||||
al_check_error();
|
||||
|
||||
if (--freeBuffers < 0) {
|
||||
printf("freeBuffer < 0 (%i)\n", freeBuffers);
|
||||
freeBuffers = 0;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
alBufferData(spkr_buffers[freeBuffers], AL_FORMAT_STEREO16, spkr_samples, buf_len, spkr_sample_rate);
|
||||
al_check_error();
|
||||
alSourceQueueBuffers(spkr_src[SPKR_SRC_GAME_SFX], 1, &spkr_buffers[freeBuffers]);
|
||||
al_check_error();
|
||||
|
||||
}
|
||||
|
||||
|
||||
void spkr_update() {
|
||||
if ( ++spkr_frame_cntr >= spkr_fps_divider ) {
|
||||
spkr_frame_cntr = 0;
|
||||
|
@ -688,7 +768,7 @@ void spkr_update() {
|
|||
// printf("q:%d clkfrm:%d frm:%llu max:%llu\n", queued, clkfrm, clk_6502_per_frm, clk_6502_per_frm_max);
|
||||
|
||||
if ( queued < SPKR_MAX_QUEUED ) {
|
||||
if ( spkr_play_time ) {
|
||||
if ( spkr_play_time > 0) {
|
||||
if ( freeBuffers ) {
|
||||
// double multiplier = 1;
|
||||
// #ifdef SPKR_KEEP_PITCH
|
||||
|
@ -698,7 +778,7 @@ void spkr_update() {
|
|||
// #endif
|
||||
|
||||
// in Game Mode do not fade out and stop playing
|
||||
if ( /*( cpuMode_game != cpuMode ) && */( --spkr_play_time == 0 ) ) {
|
||||
if ( /*( cpuMode_game != cpuMode ) && */( --spkr_play_time == SPKR_PLAY_QUIET ) ) {
|
||||
|
||||
if (--freeBuffers < 0) {
|
||||
printf("freeBuffer < 0 (%i)\n", freeBuffers);
|
||||
|
@ -743,8 +823,8 @@ void spkr_update() {
|
|||
// //spkr_samples[sample_idx] = spkr_level;
|
||||
// memset(spkr_samples + spkr_sample_idx, spkr_level, spkr_buf_alloc_size * DEFAULT_FPS - spkr_sample_idx);
|
||||
|
||||
spkr_play_with_prebuf();
|
||||
|
||||
// spkr_play_with_prebuf();
|
||||
|
||||
if (--freeBuffers < 0) {
|
||||
printf("freeBuffer < 0 (%i)\n", freeBuffers);
|
||||
freeBuffers = 0;
|
||||
|
@ -763,13 +843,11 @@ void spkr_update() {
|
|||
// digital filtering the audio stream -- most notably smoothing
|
||||
spkr_filter(buf_len);
|
||||
|
||||
alBufferData(spkr_buffers[freeBuffers], AL_FORMAT_STEREO16, spkr_samples, buf_len, spkr_sample_rate);
|
||||
al_check_error();
|
||||
alSourceQueueBuffers(spkr_src[SPKR_SRC_GAME_SFX], 1, &spkr_buffers[freeBuffers]);
|
||||
al_check_error();
|
||||
spkr_buffer_with_pause(buf_len);
|
||||
}
|
||||
}
|
||||
|
||||
spkr_play();
|
||||
// spkr_play_with_pause();
|
||||
|
||||
// int dst = 0;
|
||||
|
@ -785,6 +863,11 @@ void spkr_update() {
|
|||
spkr_sample_idx = 0;
|
||||
spkr_sample_last_idx = 0;
|
||||
|
||||
// make sure it never goes below 0 (never overflows)
|
||||
if ( (int)spkr_play_time < 0 ) {
|
||||
spkr_play_time = 0;
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
printf("Warning: No FreeBuffers!\n");
|
||||
|
|
|
@ -44,6 +44,8 @@
|
|||
#define SPKR_LEVEL_MAX 32767 // 8192
|
||||
#define SPKR_LEVEL_MIN (-SPKR_LEVEL_MAX)
|
||||
#define SPKR_PLAY_TIMEOUT 8U
|
||||
#define SPKR_PLAY_QUIET 0
|
||||
//#define SPKR_PLAY_QUIET (SPKR_PLAY_TIMEOUT - 2)
|
||||
|
||||
// quiet
|
||||
//#define SPKR_LEVEL_MIN (-1000)
|
||||
|
@ -60,6 +62,8 @@ extern float SPKR_FADE_TRAILING_EDGE;
|
|||
extern float SPKR_INITIAL_LEADING_EDGE; // leading edge should be pretty steep to get sharp sound plus to avoid Wavy Navy high pitch sound
|
||||
extern float SPKR_INITIAL_TRAILING_EDGE; // need a bit of slope to get Xonix sound good
|
||||
|
||||
extern int spkr_ema_len;
|
||||
|
||||
|
||||
#define SPKR_SAMPLE_PWM_THRESHOLD 32 // to detect PWM controlled speaker control like in Wavy Navy or Xonix
|
||||
|
||||
|
|
|
@ -88,9 +88,10 @@ uint8_t * currentLowWRMEM = Apple2_64K_RAM;
|
|||
|
||||
/// No writing (Readonly), and mark it as NO need to commit from Shadow RAM
|
||||
INLINE void set_MEM_readonly() {
|
||||
printf("NOWR_AUX\n");
|
||||
printf("NOWR_AUX (pc:$%04X)\n", m6502.PC);
|
||||
|
||||
MEMcfg.WR_RAM = 0;
|
||||
MEMcfg.WR_RAM_cntr = 0;
|
||||
WRD0MEM = Apple2_Dummy_RAM; // for Discarding any writes to $D000 - $DFFF - BANK X
|
||||
WRHIMEM = Apple2_Dummy_RAM; // for Discarding any writes to $E000 - $FFFF
|
||||
}
|
||||
|
@ -99,11 +100,13 @@ 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);
|
||||
|
||||
// uint64_t elapsed = clk - m6502.clk_wrenable;
|
||||
// int is_enabled = ( elapsed < 16 ) || MEMcfg.WR_RAM;
|
||||
int is_enabled = ++MEMcfg.WR_RAM_cntr >= 1 || MEMcfg.WR_RAM;
|
||||
|
||||
// printf("is_wr_enabled elapsed:%llu was_enabled:%i to_be_enabled:%i\n", elapsed, MEMcfg.WR_RAM, is_enabled);
|
||||
printf("is_wr_enabled WR_RAM_cntr:%u was_enabled:%i to_be_enabled:%i\n", MEMcfg.WR_RAM_cntr, MEMcfg.WR_RAM, is_enabled);
|
||||
|
||||
m6502.clk_wrenable = clk;
|
||||
return is_enabled;
|
||||
}
|
||||
|
@ -115,7 +118,7 @@ INLINE void set_AUX_read_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 ( is_wr_enabled() ) {
|
||||
printf("WR_MEM\n");
|
||||
printf("WR_MEM (pc:$%04X)\n", m6502.PC);
|
||||
|
||||
// will write to Shadow RAM, and mark it as need to commit from Shadow RAM
|
||||
MEMcfg.WR_RAM = 1;
|
||||
|
@ -131,7 +134,7 @@ 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 ( is_wr_enabled() ) {
|
||||
printf("WR_AUX\n");
|
||||
printf("WR_AUX (pc:$%04X)\n", m6502.PC);
|
||||
|
||||
MEMcfg.WR_RAM = 1;
|
||||
if ( MEMcfg.RAM_BANK_2 ) {
|
||||
|
@ -148,8 +151,10 @@ INLINE void set_AUX_write() {
|
|||
// save the content of Shadow Memory in needed
|
||||
INLINE void save_AUX() {
|
||||
if ( MEMcfg.WR_RAM && MEMcfg.RD_INT_RAM ) {
|
||||
// printf("Saving RAM Bank %d to %p\n", MEMcfg.RAM_BANK_2 + 1, current_RAM_bank);
|
||||
printf("Saving RAM Bank %d to %d (pc:$%04X)\n", MEMcfg.RAM_BANK_2 + 1, (current_RAM_bank == Apple2_64K_AUX + 0xD000) + 1, m6502.PC);
|
||||
// save LC Bank 1 or 2
|
||||
memcpy(current_RAM_bank, Apple2_64K_MEM + 0xD000, 0x1000);
|
||||
// save rest of LC RAM
|
||||
memcpy(Apple2_64K_AUX + 0xE000, Apple2_64K_MEM + 0xE000, 0x2000);
|
||||
}
|
||||
}
|
||||
|
@ -168,14 +173,14 @@ INLINE void select_RAM_BANK( uint16_t addr ) {
|
|||
case (uint8_t)io_MEM_RDROM_NOWR_2_:
|
||||
case (uint8_t)io_MEM_RDRAM_WRAM_2_:
|
||||
|
||||
printf("RAM_BANK_2\n");
|
||||
printf("RAM_BANK_2 (pc:$%04X)\n", m6502.PC);
|
||||
|
||||
MEMcfg.RAM_BANK_2 = 1;
|
||||
current_RAM_bank = Apple2_64K_AUX + 0xD000;
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("RAM_BANK_1\n");
|
||||
printf("RAM_BANK_1 (pc:$%04X)\n", m6502.PC);
|
||||
|
||||
MEMcfg.RAM_BANK_2 = 0;
|
||||
current_RAM_bank = Apple2_64K_AUX + 0xC000;
|
||||
|
@ -197,7 +202,7 @@ INLINE void read_RAM_or_ROM( uint16_t addr ) {
|
|||
case (uint8_t)io_MEM_RDRAM_NOWR_1_:
|
||||
case (uint8_t)io_MEM_RDRAM_WRAM_1_:
|
||||
|
||||
printf("RD_RAM\n");
|
||||
printf("RD_RAM (pc:$%04X)\n", m6502.PC);
|
||||
|
||||
MEMcfg.RD_INT_RAM = 1;
|
||||
|
||||
|
@ -209,7 +214,7 @@ INLINE void read_RAM_or_ROM( uint16_t addr ) {
|
|||
break;
|
||||
|
||||
default:
|
||||
printf("RD_ROM\n");
|
||||
printf("RD_ROM (pc:$%04X)\n", m6502.PC);
|
||||
|
||||
MEMcfg.RD_INT_RAM = 0;
|
||||
|
||||
|
@ -232,7 +237,7 @@ INLINE void write_RAM_or_NOT( uint16_t addr ) {
|
|||
case (uint8_t)io_MEM_RDROM_WRAM_2_:
|
||||
case (uint8_t)io_MEM_RDROM_WRAM_1_:
|
||||
|
||||
printf("RD_ROM + WR_AUX\n");
|
||||
printf("RD_ROM + WR_AUX (pc:$%04X)\n", m6502.PC);
|
||||
|
||||
set_AUX_write();
|
||||
|
||||
|
@ -244,14 +249,14 @@ INLINE void write_RAM_or_NOT( uint16_t addr ) {
|
|||
case (uint8_t)io_MEM_RDRAM_WRAM_2_:
|
||||
case (uint8_t)io_MEM_RDRAM_WRAM_1_:
|
||||
|
||||
printf("RD_RAM + WR_RAM\n");
|
||||
printf("RD_RAM + WR_RAM (pc:$%04X)\n", m6502.PC);
|
||||
|
||||
set_AUX_read_write();
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("RD_ROM + NO_WR\n");
|
||||
printf("NO_WR (pc:$%04X)\n", m6502.PC);
|
||||
|
||||
set_MEM_readonly();
|
||||
|
||||
|
@ -275,7 +280,7 @@ INLINE void io_RAM_EXP( uint16_t addr ) {
|
|||
}
|
||||
|
||||
|
||||
INLINE int is_io_interesting(addr) {
|
||||
INLINE int is_io_interesting( uint16_t addr ) {
|
||||
switch(addr) {
|
||||
case io_KBD:
|
||||
case io_KBDSTRB:
|
||||
|
@ -354,13 +359,12 @@ 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
|
||||
// TODO: 1. Implement Tape
|
||||
return rand(); // Floating I/O -- used for random number generation in Games
|
||||
|
||||
case (uint8_t)io_SPKR:
|
||||
spkr_toggle();
|
||||
return rand(); // Floating I/O -- used for random number genet=ration in Games
|
||||
return rand(); // Floating I/O -- used for random number generation in Games
|
||||
|
||||
case (uint8_t)io_STROBE:
|
||||
case (uint8_t)io_CLRAN0:
|
||||
|
@ -375,7 +379,7 @@ INLINE uint8_t ioRead( uint16_t addr ) {
|
|||
return rand(); // Apple2_64K_RAM[io_SPKR];
|
||||
|
||||
case (uint8_t)io_VID_RDVBL:
|
||||
return (m6502.clkfrm < 4550) ? 0x80 : 0;
|
||||
return (m6502.clkfrm > 4550) ? 0x80 : 0;
|
||||
|
||||
case (uint8_t)io_VID_RDTEXT:
|
||||
return videoMode.text << 7;
|
||||
|
@ -463,35 +467,35 @@ INLINE uint8_t ioRead( uint16_t addr ) {
|
|||
case (uint8_t)io_PDL1:
|
||||
case (uint8_t)io_PDL2:
|
||||
case (uint8_t)io_PDL3:
|
||||
// printf("PDL%d: %d\n", addr - io_PDL0, pdl_read( addr - io_PDL0 ));
|
||||
// printf("PDL%d: %d\n", addr - io_PDL0, pdl_read( addr - io_PDL0 ));
|
||||
return pdl_read( addr - io_PDL0 );
|
||||
|
||||
case (uint8_t)io_PDL_STROBE:
|
||||
return pdl_reset();
|
||||
|
||||
case (uint8_t)io_RDMAINRAM:
|
||||
// printf("io_RDMAINRAM\n");
|
||||
printf("R:io_RDMAINRAM (pc:$%04X)\n", m6502.PC);
|
||||
newMEMcfg = MEMcfg;
|
||||
newMEMcfg.RD_AUX_MEM = 0;
|
||||
auxMemorySelect(newMEMcfg);
|
||||
break;
|
||||
|
||||
case (uint8_t)io_RDCARDRAM:
|
||||
// printf("io_RDCARDRAM\n");
|
||||
printf("R:io_RDCARDRAM (pc:$%04X)\n", m6502.PC);
|
||||
newMEMcfg = MEMcfg;
|
||||
newMEMcfg.RD_AUX_MEM = 1;
|
||||
auxMemorySelect(newMEMcfg);
|
||||
break;
|
||||
|
||||
case (uint8_t)io_WRMAINRAM:
|
||||
// printf("io_WRMAINRAM\n");
|
||||
printf("R:io_WRMAINRAM (pc:$%04X)\n", m6502.PC);
|
||||
newMEMcfg = MEMcfg;
|
||||
newMEMcfg.WR_AUX_MEM = 0;
|
||||
auxMemorySelect(newMEMcfg);
|
||||
break;
|
||||
|
||||
case (uint8_t)io_WRCARDRAM:
|
||||
// printf("io_WRCARDRAM\n");
|
||||
printf("R:io_WRCARDRAM (pc:$%04X)\n", m6502.PC);
|
||||
newMEMcfg = MEMcfg;
|
||||
newMEMcfg.WR_AUX_MEM = 1;
|
||||
auxMemorySelect(newMEMcfg);
|
||||
|
@ -519,7 +523,7 @@ INLINE uint8_t ioRead( uint16_t addr ) {
|
|||
io_RAM_EXP(addr);
|
||||
break;
|
||||
|
||||
// TODO: Make code "card insertable to slot" / aka slot independent and dynamically add/remove
|
||||
// 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:
|
||||
|
@ -617,49 +621,47 @@ INLINE void ioWrite( uint16_t addr, uint8_t val ) {
|
|||
break;
|
||||
|
||||
case (uint8_t)io_RDMAINRAM:
|
||||
// printf("io_RDMAINRAM\n");
|
||||
printf("W:io_RDMAINRAM (pc:$%04X)\n", m6502.PC);
|
||||
newMEMcfg = MEMcfg;
|
||||
newMEMcfg.RD_AUX_MEM = 0;
|
||||
auxMemorySelect(newMEMcfg);
|
||||
break;
|
||||
|
||||
case (uint8_t)io_RDCARDRAM:
|
||||
// printf("io_RDCARDRAM\n");
|
||||
printf("W:io_RDCARDRAM (pc:$%04X)\n", m6502.PC);
|
||||
newMEMcfg = MEMcfg;
|
||||
newMEMcfg.RD_AUX_MEM = 1;
|
||||
auxMemorySelect(newMEMcfg);
|
||||
break;
|
||||
|
||||
case (uint8_t)io_WRMAINRAM:
|
||||
// printf("io_WRMAINRAM\n");
|
||||
printf("W:io_WRMAINRAM (pc:$%04X)\n", m6502.PC);
|
||||
newMEMcfg = MEMcfg;
|
||||
newMEMcfg.WR_AUX_MEM = 0;
|
||||
auxMemorySelect(newMEMcfg);
|
||||
break;
|
||||
|
||||
case (uint8_t)io_WRCARDRAM:
|
||||
// printf("io_WRCARDRAM\n");
|
||||
printf("W:io_WRCARDRAM (pc:$%04X)\n", m6502.PC);
|
||||
newMEMcfg = MEMcfg;
|
||||
newMEMcfg.WR_AUX_MEM = 1;
|
||||
auxMemorySelect(newMEMcfg);
|
||||
break;
|
||||
|
||||
case (uint8_t)io_SETSTDZP:
|
||||
printf("INT ZP (pc:$%04X)\n", m6502.PC);
|
||||
|
||||
newMEMcfg = MEMcfg;
|
||||
newMEMcfg.ALT_ZP = 0;
|
||||
auxMemorySelect(newMEMcfg);
|
||||
|
||||
// TODO: set zero page table to RAM
|
||||
printf("TODO: set zero page table to RAM\n");
|
||||
break;
|
||||
|
||||
case (uint8_t)io_SETALTZP:
|
||||
printf("AUX ZP (pc:$%04X)\n", m6502.PC);
|
||||
|
||||
newMEMcfg = MEMcfg;
|
||||
newMEMcfg.ALT_ZP = 1;
|
||||
auxMemorySelect(newMEMcfg);
|
||||
|
||||
// TODO: set zero page table to AUX
|
||||
printf("TODO: set zero page table to AUX\n");
|
||||
break;
|
||||
|
||||
case (uint8_t)io_SETSLOTCXROM:
|
||||
|
@ -716,25 +718,25 @@ INLINE void ioWrite( uint16_t addr, uint8_t val ) {
|
|||
break;
|
||||
|
||||
case (uint8_t)io_80STOREOFF:
|
||||
// printf("io_80STOREOFF\n");
|
||||
printf("io_80STOREOFF (pc:$%04X)\n", m6502.PC);
|
||||
MEMcfg.is_80STORE = 0;
|
||||
textPageSelect();
|
||||
break;
|
||||
|
||||
case (uint8_t)io_80STOREON:
|
||||
// printf("io_80STOREON\n");
|
||||
printf("io_80STOREON (pc:$%04X)\n", m6502.PC);
|
||||
MEMcfg.is_80STORE = 1;
|
||||
textPageSelect();
|
||||
break;
|
||||
|
||||
case (uint8_t)io_VID_TXTPAGE1:
|
||||
// printf("io_VID_TXTPAGE1\n");
|
||||
printf("io_VID_TXTPAGE1 (pc:$%04X)\n", m6502.PC);
|
||||
MEMcfg.txt_page_2 = 0;
|
||||
textPageSelect();
|
||||
break;
|
||||
|
||||
case (uint8_t)io_VID_TXTPAGE2:
|
||||
// printf("io_VID_TXTPAGE2\n");
|
||||
printf("io_VID_TXTPAGE2 (pc:$%04X)\n", m6502.PC);
|
||||
MEMcfg.txt_page_2 = 1;
|
||||
textPageSelect();
|
||||
break;
|
||||
|
@ -785,7 +787,7 @@ 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
|
||||
// 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:
|
||||
|
@ -1182,25 +1184,26 @@ INLINE uint8_t src_zp_Y() {
|
|||
void auxMemorySelect( MEMcfg_t newMEMcfg ) {
|
||||
const uint8_t * newReadMEM = currentLowRDMEM;
|
||||
uint8_t * newWriteMEM = currentLowWRMEM;
|
||||
|
||||
|
||||
// TODO: Check if this is supposed to be the opposite
|
||||
if ( newMEMcfg.is_80STORE ) {
|
||||
if ( newMEMcfg.RD_AUX_MEM ) {
|
||||
newReadMEM = Apple2_64K_AUX + 0x200;
|
||||
}
|
||||
else {
|
||||
newReadMEM = Apple2_64K_RAM + 0x200;
|
||||
newReadMEM = Apple2_64K_MEM + 0x200;
|
||||
}
|
||||
|
||||
if ( newMEMcfg.WR_AUX_MEM ) {
|
||||
newWriteMEM = Apple2_64K_AUX;
|
||||
}
|
||||
else {
|
||||
newWriteMEM = Apple2_64K_RAM;
|
||||
newWriteMEM = Apple2_64K_MEM;
|
||||
}
|
||||
}
|
||||
else {
|
||||
newReadMEM = Apple2_64K_RAM + 0x200;
|
||||
newWriteMEM = Apple2_64K_RAM;
|
||||
newReadMEM = Apple2_64K_MEM + 0x200;
|
||||
newWriteMEM = Apple2_64K_MEM;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1251,7 +1254,7 @@ void auxMemorySelect( MEMcfg_t newMEMcfg ) {
|
|||
}
|
||||
|
||||
// load content of SP & Stack
|
||||
memcpy( shadowZPSTCKMEM, (void*) currentZPSTCKMEM, 0x200);
|
||||
memcpy( (void*) shadowZPSTCKMEM, (void*) currentZPSTCKMEM, 0x200);
|
||||
}
|
||||
|
||||
// finally we can mark change
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>ATSApplicationFontsPath</key>
|
||||
<string>fnt</string>
|
||||
<key>BuildMachineOSBuild</key>
|
||||
<string>18G5033</string>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>Steve ][</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>Steve2Icon.icns</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.trudnai.steveii</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>Steve ][</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>0.84</string>
|
||||
<key>CFBundleSupportedPlatforms</key>
|
||||
<array>
|
||||
<string>MacOSX</string>
|
||||
</array>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>DTCompiler</key>
|
||||
<string>com.apple.compilers.llvm.clang.1_0</string>
|
||||
<key>DTPlatformBuild</key>
|
||||
<string>11C504</string>
|
||||
<key>DTPlatformVersion</key>
|
||||
<string>GM</string>
|
||||
<key>DTSDKBuild</key>
|
||||
<string>19B90</string>
|
||||
<key>DTSDKName</key>
|
||||
<string>macosx10.15</string>
|
||||
<key>DTXcode</key>
|
||||
<string>1130</string>
|
||||
<key>DTXcodeBuild</key>
|
||||
<string>11C504</string>
|
||||
<key>LSApplicationCategoryType</key>
|
||||
<string>public.app-category.education</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>10.14</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>Copyright © 2019, 2020 Tamas Rudnai. All rights reserved.</string>
|
||||
<key>NSMainStoryboardFile</key>
|
||||
<string>Main</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string>NSApplication</string>
|
||||
</dict>
|
||||
</plist>
|
|
@ -0,0 +1 @@
|
|||
APPL????
|
Loading…
Reference in New Issue
Block a user