9 Commits

Author SHA1 Message Date
clobber ebcb35c783 Bump version for sparkle updater. 2020-12-21 23:02:01 -07:00
clobber 74a023675d Add undocumented opcodes ASR and ANC from js7800 https://github.com/raz0red/js7800/commit/4d557c45d8806bc6dfbbd1835536332928cfeb21 2020-10-19 17:33:39 -05:00
C.W. Betts d0a5ab88d8 Merge branch 'master' of github.com:OpenEmu/ProSystem-Core into master 2020-10-01 02:04:21 -06:00
C.W. Betts bb87a68e59 Poke the plists: get the development language from Xcode build. 2020-10-01 01:51:37 -06:00
C.W. Betts 9228bbea43 Fix locations of the system plugin headers.
Minor Xcode maintenance.
2020-10-01 01:26:41 -06:00
clobber 56420c3a12 Merge fixes and improvements from Wii7800 0.5 fork by raz0red (https://github.com/raz0red/wii7800/releases/tag/0.5)
Includes:
- Partial Expansion Module (XM) support
  - XRAM
  - XPokey (limited to single Pokey)
- Added support for cartridges with sizes greater than 144k
- Additional bank switching modes and cartridge types
- Multiple bank switching fixes
- Reworked cartridge header detection
  - Now properly detects bank switching, RAM, etc.
  - Detects Expansion Module (XM)
  - Detects High score cartridge
  - Detects Pokey at $0450
- Cartridge database
  - Added several new cartridge properties
    - Pokey at $0450
    - Default difficulty switch settings
    - Expansion Module (XM) enabled/disabled
    - High score cartridge enabled/disabled
  - Database content
    - Fixed incorrect controller settings for Sirius, Crossbow,
        and Alien Brigade
    - Added many homebrew cartridges
- Fixed issue occurring when Kangaroo and Holey were enabled (caused
    background to be displayed, resulting in large black squares)

Missing:
- High Score Cartridge support
2020-08-23 00:36:54 -05:00
C.W. Betts 1742f0be53 Update language resources.
This quiets warnings in newer Xcode releases.

Also update framework locations.
2020-01-07 16:43:14 -07:00
clobber 408b2d3c10 Use -fileSystemRepresentation instead of -UTF8String for file names 2017-08-17 00:42:25 -05:00
Rudy Richter d2ed27ffca Enable direct-render 2017-07-22 11:06:00 -04:00
21 changed files with 2273 additions and 345 deletions
Binary file not shown.
+2 -2
View File
@@ -3,7 +3,7 @@
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIconFile</key>
@@ -17,7 +17,7 @@
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.4.1</string>
<string>1.4.2</string>
<key>NSPrincipalClass</key>
<string>OEGameCoreController</string>
<key>OEGameCoreClass</key>
+1590 -32
View File
File diff suppressed because it is too large Load Diff
+16 -10
View File
@@ -36,6 +36,7 @@
/* Begin PBXBuildFile section */
82EC409F0FD9EC420017FC19 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 82EC409E0FD9EC420017FC19 /* libz.dylib */; };
871EC9A224F08BF700CEC578 /* ExpansionModule.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 871EC9A124F08BF600CEC578 /* ExpansionModule.cpp */; };
8794D9691B74713300897F57 /* Sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 941F59AF17A6189D0005D7EA /* Sound.cpp */; };
8D5B49B0048680CD000E48DA /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C167DFE841241C02AAC07 /* InfoPlist.strings */; };
8D5B49B4048680CD000E48DA /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */; };
@@ -93,11 +94,13 @@
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
089C1672FE841209C02AAC07 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = "<absolute>"; };
089C167EFE841241C02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; };
089C167FFE841241C02AAC07 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = "<absolute>"; };
1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; };
089C1672FE841209C02AAC07 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
089C167EFE841241C02AAC07 /* en */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
089C167FFE841241C02AAC07 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; };
1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
82EC409E0FD9EC420017FC19 /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; };
871EC9A024F08BF600CEC578 /* ExpansionModule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExpansionModule.h; sourceTree = "<group>"; };
871EC9A124F08BF600CEC578 /* ExpansionModule.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ExpansionModule.cpp; sourceTree = "<group>"; };
8D5B49B6048680CD000E48DA /* ProSystem.oecoreplugin */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ProSystem.oecoreplugin; sourceTree = BUILT_PRODUCTS_DIR; };
8D5B49B7048680CD000E48DA /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
941DFB2615B6425200C6552F /* ProSystemGameCore.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ProSystemGameCore.mm; sourceTree = "<group>"; };
@@ -157,11 +160,11 @@
941F59BB17A6189D0005D7EA /* Zconf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Zconf.h; sourceTree = "<group>"; };
941F59BC17A6189D0005D7EA /* Zip.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Zip.h; sourceTree = "<group>"; };
941F59BD17A6189D0005D7EA /* Zlib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Zlib.h; sourceTree = "<group>"; };
941F59DB17A62ADD0005D7EA /* OpenEmuBase.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenEmuBase.framework; path = "../../Library/Developer/Xcode/DerivedData/OpenEmu-dsehantrxgyfywdpbneyslftzzvv/Build/Products/Debug/OpenEmuBase.framework"; sourceTree = "<group>"; };
941F59DB17A62ADD0005D7EA /* OpenEmuBase.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = OpenEmuBase.framework; sourceTree = BUILT_PRODUCTS_DIR; };
941F59FB17A77CC90005D7EA /* ProSystem.dat */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ProSystem.dat; sourceTree = SOURCE_ROOT; };
941F5A2617A78FF20005D7EA /* OE7800SystemResponderClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OE7800SystemResponderClient.h; path = "../OpenEmu/Atari 7800/OE7800SystemResponderClient.h"; sourceTree = "<group>"; };
941F5A2617A78FF20005D7EA /* OE7800SystemResponderClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OE7800SystemResponderClient.h; path = "../OpenEmu/SystemPlugins/Atari 7800/OE7800SystemResponderClient.h"; sourceTree = "<group>"; };
B5008DAD0E8BFB3E005AECAF /* ProSystemGameCore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProSystemGameCore.h; sourceTree = "<group>"; };
D2F7E65807B2D6F200F64583 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = "<absolute>"; };
D2F7E65807B2D6F200F64583 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -190,6 +193,7 @@
);
name = VisualBoyAdvance;
sourceTree = "<group>";
usesTabs = 0;
};
089C1671FE841209C02AAC07 /* Frameworks and Libraries */ = {
isa = PBXGroup;
@@ -268,6 +272,8 @@
941F598917A6189D0005D7EA /* Database.cpp */,
941F598A17A6189D0005D7EA /* Database.h */,
941F598B17A6189D0005D7EA /* Equates.h */,
871EC9A124F08BF600CEC578 /* ExpansionModule.cpp */,
871EC9A024F08BF600CEC578 /* ExpansionModule.h */,
941F598C17A6189D0005D7EA /* Hash.cpp */,
941F598D17A6189D0005D7EA /* Hash.h */,
941F598E17A6189D0005D7EA /* lib */,
@@ -369,12 +375,11 @@
089C1669FE841209C02AAC07 /* Project object */ = {
isa = PBXProject;
attributes = {
BuildIndependentTargetsInParallel = YES;
LastUpgradeCheck = 0700;
};
buildConfigurationList = 1DEB913E08733D840010E9CD /* Build configuration list for PBXProject "ProSystem" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
developmentRegion = en;
hasScannedForEncodings = 1;
knownRegions = (
en,
@@ -453,6 +458,7 @@
941F59CD17A6189D0005D7EA /* Pokey.cpp in Sources */,
941F59CE17A6189D0005D7EA /* ProSystem.cpp in Sources */,
941F59CF17A6189D0005D7EA /* Region.cpp in Sources */,
871EC9A224F08BF700CEC578 /* ExpansionModule.cpp in Sources */,
941F59D017A6189D0005D7EA /* Riot.cpp in Sources */,
941F59D117A6189D0005D7EA /* Sally.cpp in Sources */,
941F59D317A6189D0005D7EA /* Tia.cpp in Sources */,
@@ -479,7 +485,7 @@
089C167DFE841241C02AAC07 /* InfoPlist.strings */ = {
isa = PBXVariantGroup;
children = (
089C167EFE841241C02AAC07 /* English */,
089C167EFE841241C02AAC07 /* en */,
);
name = InfoPlist.strings;
sourceTree = "<group>";
+24 -24
View File
@@ -89,25 +89,27 @@
// Right difficulty switch defaults to right position, "(A)dvanced", which fixes Tower Toppler
_inputState[RIGHT_DIFF_SWITCH] = RIGHT_POSITION;
if(cartridge_Load([path UTF8String]))
if(cartridge_Load(path.fileSystemRepresentation))
{
NSString *databasePath = [[[NSBundle bundleForClass:[self class]] resourcePath] stringByAppendingPathComponent:@"ProSystem.dat"];
database_filename = [databasePath UTF8String];
database_filename = databasePath.fileSystemRepresentation;
database_enabled = true;
// BIOS is optional
NSString *biosROM = [[self biosDirectoryPath] stringByAppendingPathComponent:@"7800 BIOS (U).rom"];
if (bios_Load([biosROM UTF8String]))
NSString *biosROM = [self.biosDirectoryPath stringByAppendingPathComponent:@"7800 BIOS (U).rom"];
if (bios_Load(biosROM.fileSystemRepresentation))
bios_enabled = true;
NSLog(@"Headerless MD5 hash: %s", cartridge_digest.c_str());
NSLog(@"Header info (often wrong):\ntitle: %s\ntype: %d\nregion: %s\npokey: %s", cartridge_title.c_str(), cartridge_type, cartridge_region == REGION_NTSC ? "NTSC" : "PAL", cartridge_pokey ? "true" : "false");
NSLog(@"[ProSystem] Headerless MD5 hash: %s", cartridge_digest.c_str());
NSLog(@"[ProSystem] Header info (often wrong):\ntitle: %s\ntype: %d\nregion: %s\npokey: %s", cartridge_title.c_str(), cartridge_type, cartridge_region == REGION_NTSC ? "NTSC" : "PAL", cartridge_pokey ? "true" : "false");
database_Load(cartridge_digest);
prosystem_Reset();
std::string title = common_Trim(cartridge_title);
NSLog(@"Database info:\ntitle: %@\ntype: %d\nregion: %s\npokey: %s", [NSString stringWithUTF8String:title.c_str()], cartridge_type, cartridge_region == REGION_NTSC ? "NTSC" : "PAL", cartridge_pokey ? "true" : "false");
if (cart_in_db) {
std::string title = common_Trim(cartridge_title);
NSLog(@"[ProSystem] Database info:\ntitle: %@\ntype: %d\nregion: %s\npokey: %s", [NSString stringWithUTF8String:title.c_str()], cartridge_type, cartridge_region == REGION_NTSC ? "NTSC" : "PAL", cartridge_pokey ? "true" : "false");
}
//sound_SetSampleRate(48000);
[self setPalette32];
@@ -117,12 +119,9 @@
if(_isLightgunEnabled)
_inputState[3] = 1;
// Set defaults for Bentley Bear (homebrew) so button 1 = run/shoot and button 2 = jump
if(cartridge_digest == "ad35a98040a2facb10ecb120bf83bcc3")
{
_inputState[LEFT_DIFF_SWITCH] = RIGHT_POSITION;
_inputState[RIGHT_DIFF_SWITCH] = LEFT_POSITION;
}
// Set switch overrides from database
_inputState[LEFT_DIFF_SWITCH] = cartridge_left_switch;
_inputState[RIGHT_DIFF_SWITCH] = cartridge_right_switch;
return YES;
}
@@ -170,9 +169,9 @@
#pragma mark - Video
- (const void *)videoBuffer
- (const void *)getVideoBufferWithHint:(void *)hint
{
return _videoBuffer;
return _videoBuffer = (uint32_t*)(hint ?: _videoBuffer);
}
- (OEIntRect)screenRect
@@ -200,11 +199,6 @@
return GL_UNSIGNED_INT_8_8_8_8_REV;
}
- (GLenum)internalPixelFormat
{
return GL_RGB8;
}
#pragma mark - Audio
- (double)audioSampleRate
@@ -237,6 +231,9 @@
- (NSData *)serializeStateWithError:(NSError **)outError
{
size_t length = cartridge_type == CARTRIDGE_TYPE_SUPERCART_RAM ? 32837 : 16453;
if(cartridge_xm) {
length += 4 + XM_RAM_SIZE;
}
void *bytes = malloc(length);
if(prosystem_Save_buffer((uint8_t *)bytes))
@@ -255,18 +252,21 @@
- (BOOL)deserializeState:(NSData *)state withError:(NSError **)outError
{
size_t serial_size = cartridge_type == CARTRIDGE_TYPE_SUPERCART_RAM ? 32837 : 16453;
if(serial_size != [state length]) {
if(cartridge_xm) {
serial_size += 4 + XM_RAM_SIZE;
}
if(serial_size != state.length) {
if(outError) {
*outError = [NSError errorWithDomain:OEGameCoreErrorDomain code:OEGameCoreStateHasWrongSizeError userInfo:@{
NSLocalizedDescriptionKey : @"Save state has wrong file size.",
NSLocalizedRecoverySuggestionErrorKey : [NSString stringWithFormat:@"The save state does not have the right size, %ld expected, got: %ld.", serial_size, [state length]]
NSLocalizedRecoverySuggestionErrorKey : [NSString stringWithFormat:@"The save state does not have the right size, %ld expected, got: %ld.", serial_size, state.length]
}];
}
return NO;
}
if(prosystem_Load_buffer((uint8_t *)[state bytes]))
if(prosystem_Load_buffer((uint8_t *)state.bytes))
return YES;
if(outError) {
+136 -51
View File
@@ -5,7 +5,7 @@
//
// ----------------------------------------------------------------------------
// Copyright 2005 Greg Stanton
//
//
// This program 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 2 of the License, or
@@ -23,6 +23,9 @@
// Cartridge.cpp
// ----------------------------------------------------------------------------
#include "Cartridge.h"
#include "Region.h"
#include <string.h>
#define CARTRIDGE_SOURCE "Cartridge.cpp"
std::string cartridge_title;
@@ -34,13 +37,20 @@ std::string cartridge_filename;
byte cartridge_type;
byte cartridge_region;
bool cartridge_pokey;
byte cartridge_controller[2];
bool cartridge_pokey450;
byte cartridge_controller[2] = {1, 1};
byte cartridge_bank;
uint cartridge_flags;
int cartridge_crosshair_x;
int cartridge_crosshair_y;
bool cartridge_dualanalog = false;
bool cartridge_xm = false;
bool cartridge_disable_bios = false;
uint cartridge_hblank = 34;
byte cartridge_left_switch = 1;
byte cartridge_right_switch = 0;
bool cartridge_swap_buttons = false;
bool cartridge_hsc_enabled = false;
static byte* cartridge_buffer = NULL;
static uint cartridge_size = 0;
@@ -72,16 +82,23 @@ static bool cartridge_CC2(const byte* header) {
}
// ----------------------------------------------------------------------------
// GetBankOffset
// GetBank
// ----------------------------------------------------------------------------
static uint cartridge_GetBankOffset(byte bank) {
static uint cartridge_GetBank(byte bank) {
if ((cartridge_type == CARTRIDGE_TYPE_SUPERCART || cartridge_type == CARTRIDGE_TYPE_SUPERCART_ROM || cartridge_type == CARTRIDGE_TYPE_SUPERCART_RAM) && cartridge_size <= 65536) {
// for some of these carts, there are only 4 banks. in this case we ignore bit 3
// previously, games of this type had to be doubled. The first 4 banks needed to be duplicated at the end of the ROM
return (bank & 3) * 16384;
return (bank & 3);
}
return bank * 16384;
return bank;
}
// ----------------------------------------------------------------------------
// GetBankOffset
// ----------------------------------------------------------------------------
static uint cartridge_GetBankOffset(byte bank) {
return cartridge_GetBank(bank) * 16384;
}
// ----------------------------------------------------------------------------
@@ -95,16 +112,29 @@ static void cartridge_WriteBank(word address, byte bank) {
}
}
static void cartridge_SetTypeBySize(uint size) {
if (size <= 0x10000) {
cartridge_type = CARTRIDGE_TYPE_NORMAL;
} else if (size == 0x24000 ) {
cartridge_type = CARTRIDGE_TYPE_SUPERCART_LARGE;
} else if (size == 0x20000 ) {
cartridge_type = CARTRIDGE_TYPE_SUPERCART_ROM;
} else {
cartridge_type = CARTRIDGE_TYPE_SUPERCART;
}
}
// ----------------------------------------------------------------------------
// ReadHeader
// ----------------------------------------------------------------------------
static void cartridge_ReadHeader(const byte* header) {
char temp[33] = {0};
for(int index = 0; index < 32; index++) {
temp[index] = header[index + 17];
temp[index] = header[index + 17];
}
cartridge_title = temp;
cartridge_size = header[49] << 24;
cartridge_size |= header[50] << 16;
cartridge_size |= header[51] << 8;
@@ -128,22 +158,47 @@ static void cartridge_ReadHeader(const byte* header) {
}
}
else {
if(header[53] == 1) {
if(header[53] == 2 /*1*/) { // Wii: Abs and Act were swapped
cartridge_type = CARTRIDGE_TYPE_ABSOLUTE;
}
else if(header[53] == 2) {
else if(header[53] == 1 /*2*/) { // Wii: Abs and Act were swapped
cartridge_type = CARTRIDGE_TYPE_ACTIVISION;
}
else {
cartridge_type = CARTRIDGE_TYPE_NORMAL;
}
}
cartridge_pokey = (header[54] & 1)? true: false;
cartridge_pokey450 = (header[54] & 0x40)? true : false;
if (cartridge_pokey450) {
cartridge_pokey = true;
}
cartridge_controller[0] = header[55];
cartridge_controller[1] = header[56];
cartridge_region = header[57];
cartridge_flags = 0;
cartridge_xm = (header[63] & 1)? true: false;
cartridge_hsc_enabled = header[58]&0x01;
// Wii: Updates to header interpretation
byte ct1 = header[54];
if(header[53] == 0) {
if ((ct1&0x0a)==0x0a) { // BIT1 and BIT3 (Supercart Large: 2) rom at $4000
cartridge_type = CARTRIDGE_TYPE_SUPERCART_LARGE;
} else if ((ct1&0x12)==0x12) { // BIT1 and BIT4 (Supercart ROM: 4) bank6 at $4000
cartridge_type = CARTRIDGE_TYPE_SUPERCART_ROM;
} else if ((ct1&0x06)==0x06) { // BIT1 and BIT2 (Supercart RAM: 3) ram at $4000
cartridge_type = CARTRIDGE_TYPE_SUPERCART_RAM;
} else if ((ct1&0x02)==0x02) { // BIT1 (Supercart) bank switched
cartridge_type = CARTRIDGE_TYPE_SUPERCART;
} else if (cartridge_size <= 0x10000 && ((ct1&0x04)==0x04)) { // Size < 64k && BIT2 (Normal RAM: ?) ram at $4000 )
cartridge_type = CARTRIDGE_TYPE_NORMAL_RAM;
} else {
// Attempt to determine the cartridge type based on its size
cartridge_SetTypeBySize(cartridge_size);
}
}
}
// ----------------------------------------------------------------------------
@@ -156,7 +211,7 @@ static bool cartridge_Load(const byte* data, uint size) {
}
cartridge_Release( );
byte header[128] = {0};
for(int index = 0; index < 128; index++) {
header[index] = data[index];
@@ -172,19 +227,29 @@ if (cartridge_CC2(header)) {
cartridge_ReadHeader(header);
size -= 128;
offset = 128;
cartridge_size = size;
// Several cartridge headers do not have the proper size. So attempt to use the size
// of the file.
if (cartridge_size != size) {
// Necessary for the following roms:
// Impossible Mission hacks w/ C64 style graphics
if (size % 1024 == 0) {
cartridge_size = size;
}
}
}
else {
cartridge_size = size;
// Attempt to guess the cartridge type based on its size
cartridge_SetTypeBySize(size);
}
cartridge_buffer = new byte[cartridge_size];
for(int index = 0; index < cartridge_size; index++) {
cartridge_buffer[index] = data[index + offset];
}
cartridge_digest = hash_Compute(cartridge_buffer, cartridge_size);
return true;
}
@@ -196,10 +261,10 @@ bool cartridge_Load(std::string filename) {
logger_LogError("Cartridge filename is invalid.", CARTRIDGE_SOURCE);
return false;
}
cartridge_Release( );
logger_LogInfo("Opening cartridge file " + filename + ".", CARTRIDGE_SOURCE);
byte* data = NULL;
//uint size = archive_GetUncompressedFileSize(filename);
uint size = 0;
@@ -208,7 +273,7 @@ bool cartridge_Load(std::string filename) {
FILE *file = fopen(filename.c_str( ), "rb");
if(file == NULL) {
logger_LogError("Failed to open the cartridge file " + filename + " for reading.", CARTRIDGE_SOURCE);
return false;
return false;
}
if(fseek(file, 0L, SEEK_END)) {
@@ -222,7 +287,7 @@ bool cartridge_Load(std::string filename) {
logger_LogError("Failed to find the size of the cartridge file.", CARTRIDGE_SOURCE);
return false;
}
data = new byte[size];
if(fread(data, 1, size, file) != size && ferror(file)) {
fclose(file);
@@ -230,15 +295,15 @@ bool cartridge_Load(std::string filename) {
cartridge_Release( );
delete [ ] data;
return false;
}
}
fclose(file);
fclose(file);
}
else {
data = new byte[size];
//archive_Uncompress(filename, data, size);
}
if(!cartridge_Load(data, size)) {
logger_LogError("Failed to load the cartridge data into memory.", CARTRIDGE_SOURCE);
delete [ ] data;
@@ -247,7 +312,7 @@ bool cartridge_Load(std::string filename) {
if(data != NULL) {
delete [ ] data;
}
cartridge_filename = filename;
return true;
}
@@ -260,29 +325,37 @@ void cartridge_Store( ) {
case CARTRIDGE_TYPE_NORMAL:
memory_WriteROM(65536 - cartridge_size, cartridge_size, cartridge_buffer);
break;
case CARTRIDGE_TYPE_SUPERCART:
if(cartridge_GetBankOffset(7) < cartridge_size) {
memory_WriteROM(49152, 16384, cartridge_buffer + cartridge_GetBankOffset(7));
}
case CARTRIDGE_TYPE_NORMAL_RAM:
memory_WriteROM(65536 - cartridge_size, cartridge_size, cartridge_buffer);
memory_ClearROM(16384, 16384);
break;
case CARTRIDGE_TYPE_SUPERCART_LARGE:
if(cartridge_GetBankOffset(8) < cartridge_size) {
memory_WriteROM(49152, 16384, cartridge_buffer + cartridge_GetBankOffset(8));
case CARTRIDGE_TYPE_SUPERCART: {
uint offset = cartridge_size - 16384;
if(offset < cartridge_size) {
memory_WriteROM(49152, 16384, cartridge_buffer + offset);
}
} break;
case CARTRIDGE_TYPE_SUPERCART_LARGE: {
uint offset = cartridge_size - 16384;
if(offset < cartridge_size) {
memory_WriteROM(49152, 16384, cartridge_buffer + offset);
memory_WriteROM(16384, 16384, cartridge_buffer + cartridge_GetBankOffset(0));
}
break;
case CARTRIDGE_TYPE_SUPERCART_RAM:
if(cartridge_GetBankOffset(7) < cartridge_size) {
memory_WriteROM(49152, 16384, cartridge_buffer + cartridge_GetBankOffset(7));
} break;
case CARTRIDGE_TYPE_SUPERCART_RAM: {
uint offset = cartridge_size - 16384;
if(offset < cartridge_size) {
memory_WriteROM(49152, 16384, cartridge_buffer + offset);
memory_ClearROM(16384, 16384);
}
break;
case CARTRIDGE_TYPE_SUPERCART_ROM:
if(cartridge_GetBankOffset(7) < cartridge_size && cartridge_GetBankOffset(6) < cartridge_size) {
memory_WriteROM(49152, 16384, cartridge_buffer + cartridge_GetBankOffset(7));
} break;
case CARTRIDGE_TYPE_SUPERCART_ROM: {
uint offset = cartridge_size - 16384;
if(offset < cartridge_size && cartridge_GetBankOffset(6) < cartridge_size) {
memory_WriteROM(49152, 16384, cartridge_buffer + offset);
memory_WriteROM(16384, 16384, cartridge_buffer + cartridge_GetBankOffset(6));
}
break;
} break;
case CARTRIDGE_TYPE_ABSOLUTE:
memory_WriteROM(16384, 16384, cartridge_buffer);
memory_WriteROM(32768, 32768, cartridge_buffer + cartridge_GetBankOffset(2));
@@ -306,16 +379,18 @@ void cartridge_Write(word address, byte data) {
switch(cartridge_type) {
case CARTRIDGE_TYPE_SUPERCART:
case CARTRIDGE_TYPE_SUPERCART_RAM:
case CARTRIDGE_TYPE_SUPERCART_ROM:
if(address >= 32768 && address < 49152 && data < 9) {
case CARTRIDGE_TYPE_SUPERCART_ROM: {
uint maxbank = cartridge_size / 16384;
if(address >= 32768 && address < 49152 && cartridge_GetBank(data) < maxbank /*9*/) {
cartridge_StoreBank(data);
}
break;
case CARTRIDGE_TYPE_SUPERCART_LARGE:
if(address >= 32768 && address < 49152 && data < 9) {
} break;
case CARTRIDGE_TYPE_SUPERCART_LARGE: {
uint maxbank = cartridge_size / 16384;
if(address >= 32768 && address < 49152 && cartridge_GetBank(data) < maxbank /*9*/) {
cartridge_StoreBank(data + 1);
}
break;
} break;
case CARTRIDGE_TYPE_ABSOLUTE:
if(address == 32768 && (data == 1 || data == 2)) {
cartridge_StoreBank(data - 1);
@@ -328,6 +403,7 @@ void cartridge_Write(word address, byte data) {
break;
}
#if 0 // WIi: Moved to Memory.cpp
if(cartridge_pokey && address >= 0x4000 && address <= 0x400f) {
switch(address) {
case POKEY_AUDF1:
@@ -362,6 +438,7 @@ void cartridge_Write(word address, byte data) {
break;
}
}
#endif
}
// ----------------------------------------------------------------------------
@@ -379,7 +456,7 @@ void cartridge_StoreBank(byte bank) {
cartridge_WriteBank(32768, bank);
break;
case CARTRIDGE_TYPE_SUPERCART_LARGE:
cartridge_WriteBank(32768, bank);
cartridge_WriteBank(32768, bank);
break;
case CARTRIDGE_TYPE_ABSOLUTE:
cartridge_WriteBank(16384, bank);
@@ -387,7 +464,7 @@ void cartridge_StoreBank(byte bank) {
case CARTRIDGE_TYPE_ACTIVISION:
cartridge_WriteBank(40960, bank);
break;
}
}
}
// ----------------------------------------------------------------------------
@@ -405,16 +482,24 @@ void cartridge_Release( ) {
delete [ ] cartridge_buffer;
cartridge_size = 0;
cartridge_buffer = NULL;
cartridge_title = "";
cartridge_type = 0;
cartridge_region = 0;
cartridge_pokey = 0;
memset(cartridge_controller, 0, sizeof(cartridge_controller));
cartridge_pokey450 = 0;
cartridge_xm = false;
// Default to joysticks
memset( cartridge_controller, 1, sizeof( cartridge_controller ) );
cartridge_bank = 0;
cartridge_flags = 0;
cartridge_disable_bios = false;
cartridge_crosshair_x = 0;
cartridge_crosshair_y = 0;
cartridge_hblank = 34;
cartridge_hblank = HBLANK_DEFAULT;
cartridge_dualanalog = false;
cartridge_left_switch = 1;
cartridge_right_switch = 0;
cartridge_swap_buttons = false;
cartridge_hsc_enabled = false;
}
}
+12 -1
View File
@@ -31,12 +31,15 @@
#define CARTRIDGE_TYPE_SUPERCART_ROM 4
#define CARTRIDGE_TYPE_ABSOLUTE 5
#define CARTRIDGE_TYPE_ACTIVISION 6
#define CARTRIDGE_TYPE_NORMAL_RAM 7
#define CARTRIDGE_CONTROLLER_NONE 0
#define CARTRIDGE_CONTROLLER_JOYSTICK 1
#define CARTRIDGE_CONTROLLER_LIGHTGUN 2
#define CARTRIDGE_WSYNC_MASK 2
#define CARTRIDGE_CYCLE_STEALING_MASK 1
#define HBLANK_DEFAULT 34
#include <stdio.h>
#include <string>
#include "Equates.h"
@@ -65,9 +68,15 @@ extern std::string cartridge_filename;
extern byte cartridge_type;
extern byte cartridge_region;
extern bool cartridge_pokey;
extern bool cartridge_pokey450;
extern bool cartridge_xm;
extern byte cartridge_controller[2];
extern byte cartridge_bank;
extern uint cartridge_flags;
extern bool cartridge_disable_bios;
extern byte cartridge_left_switch;
extern byte cartridge_right_switch;
extern bool cartridge_swap_buttons;
// The x offset for the lightgun crosshair (allows per cartridge adjustments)
extern int cartridge_crosshair_x;
@@ -77,5 +86,7 @@ extern int cartridge_crosshair_y;
extern uint cartridge_hblank;
// Whether the cartridge supports dual analog
extern bool cartridge_dualanalog;
// Whether the high score cart is enabled
extern bool cartridge_hsc_enabled;
#endif
#endif
+39 -5
View File
@@ -25,6 +25,7 @@
#include "Database.h"
#define DATABASE_SOURCE "Database.cpp"
bool cart_in_db = false;
bool database_enabled = true;
std::string database_filename;
@@ -44,6 +45,7 @@ void database_Initialize( ) {
// Load
// ----------------------------------------------------------------------------
bool database_Load(std::string digest) {
cart_in_db = false;
if(database_enabled) {
logger_LogInfo("Accessing database " + database_filename + ".", DATABASE_SOURCE);
@@ -53,13 +55,22 @@ bool database_Load(std::string digest) {
return false;
}
// max count of items in the database
static int count = 17;
char buffer[256];
while(fgets(buffer, 256, file) != NULL) {
std::string line = buffer;
if(line.compare(1, 32, digest.c_str( )) == 0) {
std::string entry[11];
for(int index = 0; index < 11; index++) {
cart_in_db = true;
std::string entry[count];
for (int index = 0; index < count; index++) {
buffer[0] = '\0';
fgets(buffer, 256, file);
if (strchr(buffer, '[')) {
// Passed the current game in DB
break;
}
entry[index] = common_Remove(buffer, '\n');
entry[index] = common_Remove(entry[index], '\r');
}
@@ -73,7 +84,7 @@ bool database_Load(std::string digest) {
cartridge_flags = common_ParseUint(database_GetValue(entry[6]));
// Optionally load the lightgun crosshair offsets, hblank, dual analog
for(int index = 7; index < 11; index++)
for(int index = 7; index < count; index++)
{
if(entry[index].find("crossx") != std::string::npos)
{
@@ -90,9 +101,32 @@ bool database_Load(std::string digest) {
if(entry[index].find("dualanalog") != std::string::npos)
{
cartridge_dualanalog = common_ParseBool(database_GetValue(entry[index]));
}
}
if (entry[index].find("pokey450") != std::string::npos) {
cartridge_pokey450 = common_ParseBool(database_GetValue(entry[index]));
if (cartridge_pokey450) {
cartridge_pokey = true;
}
}
if (entry[index].find("xm") != std::string::npos) {
cartridge_xm = common_ParseBool(database_GetValue(entry[index]));
}
if (entry[index].find("disablebios") != std::string::npos) {
cartridge_disable_bios = common_ParseBool(database_GetValue(entry[index]));
}
if (entry[index].find("leftswitch") != std::string::npos) {
cartridge_left_switch = common_ParseByte(database_GetValue(entry[index]));
}
if (entry[index].find("rightswitch") != std::string::npos) {
cartridge_right_switch = common_ParseByte(database_GetValue(entry[index]));
}
if (entry[index].find("swapbuttons") != std::string::npos) {
cartridge_swap_buttons = common_ParseBool(database_GetValue(entry[index]));
}
if (entry[index].find("hsc") != std::string::npos) {
cartridge_hsc_enabled = common_ParseBool(database_GetValue(entry[index]));
}
}
break;
}
}
+2 -1
View File
@@ -38,5 +38,6 @@ extern void database_Initialize( );
extern bool database_Load(std::string digest);
extern bool database_enabled;
extern std::string database_filename;
extern bool cart_in_db;
#endif
#endif
+81
View File
@@ -0,0 +1,81 @@
/*
Memory map:
POKEY1 $0450 $045F 16 bytes
POKEY2* $0460 $046F 16 bytes
XCTRL $0470 $047F 1 byte
RAM $4000 $7FFF 16384 bytes
XCTRL Bit Description
+-------------------------------+
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
+-------------------------------+
| | | | | | | |
| | | | | | | +-- Bank select bit 0 \
| | | | | | +------ Bank select bit 1 | Totally 128 KByte in 16 KByte banks
| | | | | +---------- Bank select bit 3 /
| | | | +-------------- Enable memory bit (1 = Memory enabled, 0 after power on)
| | | +------------------ Enable POKEY bit** (1 = POKEY enabled, 0 after power on)
| | |
NA NA NA = Not Available or Not Used
* = Can be mounted piggy back on the first POKEY. Description how to do this will come when i have tried it out.
** This bit controls both POKEY chip select signals.
The mapping is totally non compatible with pretty much everything.
There is a bank select latch located at $0470 and the POKEY is located at $0450
(There's also a chip select output ($0460) on the PLD which alows you to simply piggy back a second POKEY).
Since the PLD is reconfigurable I could map the POKEY (or the RAM for that matter) to pretty much anything
if you wanted to. However since the PLD is soldered under the POKEY this needs to be configured before delivery.
*/
#include <string.h>
#include "ExpansionModule.h"
byte xm_ram[XM_RAM_SIZE] = {0};
byte xm_reg = 0;
byte xm_bank = 0;
bool xm_pokey_enabled = false;
bool xm_mem_enabled = false;
void xm_Reset() {
memset(xm_ram, 0, XM_RAM_SIZE);
xm_bank = 0;
xm_reg = 0;
xm_pokey_enabled = false;
xm_mem_enabled = false;
}
byte xm_Read(word address) {
if (xm_pokey_enabled && (address >= 0x0450 && address < 0x0460)) {
byte b = pokey_GetRegister(0x4000 + (address - 0x0450));
return b;
} else if (xm_pokey_enabled && (address >= 0x0460 && address < 0x0470)) {
byte b = pokey_GetRegister(0x4000 + (address - 0x0460));
return b;
} else if (xm_mem_enabled && (address >= 0x4000 && address < 0x8000)) {
byte b = xm_ram[(xm_bank * 0x4000) + (address - 0x4000)];
return b;
} else if (address >= 0x0470 && address < 0x0480) {
// TODO: Should the value be returned?
}
return 0;
}
void xm_Write(word address, byte data) {
if (xm_pokey_enabled && (address >= 0x0450 && address < 0x0460)) {
pokey_SetRegister(0x4000 + (address - 0x0450), data);
} else if (xm_pokey_enabled && (address >= 0x0460 && address < 0x0470)) {
pokey_SetRegister(0x4000 + (address - 0x0460), data);
} else if (xm_mem_enabled && (address >= 0x4000 && address < 0x8000)) {
xm_ram[(xm_bank * 0x4000) + (address - 0x4000)] = data;
} else if (address >= 0x0470 && address < 0x0480) {
xm_reg = data;
xm_bank = xm_reg & 7;
xm_pokey_enabled = (xm_reg & 0x10) > 0;
xm_mem_enabled = (xm_reg & 0x08) > 0;
}
}
+19
View File
@@ -0,0 +1,19 @@
#ifndef EXPANSIONMODULE_H
#define EXPANSIONMODULE_H
#include "Cartridge.h"
#include "Memory.h"
#define XM_RAM_SIZE 0x20000
extern byte xm_ram[XM_RAM_SIZE];
extern bool xm_pokey_enabled;
extern bool xm_mem_enabled;
extern byte xm_reg;
extern byte xm_bank;
void xm_Reset();
byte xm_Read(word address);
void xm_Write(word address, byte data);
#endif
+29 -21
View File
@@ -5,7 +5,7 @@
//
// ----------------------------------------------------------------------------
// Copyright 2005 Greg Stanton
//
//
// This program 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 2 of the License, or
@@ -45,12 +45,12 @@ static byte maria_wmode;
// ----------------------------------------------------------------------------
// StoreCell
// ----------------------------------------------------------------------------
static void maria_StoreCell(byte data) {
static inline void maria_StoreCell(byte data) {
if(maria_horizontal < MARIA_LINERAM_SIZE) {
if(data) {
maria_lineRAM[maria_horizontal] = maria_palette | data;
}
else {
else {
byte kmode = memory_ram[CTRL] & 4;
if(kmode) {
maria_lineRAM[maria_horizontal] = 0;
@@ -63,12 +63,12 @@ static void maria_StoreCell(byte data) {
// ----------------------------------------------------------------------------
// StoreCell
// ----------------------------------------------------------------------------
static void maria_StoreCell(byte high, byte low) {
static inline void maria_StoreCell(byte high, byte low) {
if(maria_horizontal < MARIA_LINERAM_SIZE) {
if(low || high) {
maria_lineRAM[maria_horizontal] = (maria_palette & 16) | high | low;
}
else {
else {
byte kmode = memory_ram[CTRL] & 4;
if(kmode) {
maria_lineRAM[maria_horizontal] = 0;
@@ -81,7 +81,7 @@ static void maria_StoreCell(byte high, byte low) {
// ----------------------------------------------------------------------------
// IsHolyDMA
// ----------------------------------------------------------------------------
static bool maria_IsHolyDMA( ) {
static inline bool maria_IsHolyDMA( ) {
if(maria_pp.w > 32767) {
if(maria_h16 && (maria_pp.w & 4096)) {
return true;
@@ -96,7 +96,7 @@ static bool maria_IsHolyDMA( ) {
// ----------------------------------------------------------------------------
// GetColor
// ----------------------------------------------------------------------------
static byte maria_GetColor(byte data) {
static inline byte maria_GetColor(byte data) {
if(data & 3) {
return memory_ram[BACKGRND + data];
}
@@ -108,12 +108,15 @@ static byte maria_GetColor(byte data) {
// ----------------------------------------------------------------------------
// StoreGraphic
// ----------------------------------------------------------------------------
static void maria_StoreGraphic( ) {
static inline void maria_StoreGraphic( ) {
byte data = memory_ram[maria_pp.w];
if(maria_wmode) {
if(maria_IsHolyDMA( )) {
#if 0 // Wii: disabled due to rendering in Kangaroo mode
maria_StoreCell(0, 0);
maria_StoreCell(0, 0);
#endif
maria_horizontal+=2;
}
else {
maria_StoreCell((data & 12), (data & 192) >> 6);
@@ -122,10 +125,13 @@ static void maria_StoreGraphic( ) {
}
else {
if(maria_IsHolyDMA( )) {
#if 0 // Wii: disabled due to rendering in Kangaroo mode
maria_StoreCell(0);
maria_StoreCell(0);
maria_StoreCell(0);
maria_StoreCell(0);
#endif
maria_horizontal+=4;
}
else {
maria_StoreCell((data & 192) >> 6);
@@ -140,9 +146,10 @@ static void maria_StoreGraphic( ) {
// ----------------------------------------------------------------------------
// WriteLineRAM
// ----------------------------------------------------------------------------
static void maria_WriteLineRAM(byte* buffer) {
static inline void maria_WriteLineRAM(byte* buffer) {
byte rmode = memory_ram[CTRL] & 3;
if(rmode == 0) {
// 160A/B
int pixel = 0;
for(int index = 0; index < MARIA_LINERAM_SIZE; index += 4) {
word color;
@@ -160,7 +167,8 @@ static void maria_WriteLineRAM(byte* buffer) {
buffer[pixel++] = color;
}
}
else if(rmode == 2) {
else if(rmode == 2) {
// 320B/D
int pixel = 0;
for(int index = 0; index < MARIA_LINERAM_SIZE; index += 4) {
buffer[pixel++] = maria_GetColor((maria_lineRAM[index + 0] & 16) | ((maria_lineRAM[index + 0] & 8) >> 3) | ((maria_lineRAM[index + 0] & 2)));
@@ -174,6 +182,7 @@ static void maria_WriteLineRAM(byte* buffer) {
}
}
else if(rmode == 3) {
// 320A/C
int pixel = 0;
for(int index = 0; index < MARIA_LINERAM_SIZE; index += 4) {
buffer[pixel++] = maria_GetColor((maria_lineRAM[index + 0] & 30));
@@ -191,20 +200,20 @@ static void maria_WriteLineRAM(byte* buffer) {
// ----------------------------------------------------------------------------
// StoreLineRAM
// ----------------------------------------------------------------------------
static void maria_StoreLineRAM( ) {
static inline void maria_StoreLineRAM( ) {
for(int index = 0; index < MARIA_LINERAM_SIZE; index++) {
maria_lineRAM[index] = 0;
}
byte mode = memory_ram[maria_dp.w + 1];
while(mode & 0x5f) {
byte width;
byte indirect = 0;
maria_pp.b.l = memory_ram[maria_dp.w];
maria_pp.b.h = memory_ram[maria_dp.w + 2];
if(mode & 31) {
if(mode & 31) {
maria_cycles += 8; // Maria cycles (Header 4 byte)
maria_palette = (memory_ram[maria_dp.w + 1] & 224) >> 3;
maria_horizontal = memory_ram[maria_dp.w + 3];
@@ -212,7 +221,7 @@ static void maria_StoreLineRAM( ) {
width = ((~width) & 31) + 1;
maria_dp.w += 4;
}
else {
else {
maria_cycles += 12; // Maria cycles (Header 5 byte)
maria_palette = (memory_ram[maria_dp.w + 3] & 224) >> 3;
maria_horizontal = memory_ram[maria_dp.w + 4];
@@ -237,7 +246,6 @@ static void maria_StoreLineRAM( ) {
maria_cycles += 3; // Maria cycles (Indirect)
maria_pp.b.l = memory_ram[basePP.w++];
maria_pp.b.h = memory_ram[CHARBASE] + maria_offset;
maria_cycles += 3; // Maria cycles (Indirect, 1 byte)
maria_StoreGraphic( );
if(cwidth) {
@@ -280,10 +288,10 @@ uint maria_RenderScanline( ) {
// lightgun flash
// Displays the background color when Maria is disabled (if applicable)
if( ( ( memory_ram[CTRL] & 96 ) != 64 ) &&
maria_scanline >= maria_visibleArea.top &&
maria_scanline >= maria_visibleArea.top &&
maria_scanline <= maria_visibleArea.bottom ) {
byte bgcolor = maria_GetColor(0);
byte *bgstart = maria_surface + ((maria_scanline - maria_displayArea.top) * maria_displayArea.GetLength());
byte *bgstart = maria_surface + ((maria_scanline - maria_displayArea.top) * maria_displayArea.GetLength());
for(uint index = 0; index < MARIA_LINERAM_SIZE; index++ ) {
*bgstart++ = bgcolor;
*bgstart++ = bgcolor;
@@ -329,7 +337,7 @@ uint maria_RenderScanline( ) {
{
maria_cycles += 4; // Maria cycles (Other lines of zone)
}
}
}
}
return maria_cycles;
}
@@ -341,4 +349,4 @@ void maria_Clear( ) {
for(int index = 0; index < MARIA_SURFACE_SIZE; index++) {
maria_surface[index] = 0;
}
}
}
+39 -13
View File
@@ -5,7 +5,7 @@
//
// ----------------------------------------------------------------------------
// Copyright 2005 Greg Stanton
//
//
// This program 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 2 of the License, or
@@ -23,6 +23,7 @@
// Memory.cpp
// ----------------------------------------------------------------------------
#include "Memory.h"
#include "ExpansionModule.h"
byte memory_ram[MEMORY_SIZE] = {0};
byte memory_rom[MEMORY_SIZE] = {0};
@@ -46,22 +47,32 @@ void memory_Reset( ) {
byte memory_Read(word address) {
byte tmp_byte;
if(cartridge_pokey && address == POKEY_RANDOM)
{
return pokey_GetRegister(POKEY_RANDOM);
if (cartridge_xm) {
if ((address >= 0x0470 && address < 0x0480) ||
(xm_pokey_enabled && (address >= 0x0450 && address < 0x0470)) ||
(xm_mem_enabled && (address >= 0x4000 && address < 0x8000))) {
return xm_Read(address);
}
}
if (cartridge_pokey && (
(!cartridge_pokey450 && (address >= 0x4000 && address <= 0x400f)) ||
(cartridge_pokey450 && (address >= 0x0450 && address < 0x0470)))) {
return pokey_GetRegister(
cartridge_pokey450 ? 0x4000 + (address - 0x0450) : address);
}
switch ( address ) {
case INTIM:
case INTIM | 0x2:
memory_ram[INTFLG] &= 0x7f;
memory_ram[INTFLG] &= 0x7f;
return memory_ram[INTIM];
break;
break;
case INTFLG:
case INTFLG | 0x2:
tmp_byte = memory_ram[INTFLG];
memory_ram[INTFLG] &= 0x7f;
return tmp_byte;
tmp_byte = memory_ram[INTFLG];
memory_ram[INTFLG] &= 0x7f;
return tmp_byte;
break;
default:
return memory_ram[address];
@@ -73,6 +84,21 @@ byte memory_Read(word address) {
// Write
// ----------------------------------------------------------------------------
void memory_Write(word address, byte data) {
if (cartridge_xm &&
((address >= 0x0470 && address < 0x0480) ||
((xm_pokey_enabled && (address >= 0x0450 && address < 0x0470)) ||
(xm_mem_enabled && (address >= 0x4000 && address < 0x8000))))) {
xm_Write(address, data);
return;
}
if (cartridge_pokey && (
(!cartridge_pokey450 && (address >= 0x4000 && address <= 0x400f)) ||
(cartridge_pokey450 && (address >= 0x0450 && address < 0x0470)))) {
pokey_SetRegister(
(cartridge_pokey450 ? 0x4000 + (address - 0x0450) : address), data);
return;
}
if(!memory_rom[address]) {
switch(address) {
@@ -82,8 +108,8 @@ void memory_Write(word address, byte data) {
}
break;
case INPTCTRL:
if(data == 22 && cartridge_IsLoaded( )) {
cartridge_Store( );
if(data == 22 && cartridge_IsLoaded( )) {
cartridge_Store( );
}
else if(data == 2 && bios_enabled) {
bios_Store( );
@@ -168,7 +194,7 @@ void memory_Write(word address, byte data) {
// ----------------------------------------------------------------------------
// WriteROM
// ----------------------------------------------------------------------------
void memory_WriteROM(word address, word size, const byte* data) {
void memory_WriteROM(word address, uint size, const byte* data) {
if((address + size) <= MEMORY_SIZE && data != NULL) {
for(uint index = 0; index < size; index++) {
memory_ram[address + index] = data[index];
@@ -180,7 +206,7 @@ void memory_WriteROM(word address, word size, const byte* data) {
// ----------------------------------------------------------------------------
// ClearROM
// ----------------------------------------------------------------------------
void memory_ClearROM(word address, word size) {
void memory_ClearROM(word address, uint size) {
if((address + size) <= MEMORY_SIZE) {
for(uint index = 0; index < size; index++) {
memory_ram[address + index] = 0;
+3 -3
View File
@@ -5,7 +5,7 @@
//
// ----------------------------------------------------------------------------
// Copyright 2005 Greg Stanton
//
//
// This program 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 2 of the License, or
@@ -39,8 +39,8 @@ typedef unsigned int uint;
extern void memory_Reset( );
extern byte memory_Read(word address);
extern void memory_Write(word address, byte data);
extern void memory_WriteROM(word address, word size, const byte* data);
extern void memory_ClearROM(word address, word size);
extern void memory_WriteROM(word address, uint size, const byte* data);
extern void memory_ClearROM(word address, uint size);
extern byte memory_ram[MEMORY_SIZE];
extern byte memory_rom[MEMORY_SIZE];
+97 -48
View File
@@ -5,7 +5,7 @@
//
// ----------------------------------------------------------------------------
// Copyright 2005 Greg Stanton
//
//
// This program 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 2 of the License, or
@@ -21,32 +21,33 @@
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
// ----------------------------------------------------------------------------
// PokeySound is Copyright(c) 1997 by Ron Fries
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of version 2 of the GNU Library General Public License
// as published by the Free Software Foundation.
//
// This library 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 Library
// General Public License for more details.
// To obtain a copy of the GNU Library General Public License, write to the
// Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// Any permitted reproduction of these routines, in whole or in part, must
// bear this legend.
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of version 2 of the GNU Library General Public License
// as published by the Free Software Foundation.
//
// This library 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 Library
// General Public License for more details.
// To obtain a copy of the GNU Library General Public License, write to the
// Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// Any permitted reproduction of these routines, in whole or in part, must
// bear this legend.
// ----------------------------------------------------------------------------
// Pokey.cpp
// ----------------------------------------------------------------------------
#include <stdlib.h>
#include "Pokey.h"
#include "Prosystem.h"
#include "ProSystem.h"
#define POKEY_NOTPOLY5 0x80
#define POKEY_POLY4 0x40
#define POKEY_PURE 0x20
#define POKEY_VOLUME_ONLY 0x10
#define POKEY_VOLUME_MASK 0x0f
#define POKEY_POLY9 0x80
#define POKEY_POLY9 0x80
#define POKEY_CH1_179 0x40
#define POKEY_CH3_179 0x20
#define POKEY_CH1_CH2 0x10
@@ -66,10 +67,10 @@
#define POKEY_CHANNEL4 3
#define POKEY_SAMPLE 4
#define SK_RESET 0x03
#define SK_RESET 0x03
byte pokey_buffer[POKEY_BUFFER_SIZE] = {0};
uint pokey_size = 524;
uint pokey_size = (POKEY_BUFFER_SIZE - 512); // 524 previously
static uint pokey_frequency = 1787520;
static uint pokey_sampleRate = 31440;
@@ -100,6 +101,9 @@ static uint r17;
static byte SKCTL;
byte RANDOM;
byte POT_input[8] = {228, 228, 228, 228, 228, 228, 228, 228};
static int pot_scanline;
static ulong random_scanline_counter;
static ulong prev_random_scanline_counter;
@@ -109,15 +113,15 @@ static void rand_init(byte *rng, int size, int left, int right, int add)
int i, x = 0;
for( i = 0; i < mask; i++ )
{
if (size == 17)
*rng = x >> 6; /* use bits 6..13 */
else
*rng = x; /* use bits 0..7 */
{
if (size == 17)
*rng = x >> 6; /* use bits 6..13 */
else
*rng = x; /* use bits 0..7 */
rng++;
/* calculate next bit */
x = ((x << left) + (x >> right) + add) & mask;
}
x = ((x << left) + (x >> right) + add) & mask;
}
}
void pokey_setSampleRate( uint rate ) {
@@ -128,6 +132,9 @@ void pokey_setSampleRate( uint rate ) {
// Reset
// ----------------------------------------------------------------------------
void pokey_Reset( ) {
pot_scanline = 0;
pokey_soundCntr = 0;
for(int index = 0; index < POKEY_POLY17_SIZE; index++) {
pokey_poly17[index] = rand( ) & 1;
}
@@ -152,6 +159,10 @@ void pokey_Reset( ) {
pokey_audf[channel] = 0;
}
for(int i = 0; i < 8; i++) {
POT_input[i] = 228;
}
pokey_audctl = 0;
pokey_baseMultiplier = POKEY_DIV_64;
@@ -166,7 +177,7 @@ void pokey_Reset( ) {
r17 = 0;
random_scanline_counter = 0;
prev_random_scanline_counter = 0;
}
}
/* Called prior to each frame */
void pokey_Frame() {
@@ -174,15 +185,33 @@ void pokey_Frame() {
/* Called prior to each scanline */
void pokey_Scanline() {
random_scanline_counter += CYCLES_PER_SCANLINE;
random_scanline_counter += CYCLES_PER_SCANLINE;
if (pot_scanline < 228)
pot_scanline++;
}
byte pokey_GetRegister(word address) {
byte data = 0;
byte addr = address & 0x0f;
if (addr < 8) {
byte b = POT_input[addr];
if (b <= pot_scanline)
return b;
return pot_scanline;
}
switch (address) {
case POKEY_ALLPOT: {
byte b = 0;
for (int i = 0; i < 8; i++)
if (POT_input[addr] <= pot_scanline)
b &= ~(1 << i); /* reset bit if pot value known */
return b;
}
case POKEY_RANDOM:
ulong curr_scanline_counter =
ulong curr_scanline_counter =
( random_scanline_counter + prosystem_cycles + prosystem_extra_cycles );
if( SKCTL & SK_RESET )
@@ -209,21 +238,27 @@ byte pokey_GetRegister(word address) {
RANDOM = RANDOM ^ 0xff;
data = RANDOM;
break;
}
return data;
}
}
// ----------------------------------------------------------------------------
// SetRegister
// ----------------------------------------------------------------------------
void pokey_SetRegister(word address, byte value) {
byte channelMask;
byte channelMask;
switch(address) {
case POKEY_POTGO:
if (!(SKCTL & 4))
pot_scanline = 0; /* slow pot mode */
return;
case POKEY_SKCTLS:
SKCTL = value;
if (value & 4)
pot_scanline = 228; /* fast pot mode - return results immediately */
return;
case POKEY_AUDF1:
@@ -233,7 +268,7 @@ void pokey_SetRegister(word address, byte value) {
channelMask |= 1 << POKEY_CHANNEL2;
}
break;
case POKEY_AUDC1:
pokey_audc[POKEY_CHANNEL1] = value;
channelMask = 1 << POKEY_CHANNEL1;
@@ -294,7 +329,7 @@ void pokey_SetRegister(word address, byte value) {
channelMask = 0;
break;
}
uint newValue = 0;
if(channelMask & (1 << POKEY_CHANNEL1)) {
@@ -342,7 +377,7 @@ void pokey_SetRegister(word address, byte value) {
}
if(newValue!= pokey_divideMax[POKEY_CHANNEL3]) {
pokey_divideMax[POKEY_CHANNEL3] = newValue;
if(pokey_divideCount[POKEY_CHANNEL3] > newValue) {
if(pokey_divideCount[POKEY_CHANNEL3] > newValue) {
pokey_divideCount[POKEY_CHANNEL3] = newValue;
}
}
@@ -364,19 +399,25 @@ void pokey_SetRegister(word address, byte value) {
pokey_divideMax[POKEY_CHANNEL4] = newValue;
if(pokey_divideCount[POKEY_CHANNEL4] > newValue) {
pokey_divideCount[POKEY_CHANNEL4] = newValue;
}
}
}
}
for(byte channel = POKEY_CHANNEL1; channel <= POKEY_CHANNEL4; channel++) {
if(channelMask & (1 << channel)) {
if((pokey_audc[channel] & POKEY_VOLUME_ONLY) || ((pokey_audc[channel] & POKEY_VOLUME_MASK) == 0) || (pokey_divideMax[channel] < (pokey_sampleMax >> 8))) {
if((pokey_audc[channel] & POKEY_VOLUME_ONLY) ||
((pokey_audc[channel] & POKEY_VOLUME_MASK) == 0) ||
(pokey_divideMax[channel] < (pokey_sampleMax >> 8))) {
#if 1 // WII
pokey_outVol[channel] = 1;
#else
pokey_outVol[channel] = pokey_audc[channel] & POKEY_VOLUME_MASK;
#endif
pokey_divideCount[channel] = 0x7fffffff;
pokey_divideMax[channel] = 0x7fffffff;
}
}
}
}
}
// ----------------------------------------------------------------------------
@@ -384,13 +425,18 @@ void pokey_SetRegister(word address, byte value) {
// ----------------------------------------------------------------------------
void pokey_Process(uint length) {
byte* buffer = pokey_buffer + pokey_soundCntr;
uint* sampleCntrPtr = (uint*)((byte*)(&pokey_sampleCount[0]) + 1);
//#ifdef BIG_ENDIAN
// uint* sampleCntrPtrB = (uint*)((byte*)&pokey_sampleCount[0] + 3);
//#else
uint* sampleCntrPtrB = (uint*)((byte*)&pokey_sampleCount[0] + 1);
//#endif
uint size = length;
while(length) {
byte currentValue;
byte nextEvent = POKEY_SAMPLE;
uint eventMin = *sampleCntrPtr;
uint eventMin = *sampleCntrPtrB;
byte channel;
for(channel = POKEY_CHANNEL1; channel <= POKEY_CHANNEL4; channel++) {
@@ -399,12 +445,12 @@ void pokey_Process(uint length) {
nextEvent = channel;
}
}
for(channel = POKEY_CHANNEL1; channel <= POKEY_CHANNEL4; channel++) {
pokey_divideCount[channel] -= eventMin;
}
*sampleCntrPtr -= eventMin;
*sampleCntrPtrB -= eventMin;
pokey_polyAdjust += eventMin;
if(nextEvent != POKEY_SAMPLE) {
@@ -434,7 +480,11 @@ void pokey_Process(uint length) {
}
}
else {
//#ifdef BIG_ENDIAN
// *(pokey_sampleCount + 1) += pokey_sampleMax;
//#else
*pokey_sampleCount += pokey_sampleMax;
//#endif
currentValue = 0;
for(channel = POKEY_CHANNEL1; channel <= POKEY_CHANNEL4; channel++) {
@@ -445,8 +495,8 @@ void pokey_Process(uint length) {
*buffer++ = currentValue;
length--;
}
}
}
pokey_soundCntr += size;
if(pokey_soundCntr >= pokey_size) {
pokey_soundCntr = 0;
@@ -457,7 +507,6 @@ void pokey_Process(uint length) {
// Clear
// ----------------------------------------------------------------------------
void pokey_Clear( ) {
for(int index = 0; index < POKEY_BUFFER_SIZE; index++) {
pokey_buffer[index] = 0;
}
}
pokey_soundCntr = 0;
memset(pokey_buffer, 0, POKEY_BUFFER_SIZE);
}
+102 -42
View File
@@ -52,6 +52,7 @@ void prosystem_Reset( ) {
tia_Reset( );
pokey_Clear( );
pokey_Reset( );
xm_Reset( );
memory_Reset( );
maria_Clear( );
maria_Reset( );
@@ -102,7 +103,7 @@ void prosystem_ExecuteFrame(const byte* input) {
prosystem_extra_cycles = 0;
if(cartridge_pokey) pokey_Frame();
if(cartridge_pokey || cartridge_xm) pokey_Frame();
for(maria_scanline = 1; maria_scanline <= prosystem_scanlines; maria_scanline++) {
if(maria_scanline == maria_displayArea.top) {
@@ -196,11 +197,11 @@ void prosystem_ExecuteFrame(const byte* input) {
if(lightgun) prosystem_FireLightGun();
tia_Process(2);
if(cartridge_pokey) {
if(cartridge_pokey || cartridge_xm) {
pokey_Process(2);
}
if(cartridge_pokey) pokey_Scanline();
if(cartridge_pokey || cartridge_xm) pokey_Scanline();
}
prosystem_frame++;
@@ -220,7 +221,7 @@ bool prosystem_Save(std::string filename, bool compress) {
logger_LogInfo("Saving game state to file " + filename + ".", PRO_SYSTEM_SOURCE);
byte loc_buffer[33000] = {0};
byte loc_buffer[33000 + XM_RAM_SIZE + 4] = {0};
uint size = 0;
@@ -272,9 +273,19 @@ bool prosystem_Save(std::string filename, bool compress) {
loc_buffer[size++] = ( 0xff & ( riot_clocks >> 8 ) );
loc_buffer[size++] = ( 0xff & riot_clocks );
#if 0
if(!compress) {
#endif
// XM (if applicable)
if (cartridge_xm) {
loc_buffer[size++] = xm_reg;
loc_buffer[size++] = xm_bank;
loc_buffer[size++] = xm_pokey_enabled;
loc_buffer[size++] = xm_mem_enabled;
for (index = 0; index < XM_RAM_SIZE; index++) {
loc_buffer[size + index] = xm_ram[index];
}
size += XM_RAM_SIZE;
}
FILE* file = fopen(filename.c_str( ), "wb");
if(file == NULL) {
logger_LogError("Failed to open the file " + filename + " for writing.", PRO_SYSTEM_SOURCE);
@@ -289,15 +300,6 @@ bool prosystem_Save(std::string filename, bool compress) {
fflush(file);
fclose(file);
#if 0
}
else {
if(!archive_Compress(filename.c_str( ), "Save.sav", loc_buffer, size)) {
logger_LogError("Failed to compress the save state data to the file " + filename + ".", PRO_SYSTEM_SOURCE);
return false;
}
}
#endif
return true;
}
@@ -354,6 +356,19 @@ bool prosystem_Save_buffer(byte *buffer)
buffer[size++] = ( 0xff & ( riot_clocks >> 8 ) );
buffer[size++] = ( 0xff & riot_clocks );
// XM (if applicable)
if (cartridge_xm) {
buffer[size++] = xm_reg;
buffer[size++] = xm_bank;
buffer[size++] = xm_pokey_enabled;
buffer[size++] = xm_mem_enabled;
for (index = 0; index < XM_RAM_SIZE; index++) {
buffer[size + index] = xm_ram[index];
}
size += XM_RAM_SIZE;
}
return true;
}
@@ -368,7 +383,7 @@ bool prosystem_Load(const std::string filename) {
logger_LogInfo("Loading game state from file " + filename + ".", PRO_SYSTEM_SOURCE);
byte loc_buffer[33000] = {0};
byte loc_buffer[33000 + XM_RAM_SIZE + 4] = {0};
uint size = archive_GetUncompressedFileSize(filename);
if(size == 0) {
@@ -391,10 +406,11 @@ bool prosystem_Load(const std::string filename) {
return false;
}
if( size != 16445 &&
size != 32829 &&
size != 16453 &&
size != 32837 ) {
if( size != 16445 && size != 32829 && /* no RIOT */
size != 16453 && size != 32837 && /* with RIOT */
size != (16453 + 4 + XM_RAM_SIZE) && /* XM without supercart ram */
size != (32837 + 4 + XM_RAM_SIZE)) /* XM with supercart ram */
{
fclose(file);
logger_LogError("Save state file has an invalid size.", PRO_SYSTEM_SOURCE);
return false;
@@ -406,9 +422,6 @@ bool prosystem_Load(const std::string filename) {
return false;
}
fclose(file);
}
else if(size == 16445 || size == 32829) {
archive_Uncompress(filename, loc_buffer, size);
}
else {
logger_LogError("Save state file has an invalid size.", PRO_SYSTEM_SOURCE);
@@ -459,7 +472,9 @@ bool prosystem_Load(const std::string filename) {
offset += 16384;
if(cartridge_type == CARTRIDGE_TYPE_SUPERCART_RAM) {
if(size != 32829 && size != 32837) {
if (size != 32829 && /* no RIOT */
size != 32837 && /* with RIOT */
size != (32837 + 4 + XM_RAM_SIZE)) /* XM */ {
logger_LogError("Save state file has an invalid size.", PRO_SYSTEM_SOURCE);
return false;
}
@@ -469,8 +484,10 @@ bool prosystem_Load(const std::string filename) {
offset += 16384;
}
if( size == 16453 || size == 32837 )
{
if (size == 16453 || /* no supercart ram */
size == 32837 || /* supercart ram */
size == (16453 + 4 + XM_RAM_SIZE) || /* xm, no supercart ram */
size == (32837 + 4 + XM_RAM_SIZE)) /* xm, supercart ram */ {
// RIOT state
riot_dra = loc_buffer[offset++];
riot_drb = loc_buffer[offset++];
@@ -480,7 +497,23 @@ bool prosystem_Load(const std::string filename) {
riot_intervals = loc_buffer[offset++];
riot_clocks = ( loc_buffer[offset++] << 8 );
riot_clocks |= loc_buffer[offset++];
}
// XM (if applicable)
if (cartridge_xm) {
if ((size != (16453 + 4 + XM_RAM_SIZE)) &&
(size != (32837 + 4 + XM_RAM_SIZE))) {
logger_LogError("Save state file has an invalid size.", PRO_SYSTEM_SOURCE);
return false;
}
xm_reg = loc_buffer[offset++];
xm_bank = loc_buffer[offset++];
xm_pokey_enabled = loc_buffer[offset++];
xm_mem_enabled = loc_buffer[offset++];
for (index = 0; index < XM_RAM_SIZE; index++) {
xm_ram[index] = loc_buffer[offset++];
}
}
return true;
@@ -489,6 +522,9 @@ bool prosystem_Load(const std::string filename) {
bool prosystem_Load_buffer(const byte *buffer)
{
uint size = cartridge_type == CARTRIDGE_TYPE_SUPERCART_RAM ? 32837 : 16453;
if(cartridge_xm) {
size += 4 + XM_RAM_SIZE;
}
uint offset = 0;
uint index;
@@ -533,25 +569,49 @@ bool prosystem_Load_buffer(const byte *buffer)
offset += 16384;
if(cartridge_type == CARTRIDGE_TYPE_SUPERCART_RAM) {
if(size != 32829 && size != 32837) {
if (size != 32829 && /* no RIOT */
size != 32837 && /* with RIOT */
size != (32837 + 4 + XM_RAM_SIZE)) /* XM */ {
logger_LogError("Save state file has an invalid size.", PRO_SYSTEM_SOURCE);
return false;
}
for(index = 0; index < 16384; index++) {
memory_ram[16384 + index] = buffer[offset + index];
}
offset += 16384;
}
if (size == 16453 || /* no supercart ram */
size == 32837 || /* supercart ram */
size == (16453 + 4 + XM_RAM_SIZE) || /* xm, no supercart ram */
size == (32837 + 4 + XM_RAM_SIZE)) /* xm, supercart ram */ {
// RIOT state
riot_dra = buffer[offset++];
riot_drb = buffer[offset++];
riot_timing = buffer[offset++];
riot_timer = ( buffer[offset++] << 8 );
riot_timer |= buffer[offset++];
riot_intervals = buffer[offset++];
riot_clocks = ( buffer[offset++] << 8 );
riot_clocks |= buffer[offset++];
}
// XM (if applicable)
if (cartridge_xm) {
if ((size != (16453 + 4 + XM_RAM_SIZE)) &&
(size != (32837 + 4 + XM_RAM_SIZE))) {
logger_LogError("Save state file has an invalid size.", PRO_SYSTEM_SOURCE);
return false;
}
for(index = 0; index < 16384; index++) {
memory_ram[16384 + index] = buffer[offset + index];
}
offset += 16384;
}
xm_reg = buffer[offset++];
xm_bank = buffer[offset++];
xm_pokey_enabled = buffer[offset++];
xm_mem_enabled = buffer[offset++];
// RIOT state
riot_dra = buffer[offset++];
riot_drb = buffer[offset++];
riot_timing = buffer[offset++];
riot_timer = ( buffer[offset++] << 8 );
riot_timer |= buffer[offset++];
riot_intervals = buffer[offset++];
riot_clocks = ( buffer[offset++] << 8 );
riot_clocks |= buffer[offset++];
for (index = 0; index < XM_RAM_SIZE; index++) {
xm_ram[index] = buffer[offset++];
}
}
return true;
}
+2 -1
View File
@@ -38,6 +38,7 @@
#include "Archive.h"
#include "Tia.h"
#include "Pokey.h"
#include "ExpansionModule.h"
typedef unsigned char byte;
typedef unsigned short word;
@@ -75,4 +76,4 @@ extern float lightgun_cycle;
// Whether the lightgun is enabled for the current cartridge
//extern bool lightgun_enabled;
#endif
#endif
+23 -3
View File
@@ -64,11 +64,11 @@ static const Vector SALLY_NMI = {65531, 65530};
static const Vector SALLY_IRQ = {65535, 65534};
static const byte SALLY_CYCLES[256] = {
7,6,0,0,0,3,5,0,3,2,2,0,0,4,6,0,
7,6,0,0,0,3,5,0,3,2,2,2,0,4,6,0,
2,5,0,0,0,4,6,0,2,4,0,0,0,4,7,0,
6,6,0,0,3,3,5,0,4,2,2,0,4,4,6,0,
6,6,0,0,3,3,5,0,4,2,2,2,4,4,6,0,
2,5,0,0,0,4,6,0,2,4,0,0,0,4,7,0,
6,6,0,0,0,3,5,0,3,2,2,0,3,4,6,0,
6,6,0,0,0,3,5,0,3,2,2,2,3,4,6,0,
2,5,0,0,0,4,6,0,2,4,0,0,0,4,7,0,
6,6,0,0,0,3,5,0,4,2,2,0,5,4,6,0,
2,5,0,0,0,4,6,0,2,4,0,0,0,4,7,0,
@@ -1705,6 +1705,26 @@ uint sally_ExecuteInstruction( ) {
sally_INC( );
break;
case 0x4b: // ALR (ASR)
sally_Immediate();
sally_AND();
sally_LSRA();
break;
case 0x0b: // ANC
case 0x2b: { // ANC
sally_Immediate();
sally_AND();
if (sally_a & 128) {
sally_p |= SALLY_FLAG.C;
}
else {
//sally_p &= ~SALLY_FLAG.C;
sally_p = (sally_p & ~SALLY_FLAG.C) & 0xFF;
}
break;
}
default:
break;
}
+35 -68
View File
@@ -1,11 +1,12 @@
// ----------------------------------------------------------------------------
// ___ ___ ___ ___ ___ ____ ___ _ _
// /__/ /__/ / / /__ /__/ /__ / /_ / |/ /
// / / \ /__/ ___/ ___/ ___/ / /__ / / emulator
// ___ ___ ___ ___ ___ ____ ___ _ _ __ ___
// /__/ /__/ / / /__ /__/ /__ / /_ / |/ / / / _
// / / \ /__/ ___/ ___/ ___/ / /__ / / ___/ /__/
//
// ----------------------------------------------------------------------------
// Copyright 2005 Greg Stanton
//
// Copyright 2020 Rupert Carmichael
//
// This program 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 2 of the License, or
@@ -20,101 +21,67 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
// ----------------------------------------------------------------------------
// Sound.cpp
// Sound.c
// ----------------------------------------------------------------------------
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include "Sound.h"
#define MAX_BUFFER_SIZE 8192
typedef struct
{
uint nSamplesPerSec;
word nChannels;
word wBitsPerSample;
} SOUNDCONFIG;
static uint32_t nSamplesPerSec = 48000;
static const SOUNDCONFIG soundDefaults = {48000, 1, 8};
static SOUNDCONFIG sound_format = soundDefaults;
// ----------------------------------------------------------------------------
// GetSampleLength
// ----------------------------------------------------------------------------
static uint sound_GetSampleLength(uint length, uint unit, uint unitMax)
{
uint sampleLength = length / unitMax;
uint sampleRemain = length % unitMax;
if(sampleRemain != 0 && sampleRemain >= unit)
{
sampleLength++;
}
return sampleLength;
}
// ----------------------------------------------------------------------------
// Resample
// ----------------------------------------------------------------------------
static void sound_Resample(const byte *source, byte *target, int length)
{
int measurement = sound_format.nSamplesPerSec;
static void sound_Resample(const uint8_t *source, uint8_t *target, int length) {
int measurement = nSamplesPerSec;
int sourceIndex = 0;
int targetIndex = 0;
int max = ((prosystem_frequency * prosystem_scanlines) << 1);
while(targetIndex < length)
{
if(measurement >= max)
{
while (targetIndex < length) {
if (measurement >= max) {
target[targetIndex++] = source[sourceIndex];
measurement -= max;
}
else
{
else {
sourceIndex++;
measurement += sound_format.nSamplesPerSec;
measurement += nSamplesPerSec;
}
}
}
// ----------------------------------------------------------------------------
// Store
// ----------------------------------------------------------------------------
uint sound_Store(byte *out_buffer)
{
uint32_t sound_Store(uint8_t *out_buffer) {
memset(out_buffer, 0, MAX_BUFFER_SIZE);
uint length = 48000 / prosystem_frequency; // sound_GetSampleLength(sound_format.nSamplesPerSec, prosystem_frame, prosystem_frequency);
uint32_t length = nSamplesPerSec / prosystem_frequency;
sound_Resample(tia_buffer, out_buffer, length);
tia_Clear();
// Ballblazer, Commando, various homebrew and hacks
if(cartridge_pokey)
{
byte pokeySample[MAX_BUFFER_SIZE];
if(cartridge_pokey || xm_pokey_enabled) {
uint8_t pokeySample[MAX_BUFFER_SIZE];
memset(pokeySample, 0, MAX_BUFFER_SIZE);
sound_Resample(pokey_buffer, pokeySample, length);
for(uint index = 0; index < length; index++)
{
out_buffer[index] += pokeySample[index];
out_buffer[index] = out_buffer[index] / 2;
for(uint32_t index = 0; index < length; index++) {
uint32_t sound = out_buffer[index] + pokeySample[index];
out_buffer[index] = sound >> 1;
}
}
else {
for(uint32_t index = 0; index < length; index++) {
out_buffer[index] = out_buffer[index] * 0.75; //>> 1;
}
}
pokey_Clear();
return length;
}
// ----------------------------------------------------------------------------
// SetSampleRate
// ----------------------------------------------------------------------------
void sound_SetSampleRate(uint rate)
{
sound_format.nSamplesPerSec = rate;
void sound_SetSampleRate(uint32_t rate) {
nSamplesPerSec = rate;
}
// ----------------------------------------------------------------------------
// GetSampleRate
// ----------------------------------------------------------------------------
uint sound_GetSampleRate()
{
return sound_format.nSamplesPerSec;
uint32_t sound_GetSampleRate(void) {
return nSamplesPerSec;
}
+20 -20
View File
@@ -5,7 +5,7 @@
//
// ----------------------------------------------------------------------------
// Copyright 2005 Greg Stanton
//
//
// This program 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 2 of the License, or
@@ -21,30 +21,31 @@
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
// ----------------------------------------------------------------------------
// TiaSound is Copyright(c) 1997 by Ron Fries
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of version 2 of the GNU Library General Public License
// as published by the Free Software Foundation.
//
// This library 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 Library
// General Public License for more details.
// To obtain a copy of the GNU Library General Public License, write to the
// Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of version 2 of the GNU Library General Public License
// as published by the Free Software Foundation.
//
// This library 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 Library
// General Public License for more details.
// To obtain a copy of the GNU Library General Public License, write to the
// Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// Any permitted reproduction of these routines, in whole or in part, must
// bear this legend.
// bear this legend.
// ----------------------------------------------------------------------------
// Tia.cpp
// ----------------------------------------------------------------------------
#include "Tia.h"
#include <string.h>
#define TIA_POLY4_SIZE 15
#define TIA_POLY5_SIZE 31
#define TIA_POLY9_SIZE 511
byte tia_buffer[TIA_BUFFER_SIZE] = {0};
uint tia_size = 524;
uint tia_size = TIA_BUFFER_SIZE; // previously was 524
static const byte TIA_POLY4[ ] = {1,1,0,1,1,1,0,0,0,0,1,0,1,0,0};
static const byte TIA_POLY5[ ] = {0,0,1,0,1,1,0,0,1,1,1,1,1,0,0,0,1,1,0,1,1,1,0,1,0,1,0,0,0,0,1};
@@ -119,9 +120,8 @@ void tia_Reset( ) {
// Clear
// ----------------------------------------------------------------------------
void tia_Clear( ) {
for(int index = 0; index < TIA_BUFFER_SIZE; index++) {
tia_buffer[index] = 0;
}
tia_soundCntr = 0;
memset(tia_buffer, 0, TIA_BUFFER_SIZE);
}
// ----------------------------------------------------------------------------
@@ -130,7 +130,7 @@ void tia_Clear( ) {
void tia_SetRegister(word address, byte data) {
byte channel;
byte frequency;
switch(address) {
case AUDC0:
tia_audc[0] = data & 15;
@@ -203,4 +203,4 @@ void tia_Process(uint length) {
tia_soundCntr = 0;
}
}
}
}
+2
View File
@@ -0,0 +1,2 @@
/* Localized versions of Info.plist keys */